diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/arm | |
download | op-kernel-dev-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip op-kernel-dev-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/arm')
563 files changed, 140025 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig new file mode 100644 index 0000000..4055115 --- /dev/null +++ b/arch/arm/Kconfig @@ -0,0 +1,736 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# + +mainmenu "Linux Kernel Configuration" + +config ARM + bool + default y + help + The ARM series is a line of low-power-consumption RISC chip designs + licensed by ARM ltd and targeted at embedded applications and + handhelds such as the Compaq IPAQ. ARM-based PCs are no longer + manufactured, but legacy ARM-based PC hardware remains popular in + Europe. There is an ARM Linux project with a web page at + <http://www.arm.linux.org.uk/>. + +config MMU + bool + default y + +config EISA + bool + ---help--- + The Extended Industry Standard Architecture (EISA) bus was + developed as an open alternative to the IBM MicroChannel bus. + + The EISA bus provided some of the features of the IBM MicroChannel + bus while maintaining backward compatibility with cards made for + the older ISA bus. The EISA bus saw limited use between 1988 and + 1995 when it was made obsolete by the PCI bus. + + Say Y here if you are building a kernel for an EISA-based machine. + + Otherwise, say N. + +config SBUS + bool + +config MCA + bool + help + MicroChannel Architecture is found in some IBM PS/2 machines and + laptops. It is a bus system similar to PCI or ISA. See + <file:Documentation/mca.txt> (and especially the web page given + there) before attempting to build an MCA bus kernel. + +config UID16 + bool + default y + +config RWSEM_GENERIC_SPINLOCK + bool + default y + +config RWSEM_XCHGADD_ALGORITHM + bool + +config GENERIC_CALIBRATE_DELAY + bool + default y + +config GENERIC_BUST_SPINLOCK + bool + +config GENERIC_ISA_DMA + bool + +config GENERIC_IOMAP + bool + default y + +config FIQ + bool + +source "init/Kconfig" + +menu "System Type" + +choice + prompt "ARM system type" + default ARCH_RPC + +config ARCH_CLPS7500 + bool "Cirrus-CL-PS7500FE" + select TIMER_ACORN + +config ARCH_CLPS711X + bool "CLPS711x/EP721x-based" + +config ARCH_CO285 + bool "Co-EBSA285" + select FOOTBRIDGE + select FOOTBRIDGE_ADDIN + +config ARCH_EBSA110 + bool "EBSA-110" + help + This is an evaluation board for the StrongARM processor available + from Digital. It has limited hardware on-board, including an onboard + Ethernet interface, two PCMCIA sockets, two serial ports and a + parallel port. + +config ARCH_CAMELOT + bool "Epxa10db" + help + This enables support for Altera's Excalibur XA10 development board. + If you would like to build your kernel to run on one of these boards + then you must say 'Y' here. Otherwise say 'N' + +config ARCH_FOOTBRIDGE + bool "FootBridge" + select FOOTBRIDGE + +config ARCH_INTEGRATOR + bool "Integrator" + select ARM_AMBA + select ICST525 + +config ARCH_IOP3XX + bool "IOP3xx-based" + +config ARCH_IXP4XX + bool "IXP4xx-based" + select DMABOUNCE + +config ARCH_IXP2000 + bool "IXP2400/2800-based" + +config ARCH_L7200 + bool "LinkUp-L7200" + select FIQ + help + Say Y here if you intend to run this kernel on a LinkUp Systems + L7200 Software Development Board which uses an ARM720T processor. + Information on this board can be obtained at: + + <http://www.linkupsys.com/> + + If you have any questions or comments about the Linux kernel port + to this board, send e-mail to <sjhill@cotw.com>. + +config ARCH_PXA + bool "PXA2xx-based" + +config ARCH_RPC + bool "RiscPC" + select ARCH_ACORN + select FIQ + select TIMER_ACORN + help + On the Acorn Risc-PC, Linux can support the internal IDE disk and + CD-ROM interface, serial and parallel port, and the floppy drive. + +config ARCH_SA1100 + bool "SA1100-based" + +config ARCH_S3C2410 + bool "Samsung S3C2410" + help + Samsung S3C2410X CPU based systems, such as the Simtec Electronics + BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or + the Samsung SMDK2410 development board (and derviatives). + +config ARCH_SHARK + bool "Shark" + +config ARCH_LH7A40X + bool "Sharp LH7A40X" + help + Say Y here for systems based on one of the Sharp LH7A40X + System on a Chip processors. These CPUs include an ARM922T + core with a wide array of integrated devices for + hand-held and low-power applications. + +config ARCH_OMAP + bool "TI OMAP" + +config ARCH_VERSATILE + bool "Versatile" + select ARM_AMBA + select ICST307 + help + This enables support for ARM Ltd Versatile board. + +config ARCH_IMX + bool "IMX" + +config ARCH_H720X + bool "Hynix-HMS720x-based" + help + This enables support for systems based on the Hynix HMS720x + +endchoice + +source "arch/arm/mach-clps711x/Kconfig" + +source "arch/arm/mach-epxa10db/Kconfig" + +source "arch/arm/mach-footbridge/Kconfig" + +source "arch/arm/mach-integrator/Kconfig" + +source "arch/arm/mach-iop3xx/Kconfig" + +source "arch/arm/mach-ixp4xx/Kconfig" + +source "arch/arm/mach-ixp2000/Kconfig" + +source "arch/arm/mach-pxa/Kconfig" + +source "arch/arm/mach-sa1100/Kconfig" + +source "arch/arm/mach-omap/Kconfig" + +source "arch/arm/mach-s3c2410/Kconfig" + +source "arch/arm/mach-lh7a40x/Kconfig" + +source "arch/arm/mach-imx/Kconfig" + +source "arch/arm/mach-h720x/Kconfig" + +source "arch/arm/mach-versatile/Kconfig" + +# Definitions to make life easier +config ARCH_ACORN + bool + +source arch/arm/mm/Kconfig + +# bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER +config XSCALE_PMU + bool + depends on CPU_XSCALE && !XSCALE_PMU_TIMER + default y + +endmenu + +source "arch/arm/common/Kconfig" + +config FORCE_MAX_ZONEORDER + int + depends on SA1111 + default "9" + +menu "Bus support" + +config ARM_AMBA + bool + +config ISA + bool + depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100 || ARCH_MX1ADS + default y + help + Find out whether you have ISA slots on your motherboard. ISA is the + name of a bus system, i.e. the way the CPU talks to the other stuff + inside your box. Other bus systems are PCI, EISA, MicroChannel + (MCA) or VESA. ISA is an older system, now being displaced by PCI; + newer boards don't support it. If you have ISA, say Y, otherwise N. + +config ISA_DMA + bool + depends on FOOTBRIDGE_HOST || ARCH_SHARK + default y + +config PCI + bool "PCI support" if ARCH_INTEGRATOR_AP + default y if ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_IXP2000 + help + Find out whether you have a PCI motherboard. PCI is the name of a + bus system, i.e. the way the CPU talks to the other stuff inside + your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or + VESA. If you have PCI, say Y, otherwise N. + + The PCI-HOWTO, available from + <http://www.tldp.org/docs.html#howto>, contains valuable + information about which PCI hardware does work under Linux and which + doesn't. + +# Select the host bridge type +config PCI_HOST_VIA82C505 + bool + depends on PCI && ARCH_SHARK + default y + +source "drivers/pci/Kconfig" + +source "drivers/pcmcia/Kconfig" + +endmenu + +menu "Kernel Features" + +config SMP + bool "Symmetric Multi-Processing (EXPERIMENTAL)" + depends on EXPERIMENTAL && n + help + This enables support for systems with more than one CPU. If you have + a system with only one CPU, like most personal computers, say N. If + you have a system with more than one CPU, say Y. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on many, but not all, single + processor machines. On a single processor machine, the kernel will + run faster if you say N here. + + See also the <file:Documentation/smp.tex>, + <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>, + <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at + <http://www.linuxdoc.org/docs.html#howto>. + + If you don't know what to do here, say N. + +config NR_CPUS + int "Maximum number of CPUs (2-32)" + range 2 32 + depends on SMP + default "4" + +config PREEMPT + bool "Preemptible Kernel (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + This option reduces the latency of the kernel when reacting to + real-time or interactive events by allowing a low priority process to + be preempted even if it is in kernel mode executing a system call. + This allows applications to run more reliably even when the system is + under load. + + Say Y here if you are building a kernel for a desktop, embedded + or real-time system. Say N if you are unsure. + +config DISCONTIGMEM + bool + depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) + default y + help + Say Y to support efficient handling of discontiguous physical memory, + for architectures which are either NUMA (Non-Uniform Memory Access) + or have huge holes in the physical address space for other reasons. + See <file:Documentation/vm/numa> for more. + +config LEDS + bool "Timer and CPU usage LEDs" + depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \ + ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \ + ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \ + ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ + ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE + help + If you say Y here, the LEDs on your machine will be used + to provide useful information about your current system status. + + If you are compiling a kernel for a NetWinder or EBSA-285, you will + be able to select which LEDs are active using the options below. If + you are compiling a kernel for the EBSA-110 or the LART however, the + red LED will simply flash regularly to indicate that the system is + still functional. It is safe to say Y here if you have a CATS + system, but the driver will do nothing. + +config LEDS_TIMER + bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \ + MACH_OMAP_H2 || MACH_OMAP_PERSEUS2 + depends on LEDS + default y if ARCH_EBSA110 + help + If you say Y here, one of the system LEDs (the green one on the + NetWinder, the amber one on the EBSA285, or the red one on the LART) + will flash regularly to indicate that the system is still + operational. This is mainly useful to kernel hackers who are + debugging unstable kernels. + + The LART uses the same LED for both Timer LED and CPU usage LED + functions. You may choose to use both, but the Timer LED function + will overrule the CPU usage LED. + +config LEDS_CPU + bool "CPU usage LED" if (!ARCH_CDB89712 && !ARCH_EBSA110 && \ + !ARCH_OMAP) || MACH_OMAP_H2 || MACH_OMAP_PERSEUS2 + depends on LEDS + help + If you say Y here, the red LED will be used to give a good real + time indication of CPU usage, by lighting whenever the idle task + is not currently executing. + + The LART uses the same LED for both Timer LED and CPU usage LED + functions. You may choose to use both, but the Timer LED function + will overrule the CPU usage LED. + +config ALIGNMENT_TRAP + bool + default y if !ARCH_EBSA110 + help + ARM processors can not fetch/store information which is not + naturally aligned on the bus, i.e., a 4 byte fetch must start at an + address divisible by 4. On 32-bit ARM processors, these non-aligned + fetch/store instructions will be emulated in software if you say + here, which has a severe performance impact. This is necessary for + correct operation of some network protocols. With an IP-only + configuration it is safe to say N, otherwise say Y. + +endmenu + +menu "Boot options" + +# Compressed boot loader in ROM. Yes, we really want to ask about +# TEXT and BSS so we preserve their values in the config files. +config ZBOOT_ROM_TEXT + hex "Compressed ROM boot loader base address" + default "0" + help + The physical address at which the ROM-able zImage is to be + placed in the target. Platforms which normally make use of + ROM-able zImage formats normally set this to a suitable + value in their defconfig file. + + If ZBOOT_ROM is not enabled, this has no effect. + +config ZBOOT_ROM_BSS + hex "Compressed ROM boot loader BSS address" + default "0" + help + The base address of 64KiB of read/write memory in the target + for the ROM-able zImage, which must be available while the + decompressor is running. Platforms which normally make use of + ROM-able zImage formats normally set this to a suitable + value in their defconfig file. + + If ZBOOT_ROM is not enabled, this has no effect. + +config ZBOOT_ROM + bool "Compressed boot loader in ROM/flash" + depends on ZBOOT_ROM_TEXT != ZBOOT_ROM_BSS + help + Say Y here if you intend to execute your compressed kernel image + (zImage) directly from ROM or flash. If unsure, say N. + +config CMDLINE + string "Default kernel command string" + default "" + help + On some architectures (EBSA110 and CATS), there is currently no way + for the boot loader to pass arguments to the kernel. For these + architectures, you should supply some command-line options at build + time by entering them here. As a minimum, you should specify the + memory size and the root device (e.g., mem=64M root=/dev/nfs). + +config XIP_KERNEL + bool "Kernel Execute-In-Place from ROM" + depends on !ZBOOT_ROM + help + Execute-In-Place allows the kernel to run from non-volatile storage + directly addressable by the CPU, such as NOR flash. This saves RAM + space since the text section of the kernel is not loaded from flash + to RAM. Read-write sections, such as the data section and stack, + are still copied to RAM. The XIP kernel is not compressed since + it has to run directly from flash, so it will take more space to + store it. The flash address used to link the kernel object files, + and for storing it, is configuration dependent. Therefore, if you + say Y here, you must know the proper physical address where to + store the kernel image depending on your own flash memory usage. + + Also note that the make target becomes "make xipImage" rather than + "make zImage" or "make Image". The final kernel binary to put in + ROM memory will be arch/arm/boot/xipImage. + + If unsure, say N. + +config XIP_PHYS_ADDR + hex "XIP Kernel Physical Location" + depends on XIP_KERNEL + default "0x00080000" + help + This is the physical address in your flash memory the kernel will + be linked for and stored to. This address is dependent on your + own flash usage. + +endmenu + +if (ARCH_SA1100 || ARCH_INTEGRATOR) + +menu "CPU Frequency scaling" + +source "drivers/cpufreq/Kconfig" + +config CPU_FREQ_SA1100 + bool + depends on CPU_FREQ && (SA1100_LART || SA1100_PLEB) + default y + +config CPU_FREQ_SA1110 + bool + depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3) + default y + +config CPU_FREQ_INTEGRATOR + tristate "CPUfreq driver for ARM Integrator CPUs" + depends on ARCH_INTEGRATOR && CPU_FREQ + default y + help + This enables the CPUfreq driver for ARM Integrator CPUs. + + For details, take a look at <file:Documentation/cpu-freq>. + + If in doubt, say Y. + +endmenu + +endif + +menu "Floating point emulation" + +comment "At least one emulation must be selected" + +config FPE_NWFPE + bool "NWFPE math emulation" + ---help--- + Say Y to include the NWFPE floating point emulator in the kernel. + This is necessary to run most binaries. Linux does not currently + support floating point hardware so you need to say Y here even if + your machine has an FPA or floating point co-processor podule. + + You may say N here if you are going to load the Acorn FPEmulator + early in the bootup. + +config FPE_NWFPE_XP + bool "Support extended precision" + depends on FPE_NWFPE && !CPU_BIG_ENDIAN + help + Say Y to include 80-bit support in the kernel floating-point + emulator. Otherwise, only 32 and 64-bit support is compiled in. + Note that gcc does not generate 80-bit operations by default, + so in most cases this option only enlarges the size of the + floating point emulator without any good reason. + + You almost surely want to say N here. + +config FPE_FASTFPE + bool "FastFPE math emulation (EXPERIMENTAL)" + depends on !CPU_32v3 && EXPERIMENTAL + ---help--- + Say Y here to include the FAST floating point emulator in the kernel. + This is an experimental much faster emulator which now also has full + precision for the mantissa. It does not support any exceptions. + It is very simple, and approximately 3-6 times faster than NWFPE. + + It should be sufficient for most programs. It may be not suitable + for scientific calculations, but you have to check this for yourself. + If you do not feel you need a faster FP emulation you should better + choose NWFPE. + +config VFP + bool "VFP-format floating point maths" + depends on CPU_V6 || CPU_ARM926T + help + Say Y to include VFP support code in the kernel. This is needed + if your hardware includes a VFP unit. + + Please see <file:Documentation/arm/VFP/release-notes.txt> for + release notes and additional status information. + + Say N if your target does not have VFP hardware. + +endmenu + +menu "Userspace binary formats" + +source "fs/Kconfig.binfmt" + +config ARTHUR + tristate "RISC OS personality" + help + Say Y here to include the kernel code necessary if you want to run + Acorn RISC OS/Arthur binaries under Linux. This code is still very + experimental; if this sounds frightening, say N and sleep in peace. + You can also say M here to compile this support as a module (which + will be called arthur). + +endmenu + +menu "Power management options" + +config PM + bool "Power Management support" + ---help--- + "Power Management" means that parts of your computer are shut + off or put into a power conserving "sleep" mode if they are not + being used. There are two competing standards for doing this: APM + and ACPI. If you want to use either one, say Y here and then also + to the requisite support below. + + Power Management is most important for battery powered laptop + computers; if you have a laptop, check out the Linux Laptop home + page on the WWW at <http://www.linux-on-laptops.com/> or + Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/> + and the Battery Powered Linux mini-HOWTO, available from + <http://www.tldp.org/docs.html#howto>. + + Note that, even if you say N here, Linux on the x86 architecture + will issue the hlt instruction if nothing is to be done, thereby + sending the processor to sleep and saving power. + +config APM + tristate "Advanced Power Management Emulation" + depends on PM + ---help--- + APM is a BIOS specification for saving power using several different + techniques. This is mostly useful for battery powered laptops with + APM compliant BIOSes. If you say Y here, the system time will be + reset after a RESUME operation, the /proc/apm device will provide + battery status information, and user-space programs will receive + notification of APM "events" (e.g. battery status change). + + If you select "Y" here, you can disable actual use of the APM + BIOS by passing the "apm=off" option to the kernel at boot time. + + Note that the APM support is almost completely disabled for + machines with more than one CPU. + + In order to use APM, you will need supporting software. For location + and more information, read <file:Documentation/pm.txt> and the + Battery Powered Linux mini-HOWTO, available from + <http://www.tldp.org/docs.html#howto>. + + This driver does not spin down disk drives (see the hdparm(8) + manpage ("man 8 hdparm") for that), and it doesn't turn off + VESA-compliant "green" monitors. + + This driver does not support the TI 4000M TravelMate and the ACER + 486/DX4/75 because they don't have compliant BIOSes. Many "green" + desktop machines also don't have compliant BIOSes, and this driver + may cause those machines to panic during the boot phase. + + Generally, if you don't have a battery in your machine, there isn't + much point in using this driver and you should say N. If you get + random kernel OOPSes or reboots that don't seem to be related to + anything, try disabling/enabling this option (or disabling/enabling + APM in your BIOS). + + Some other things you should try when experiencing seemingly random, + "weird" problems: + + 1) make sure that you have enough swap space and that it is + enabled. + 2) pass the "no-hlt" option to the kernel + 3) switch on floating point emulation in the kernel and pass + the "no387" option to the kernel + 4) pass the "floppy=nodma" option to the kernel + 5) pass the "mem=4M" option to the kernel (thereby disabling + all but the first 4 MB of RAM) + 6) make sure that the CPU is not over clocked. + 7) read the sig11 FAQ at <http://www.bitwizard.nl/sig11/> + 8) disable the cache from your BIOS settings + 9) install a fan for the video card or exchange video RAM + 10) install a better fan for the CPU + 11) exchange RAM chips + 12) exchange the motherboard. + + To compile this driver as a module, choose M here: the + module will be called apm. + +endmenu + +menu "Device Drivers" + +source "drivers/base/Kconfig" + +if ALIGNMENT_TRAP +source "drivers/mtd/Kconfig" +endif + +source "drivers/parport/Kconfig" + +source "drivers/pnp/Kconfig" + +source "drivers/block/Kconfig" + +source "drivers/acorn/block/Kconfig" + +if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE +source "drivers/ide/Kconfig" +endif + +source "drivers/scsi/Kconfig" + +source "drivers/md/Kconfig" + +source "drivers/message/fusion/Kconfig" + +source "drivers/ieee1394/Kconfig" + +source "drivers/message/i2o/Kconfig" + +source "net/Kconfig" + +source "drivers/isdn/Kconfig" + +# input before char - char/joystick depends on it. As does USB. + +source "drivers/input/Kconfig" + +source "drivers/char/Kconfig" + +source "drivers/i2c/Kconfig" + +#source "drivers/l3/Kconfig" + +source "drivers/misc/Kconfig" + +source "drivers/media/Kconfig" + +source "drivers/video/Kconfig" + +source "sound/Kconfig" + +source "drivers/usb/Kconfig" + +source "drivers/mmc/Kconfig" + +endmenu + +source "fs/Kconfig" + +source "arch/arm/oprofile/Kconfig" + +source "arch/arm/Kconfig.debug" + +source "security/Kconfig" + +source "crypto/Kconfig" + +source "lib/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug new file mode 100644 index 0000000..45a5709 --- /dev/null +++ b/arch/arm/Kconfig.debug @@ -0,0 +1,109 @@ +menu "Kernel hacking" + +source "lib/Kconfig.debug" + +# RMK wants arm kernels compiled with frame pointers so hardwire this to y. +# If you know what you are doing and are willing to live without stack +# traces, you can get a slightly smaller kernel by setting this option to +# n, but then RMK will have to kill you ;). +config FRAME_POINTER + bool + default y + help + If you say N here, the resulting kernel will be slightly smaller and + faster. However, when a problem occurs with the kernel, the + information that is reported is severely limited. Most people + should say Y here. + +config DEBUG_USER + bool "Verbose user fault messages" + help + When a user program crashes due to an exception, the kernel can + print a brief message explaining what the problem was. This is + sometimes helpful for debugging but serves no purpose on a + production system. Most people should say N here. + + In addition, you need to pass user_debug=N on the kernel command + line to enable this feature. N consists of the sum of: + + 1 - undefined instruction events + 2 - system calls + 4 - invalid data aborts + 8 - SIGSEGV faults + 16 - SIGBUS faults + +config DEBUG_WAITQ + bool "Wait queue debugging" + depends on DEBUG_KERNEL + +config DEBUG_ERRORS + bool "Verbose kernel error messages" + depends on DEBUG_KERNEL + help + This option controls verbose debugging information which can be + printed when the kernel detects an internal error. This debugging + information is useful to kernel hackers when tracking down problems, + but mostly meaningless to other people. It's safe to say Y unless + you are concerned with the code size or don't want to see these + messages. + + +# These options are only for real kernel hackers who want to get their hands dirty. +config DEBUG_LL + bool "Kernel low-level debugging functions" + depends on DEBUG_KERNEL + help + Say Y here to include definitions of printascii, printchar, printhex + in the kernel. This is helpful if you are debugging code that + executes before the console is initialized. + +config DEBUG_ICEDCC + bool "Kernel low-level debugging via EmbeddedICE DCC channel" + depends on DEBUG_LL + help + Say Y here if you want the debug print routines to direct their + output to the EmbeddedICE macrocell's DCC channel using + co-processor 14. This is known to work on the ARM9 style ICE + channel. + + It does include a timeout to ensure that the system does not + totally freeze when there is nothing connected to read. + +config DEBUG_DC21285_PORT + bool "Kernel low-level debugging messages via footbridge serial port" + depends on DEBUG_LL && FOOTBRIDGE + help + Say Y here if you want the debug print routines to direct their + output to the serial port in the DC21285 (Footbridge). Saying N + will cause the debug messages to appear on the first 16550 + serial port. + +config DEBUG_CLPS711X_UART2 + bool "Kernel low-level debugging messages via UART2" + depends on DEBUG_LL && ARCH_CLPS711X + help + Say Y here if you want the debug print routines to direct their + output to the second serial port on these devices. Saying N will + cause the debug messages to appear on the first serial port. + +config DEBUG_S3C2410_PORT + depends on DEBUG_LL && ARCH_S3C2410 + bool "Kernel low-level debugging messages via S3C2410 UART" + help + Say Y here if you want debug print routines to go to one of the + S3C2410 internal UARTs. The chosen UART must have been configured + before it is used. + +config DEBUG_S3C2410_UART + depends on ARCH_S3C2410 + int "S3C2410 UART to use for low-level debug" + default "0" + help + Choice for UART for kernel low-level using S3C2410 UARTS, + should be between zero and two. The port must have been + initalised by the boot-loader before use. + + The uncompressor code port configuration is now handled + by CONFIG_S3C2410_LOWLEVEL_UART_PORT. + +endmenu diff --git a/arch/arm/Makefile b/arch/arm/Makefile new file mode 100644 index 0000000..2277e3d --- /dev/null +++ b/arch/arm/Makefile @@ -0,0 +1,216 @@ +# +# arch/arm/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1995-2001 by Russell King + +LDFLAGS_vmlinux :=-p --no-undefined -X +CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) +OBJCOPYFLAGS :=-O binary -R .note -R .comment -S +GZFLAGS :=-9 +#CFLAGS +=-pipe + +# Do not use arch/arm/defconfig - it's always outdated. +# Select a platform tht is kept up-to-date +KBUILD_DEFCONFIG := versatile_defconfig + +ifeq ($(CONFIG_FRAME_POINTER),y) +CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog +endif + +ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) +CPPFLAGS += -mbig-endian +AS += -EB +LD += -EB +else +CPPFLAGS += -mlittle-endian +AS += -EL +LD += -EL +endif + +comma = , + +# This selects which instruction set is used. +# Note that GCC does not numerically define an architecture version +# macro, but instead defines a whole series of macros which makes +# testing for a specific architecture or later rather impossible. +arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) +arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4) +arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 +arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 + +# This selects how we optimise for the processor. +tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 +tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 +tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi +tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 +tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 +tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale +tune-$(CONFIG_CPU_V6) :=-mtune=strongarm + +# Need -Uarm for gcc < 3.x +CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm +AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float + +CHECKFLAGS += -D__arm__ + +#Default value +head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o +textaddr-y := 0xC0008000 + + machine-$(CONFIG_ARCH_RPC) := rpc + machine-$(CONFIG_ARCH_EBSA110) := ebsa110 + machine-$(CONFIG_ARCH_CLPS7500) := clps7500 + incdir-$(CONFIG_ARCH_CLPS7500) := cl7500 + machine-$(CONFIG_FOOTBRIDGE) := footbridge + incdir-$(CONFIG_FOOTBRIDGE) := ebsa285 +textaddr-$(CONFIG_ARCH_CO285) := 0x60008000 + machine-$(CONFIG_ARCH_CO285) := footbridge + incdir-$(CONFIG_ARCH_CO285) := ebsa285 + machine-$(CONFIG_ARCH_SHARK) := shark + machine-$(CONFIG_ARCH_SA1100) := sa1100 +ifeq ($(CONFIG_ARCH_SA1100),y) +# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory +textaddr-$(CONFIG_SA1111) := 0xc0208000 +endif + machine-$(CONFIG_ARCH_PXA) := pxa + machine-$(CONFIG_ARCH_L7200) := l7200 + machine-$(CONFIG_ARCH_INTEGRATOR) := integrator + machine-$(CONFIG_ARCH_CAMELOT) := epxa10db +textaddr-$(CONFIG_ARCH_CLPS711X) := 0xc0028000 + machine-$(CONFIG_ARCH_CLPS711X) := clps711x +textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000 + machine-$(CONFIG_ARCH_IOP3XX) := iop3xx + machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx + machine-$(CONFIG_ARCH_IXP2000) := ixp2000 + machine-$(CONFIG_ARCH_OMAP) := omap + machine-$(CONFIG_ARCH_S3C2410) := s3c2410 + machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x + machine-$(CONFIG_ARCH_VERSATILE) := versatile + machine-$(CONFIG_ARCH_IMX) := imx + machine-$(CONFIG_ARCH_H720X) := h720x + +ifeq ($(CONFIG_ARCH_EBSA110),y) +# This is what happens if you forget the IOCS16 line. +# PCMCIA cards stop working. +CFLAGS_3c589_cs.o :=-DISA_SIXTEEN_BIT_PERIPHERAL +export CFLAGS_3c589_cs.o +endif + +TEXTADDR := $(textaddr-y) +ifeq ($(CONFIG_XIP_KERNEL),y) + DATAADDR := $(TEXTADDR) + xipaddr-$(CONFIG_ARCH_CO285) := 0x5f000000 + xipaddr-y ?= 0xbf000000 + # Replace phys addr with virt addr while keeping offset from base. + TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \ + awk --non-decimal-data '/[:xdigit:]/ \ + { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' ) +endif + +ifeq ($(incdir-y),) +incdir-y := $(machine-y) +endif +INCDIR := arch-$(incdir-y) +ifneq ($(machine-y),) +MACHINE := arch/arm/mach-$(machine-y)/ +else +MACHINE := +endif + +export TEXTADDR DATAADDR GZFLAGS + +# Do we have FASTFPE? +FASTFPE :=arch/arm/fastfpe +ifeq ($(FASTFPE),$(wildcard $(FASTFPE))) +FASTFPE_OBJ :=$(FASTFPE)/ +endif + +# If we have a machine-specific directory, then include it in the build. +core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ +core-y += $(MACHINE) +core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ +core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) +core-$(CONFIG_VFP) += arch/arm/vfp/ + +drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ +drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/ +drivers-$(CONFIG_ARCH_L7200) += drivers/acorn/char/ + +libs-y += arch/arm/lib/ + +# Default target when executing plain make +ifeq ($(CONFIG_XIP_KERNEL),y) +all: xipImage +else +all: zImage +endif + +boot := arch/arm/boot + +# Update machine arch and proc symlinks if something which affects +# them changed. We use .arch to indicate when they were updated +# last, otherwise make uses the target directory mtime. + +include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/MARKER + @echo ' SYMLINK include/asm-arm/arch -> include/asm-arm/$(INCDIR)' +ifneq ($(KBUILD_SRC),) + $(Q)mkdir -p include/asm-arm + $(Q)ln -fsn $(srctree)/include/asm-arm/$(INCDIR) include/asm-arm/arch +else + $(Q)ln -fsn $(INCDIR) include/asm-arm/arch +endif + @touch $@ + +prepare: maketools include/asm-arm/.arch + +.PHONY: maketools FORCE +maketools: include/asm-arm/constants.h include/linux/version.h FORCE + $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h + +# Convert bzImage to zImage +bzImage: zImage + +zImage Image xipImage bootpImage uImage: vmlinux + $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ + +zinstall install: vmlinux + $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ + +CLEAN_FILES += include/asm-arm/constants.h* include/asm-arm/mach-types.h \ + include/asm-arm/arch include/asm-arm/.arch + +# We use MRPROPER_FILES and CLEAN_FILES now +archclean: + $(Q)$(MAKE) $(clean)=$(boot) + +# My testing targets (bypasses dependencies) +bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage +i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ + +arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \ + include/asm-arm/.arch + +include/asm-$(ARCH)/constants.h: arch/$(ARCH)/kernel/asm-offsets.s + $(call filechk,gen-asm-offsets) + +define archhelp + echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' + echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' + echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)' + echo ' bootpImage - Combined zImage and initial RAM disk' + echo ' (supply initrd image via make variable INITRD=<path>)' + echo ' install - Install uncompressed kernel' + echo ' zinstall - Install compressed kernel' + echo ' Install using (your) ~/bin/installkernel or' + echo ' (distribution) /sbin/installkernel or' + echo ' install to $$(INSTALL_PATH) and run lilo' +endef diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile new file mode 100644 index 0000000..937a353 --- /dev/null +++ b/arch/arm/boot/Makefile @@ -0,0 +1,91 @@ +# +# arch/arm/boot/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1995-2002 Russell King +# + +MKIMAGE := $(srctree)/scripts/mkuboot.sh + +ifneq ($(MACHINE),) +include $(srctree)/$(MACHINE)/Makefile.boot +endif + +# Note: the following conditions must always be true: +# ZRELADDR == virt_to_phys(TEXTADDR) +# PARAMS_PHYS must be within 4MB of ZRELADDR +# INITRD_PHYS must be in RAM +ZRELADDR := $(zreladdr-y) +PARAMS_PHYS := $(params_phys-y) +INITRD_PHYS := $(initrd_phys-y) + +export ZRELADDR INITRD_PHYS PARAMS_PHYS + +targets := Image zImage xipImage bootpImage uImage + +ifeq ($(CONFIG_XIP_KERNEL),y) + +$(obj)/xipImage: vmlinux FORCE + $(call if_changed,objcopy) + @echo ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' + +$(obj)/Image $(obj)/zImage: FORCE + @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' + @echo 'Only the xipImage target is available in this case' + @false + +else + +$(obj)/xipImage: FORCE + @echo 'Kernel not configured for XIP (CONFIG_XIP_KERNEL!=y)' + @false + +$(obj)/Image: vmlinux FORCE + $(call if_changed,objcopy) + @echo ' Kernel: $@ is ready' + +$(obj)/compressed/vmlinux: $(obj)/Image FORCE + $(Q)$(MAKE) $(build)=$(obj)/compressed $@ + +$(obj)/zImage: $(obj)/compressed/vmlinux FORCE + $(call if_changed,objcopy) + @echo ' Kernel: $@ is ready' + +endif + +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ + -C none -a $(ZRELADDR) -e $(ZRELADDR) \ + -n 'Linux-$(KERNELRELEASE)' -d $< $@ + +$(obj)/uImage: $(obj)/zImage FORCE + $(call if_changed,uimage) + @echo ' Image $@ is ready' + +$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE + $(Q)$(MAKE) $(build)=$(obj)/bootp $@ + @: + +$(obj)/bootpImage: $(obj)/bootp/bootp FORCE + $(call if_changed,objcopy) + @echo ' Kernel: $@ is ready' + +.PHONY: initrd FORCE +initrd: + @test "$(INITRD_PHYS)" != "" || \ + (echo This machine does not support INITRD; exit -1) + @test "$(INITRD)" != "" || \ + (echo You must specify INITRD; exit -1) + +install: $(obj)/Image + $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(obj)/Image System.map "$(INSTALL_PATH)" + +zinstall: $(obj)/zImage + $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(obj)/zImage System.map "$(INSTALL_PATH)" + +subdir- := bootp compressed diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile new file mode 100644 index 0000000..8e8879b --- /dev/null +++ b/arch/arm/boot/bootp/Makefile @@ -0,0 +1,24 @@ +# +# linux/arch/arm/boot/bootp/Makefile +# + +LDFLAGS_bootp :=-p --no-undefined -X \ + --defsym initrd_phys=$(INITRD_PHYS) \ + --defsym params_phys=$(PARAMS_PHYS) -T +AFLAGS_initrd.o :=-DINITRD=\"$(INITRD)\" + +targets := bootp init.o kernel.o initrd.o + +# Note that bootp.lds picks up kernel.o and initrd.o +$(obj)/bootp: $(src)/bootp.lds $(addprefix $(obj)/,init.o kernel.o initrd.o) FORCE + $(call if_changed,ld) + @: + +# kernel.o and initrd.o includes a binary image using +# .incbin, a dependency which is not tracked automatically + +$(obj)/kernel.o: arch/arm/boot/zImage FORCE + +$(obj)/initrd.o: $(INITRD) FORCE + +.PHONY: $(INITRD) FORCE diff --git a/arch/arm/boot/bootp/bootp.lds b/arch/arm/boot/bootp/bootp.lds new file mode 100644 index 0000000..8e3d81c --- /dev/null +++ b/arch/arm/boot/bootp/bootp.lds @@ -0,0 +1,30 @@ +/* + * linux/arch/arm/boot/bootp/bootp.lds + * + * Copyright (C) 2000-2002 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. + */ +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0; + .text : { + _stext = .; + *(.start) + *(.text) + initrd_size = initrd_end - initrd_start; + _etext = .; + } + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S new file mode 100644 index 0000000..df7bc70 --- /dev/null +++ b/arch/arm/boot/bootp/init.S @@ -0,0 +1,86 @@ +/* + * linux/arch/arm/boot/bootp/init.S + * + * Copyright (C) 2000-2003 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. + * + * "Header" file for splitting kernel + initrd. Note that we pass + * r0 through to r3 straight through. + * + * This demonstrates how to append code to the start of the kernel + * zImage, and boot the kernel without copying it around. This + * example would be simpler; if we didn't have an object of unknown + * size immediately following the kernel, we could build this into + * a binary blob, and concatenate the zImage using the cat command. + */ + .section .start,#alloc,#execinstr + .type _start, #function + .globl _start + +_start: add lr, pc, #-0x8 @ lr = current load addr + adr r13, data + ldmia r13!, {r4-r6} @ r5 = dest, r6 = length + add r4, r4, lr @ r4 = initrd_start + load addr + bl move @ move the initrd + +/* + * Setup the initrd parameters to pass to the kernel. This can only be + * passed in via the tagged list. + */ + ldmia r13, {r5-r9} @ get size and addr of initrd + @ r5 = ATAG_CORE + @ r6 = ATAG_INITRD2 + @ r7 = initrd start + @ r8 = initrd end + @ r9 = param_struct address + + ldr r10, [r9, #4] @ get first tag + teq r10, r5 @ is it ATAG_CORE? +/* + * If we didn't find a valid tag list, create a dummy ATAG_CORE entry. + */ + movne r10, #0 @ terminator + movne r4, #2 @ Size of this entry (2 words) + stmneia r9, {r4, r5, r10} @ Size, ATAG_CORE, terminator + +/* + * find the end of the tag list, and then add an INITRD tag on the end. + * If there is already an INITRD tag, then we ignore it; the last INITRD + * tag takes precidence. + */ +taglist: ldr r10, [r9, #0] @ tag length + teq r10, #0 @ last tag (zero length)? + addne r9, r9, r10, lsl #2 + bne taglist + + mov r5, #4 @ Size of initrd tag (4 words) + stmia r9, {r5, r6, r7, r8, r10} + b kernel_start @ call kernel + +/* + * Move the block of memory length r6 from address r4 to address r5 + */ +move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time + stmia r5!, {r7 - r10} + ldmia r4!, {r7 - r10} + stmia r5!, {r7 - r10} + subs r6, r6, #8 * 4 + bcs move + mov pc, lr + + .size _start, . - _start + + .type data,#object +data: .word initrd_start @ source initrd address + .word initrd_phys @ destination initrd address + .word initrd_size @ initrd size + + .word 0x54410001 @ r5 = ATAG_CORE + .word 0x54420005 @ r6 = ATAG_INITRD2 + .word initrd_phys @ r7 + .word initrd_size @ r8 + .word params_phys @ r9 + .size data, . - data diff --git a/arch/arm/boot/bootp/initrd.S b/arch/arm/boot/bootp/initrd.S new file mode 100644 index 0000000..d81ea18 --- /dev/null +++ b/arch/arm/boot/bootp/initrd.S @@ -0,0 +1,6 @@ + .type initrd_start,#object + .globl initrd_start +initrd_start: + .incbin INITRD + .globl initrd_end +initrd_end: diff --git a/arch/arm/boot/bootp/kernel.S b/arch/arm/boot/bootp/kernel.S new file mode 100644 index 0000000..b87a25c --- /dev/null +++ b/arch/arm/boot/bootp/kernel.S @@ -0,0 +1,6 @@ + .globl kernel_start +kernel_start: + .incbin "arch/arm/boot/zImage" + .globl kernel_end +kernel_end: + .align 2 diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile new file mode 100644 index 0000000..6b505ce --- /dev/null +++ b/arch/arm/boot/compressed/Makefile @@ -0,0 +1,114 @@ +# +# linux/arch/arm/boot/compressed/Makefile +# +# create a compressed vmlinuz image from the original vmlinux +# + +HEAD = head.o +OBJS = misc.o +FONTC = drivers/video/console/font_acorn_8x8.c + +FONT = $(addprefix ../../../../drivers/video/console/, font_acorn_8x8.o) + +# +# Architecture dependencies +# +ifeq ($(CONFIG_ARCH_ACORN),y) +OBJS += ll_char_wr.o $(FONT) +endif + +ifeq ($(CONFIG_ARCH_SHARK),y) +OBJS += head-shark.o ofw-shark.o +endif + +ifeq ($(CONFIG_ARCH_CAMELOT),y) +OBJS += head-epxa10db.o +endif + +ifeq ($(CONFIG_ARCH_L7200),y) +OBJS += head-l7200.o +endif + +ifeq ($(CONFIG_ARCH_CLPS7500),y) +HEAD = head-clps7500.o +endif + +ifeq ($(CONFIG_ARCH_P720T),y) +# Borrow this code from SA1100 +OBJS += head-sa1100.o +endif + +ifeq ($(CONFIG_ARCH_SA1100),y) +OBJS += head-sa1100.o +endif + +ifeq ($(CONFIG_CPU_XSCALE),y) +OBJS += head-xscale.o +endif + +ifeq ($(CONFIG_PXA_SHARPSL),y) +OBJS += head-sharpsl.o +endif + +ifeq ($(CONFIG_DEBUG_ICEDCC),y) +OBJS += ice-dcc.o +endif + +ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) +OBJS += big-endian.o +endif + +# +# We now have a PIC decompressor implementation. Decompressors running +# from RAM should not define ZTEXTADDR. Decompressors running directly +# from ROM or Flash must define ZTEXTADDR (preferably via the config) +# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK +ifeq ($(CONFIG_ZBOOT_ROM),y) +ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT) +ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS) +else +ZTEXTADDR := 0 +ZBSSADDR := ALIGN(4) +endif + +SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ + +targets := vmlinux vmlinux.lds piggy.gz piggy.o $(FONT) \ + head.o misc.o $(OBJS) +EXTRA_CFLAGS := -fpic +EXTRA_AFLAGS := + +# Supply ZRELADDR, INITRD_PHYS and PARAMS_PHYS to the decompressor via +# linker symbols. We only define initrd_phys and params_phys if the +# machine class defined the corresponding makefile variable. +LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR) +ifneq ($(INITRD_PHYS),) +LDFLAGS_vmlinux += --defsym initrd_phys=$(INITRD_PHYS) +endif +ifneq ($(PARAMS_PHYS),) +LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS) +endif +LDFLAGS_vmlinux += -p --no-undefined -X \ + $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) -T + +# Don't allow any static data in misc.o, which +# would otherwise mess up our GOT table +CFLAGS_misc.o := -Dstatic= + +$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ + $(addprefix $(obj)/, $(OBJS)) FORCE + $(call if_changed,ld) + @: + +$(obj)/piggy.gz: $(obj)/../Image FORCE + $(call if_changed,gzip) + +$(obj)/piggy.o: $(obj)/piggy.gz FORCE + +CFLAGS_font_acorn_8x8.o := -Dstatic= + +$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config + @sed "$(SEDFLAGS)" < $< > $@ + +$(obj)/misc.o: $(obj)/misc.c include/asm/arch/uncompress.h lib/inflate.c + diff --git a/arch/arm/boot/compressed/Makefile.debug b/arch/arm/boot/compressed/Makefile.debug new file mode 100644 index 0000000..491a037 --- /dev/null +++ b/arch/arm/boot/compressed/Makefile.debug @@ -0,0 +1,23 @@ +# +# linux/arch/arm/boot/compressed/Makefile +# +# create a compressed vmlinux image from the original vmlinux +# + +COMPRESSED_EXTRA=../../lib/ll_char_wr.o +OBJECTS=misc-debug.o ll_char_wr.aout.o + +CFLAGS=-D__KERNEL__ -O2 -DSTDC_HEADERS -DSTANDALONE_DEBUG -Wall -I../../../../include -c + +test-gzip: piggy.aout.o $(OBJECTS) + $(CC) -o $@ $(OBJECTS) piggy.aout.o + +misc-debug.o: misc.c + $(CC) $(CFLAGS) -o $@ misc.c + +piggy.aout.o: piggy.o + arm-linuxelf-objcopy --change-leading-char -I elf32-arm -O arm-aout32-linux piggy.o piggy.aout.o + +ll_char_wr.aout.o: $(COMPRESSED_EXTRA) + arm-linuxelf-objcopy --change-leading-char -I elf32-arm -O arm-aout32-linux $(COMPRESSED_EXTRA) ll_char_wr.aout.o + diff --git a/arch/arm/boot/compressed/big-endian.S b/arch/arm/boot/compressed/big-endian.S new file mode 100644 index 0000000..25ab26f --- /dev/null +++ b/arch/arm/boot/compressed/big-endian.S @@ -0,0 +1,13 @@ +/* + * linux/arch/arm/boot/compressed/big-endian.S + * + * Switch CPU into big endian mode. + * Author: Nicolas Pitre + */ + + .section ".start", #alloc, #execinstr + + mrc p15, 0, r0, c1, c0, 0 @ read control reg + orr r0, r0, #(1 << 7) @ enable big endian mode + mcr p15, 0, r0, c1, c0, 0 @ write control reg + diff --git a/arch/arm/boot/compressed/head-clps7500.S b/arch/arm/boot/compressed/head-clps7500.S new file mode 100644 index 0000000..4a8a689 --- /dev/null +++ b/arch/arm/boot/compressed/head-clps7500.S @@ -0,0 +1,87 @@ +/* + * linux/arch/arm/boot/compressed/head.S + * + * Copyright (C) 1999, 2000, 2001 Nexus Electronics Ltd + */ + +#include <linux/config.h> + + /* There are three different ways the kernel can be + booted on a 7500 system: from Angel (loaded in RAM), from + 16-bit ROM or from 32-bit Flash. Luckily, a single kernel + image does for them all. */ + /* This branch is taken if the CPU memory width matches the + actual device in use. The default at power on is 16 bits + so we must be prepared for a mismatch. */ + .section ".start", "ax" +2: + b 1f + .word 0xffff + .word 0xb632 @ mov r11, #0x03200000 + .word 0xe3a0 + .word 0x0000 @ mov r0, #0 + .word 0xe3a0 + .word 0x0080 @ strb r0, [r11, #0x80] + .word 0xe5cb + .word 0xf000 @ mov pc, #0 + .word 0xe3a0 +1: + adr r1, 2b + teq r1, #0 + bne .Langel + /* This is a direct-from-ROM boot. Copy the kernel into + RAM and run it there. */ + mov r0, #0x30 + mcr p15, 0, r0, c1, c0, 0 + mov r0, #0x13 + msr cpsr_cxsf, r0 + mov r12, #0x03000000 @ point to LEDs + orr r12, r12, #0x00020000 + orr r12, r12, #0xba00 + mov r0, #0x5500 + str r0, [r12] + mov r0, #0x10000000 + orr r0, r0, #0x8000 + mov r4, r0 + ldr r2, =_end +2: + ldr r3, [r1], #4 + str r3, [r0], #4 + teq r0, r2 + bne 2b + mov r0, #0xff00 + str r0, [r12] +1: + mov r12, #0x03000000 @ point to LEDs + orr r12, r12, #0x00020000 + orr r12, r12, #0xba00 + mov r0, #0xfe00 + str r0, [r12] + + adr lr, 1f + mov r0, #0 + mov r1, #14 /* MACH_TYPE_CLPS7500 */ + mov pc, lr +.Langel: +#ifdef CONFIG_ANGELBOOT + /* Call Angel to switch into SVC mode. */ + mov r0, #0x17 + swi 0x123456 +#endif + /* Ensure all interrupts are off and MMU disabled */ + mrs r0, cpsr + orr r0, r0, #0xc0 + msr cpsr_cxsf, r0 + + adr lr, 1b + orr lr, lr, #0x10000000 + mov r0, #0x30 @ MMU off + mcr p15, 0, r0, c1, c0, 0 + mov r0, r0 + mov pc, lr + + .ltorg + +1: +/* And the rest */ +#include "head.S" diff --git a/arch/arm/boot/compressed/head-epxa10db.S b/arch/arm/boot/compressed/head-epxa10db.S new file mode 100644 index 0000000..757681f --- /dev/null +++ b/arch/arm/boot/compressed/head-epxa10db.S @@ -0,0 +1,5 @@ +#include <asm/mach-types.h> +#include <asm/arch/excalibur.h> + + .section ".start", "ax" + mov r7, #MACH_TYPE_CAMELOT diff --git a/arch/arm/boot/compressed/head-l7200.S b/arch/arm/boot/compressed/head-l7200.S new file mode 100644 index 0000000..b08bd23 --- /dev/null +++ b/arch/arm/boot/compressed/head-l7200.S @@ -0,0 +1,30 @@ +/* + * linux/arch/arm/boot/compressed/head-l7200.S + * + * Copyright (C) 2000 Steve Hill <sjhill@cotw.com> + * + * Some code borrowed from Nicolas Pitre's 'head-sa1100.S' file. This + * is merged with head.S by the linker. + */ + +#include <linux/config.h> +#include <asm/mach-types.h> + +#ifndef CONFIG_ARCH_L7200 +#error What am I doing here... +#endif + + .section ".start", "ax" + +__L7200_start: + mov r0, #0x00100000 @ FLASH address of initrd + mov r2, #0xf1000000 @ RAM address of initrd + add r3, r2, #0x00700000 @ Size of initrd +1: + ldmia r0!, {r4, r5, r6, r7} + stmia r2!, {r4, r5, r6, r7} + cmp r2, r3 + ble 1b + + mov r8, #0 @ Zero it out + mov r7, #MACH_TYPE_L7200 @ Set architecture ID diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S new file mode 100644 index 0000000..5aefffd --- /dev/null +++ b/arch/arm/boot/compressed/head-sa1100.S @@ -0,0 +1,48 @@ +/* + * linux/arch/arm/boot/compressed/head-sa1100.S + * + * Copyright (C) 1999 Nicolas Pitre <nico@cam.org> + * + * SA1100 specific tweaks. This is merged into head.S by the linker. + * + */ + +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/mach-types.h> + + .section ".start", "ax" + +__SA1100_start: + + @ Preserve r8/r7 i.e. kernel entry values +#ifdef CONFIG_SA1100_COLLIE + mov r7, #MACH_TYPE_COLLIE +#endif +#ifdef CONFIG_SA1100_SIMPAD + @ UNTIL we've something like an open bootldr + mov r7, #MACH_TYPE_SIMPAD @should be 87 +#endif + mrc p15, 0, r0, c1, c0, 0 @ read control reg + ands r0, r0, #0x0d + beq 99f + + @ Data cache might be active. + @ Be sure to flush kernel binary out of the cache, + @ whatever state it is, before it is turned off. + @ This is done by fetching through currently executed + @ memory to be sure we hit the same cache. + bic r2, pc, #0x1f + add r3, r2, #0x4000 @ 16 kb is quite enough... +1: ldr r0, [r2], #32 + teq r2, r3 + bne 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches + + @ disabling MMU and caches + mrc p15, 0, r0, c1, c0, 0 @ read control reg + bic r0, r0, #0x0d @ clear WB, DC, MMU + bic r0, r0, #0x1000 @ clear Icache + mcr p15, 0, r0, c1, c0, 0 +99: diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S new file mode 100644 index 0000000..848f60e --- /dev/null +++ b/arch/arm/boot/compressed/head-shark.S @@ -0,0 +1,115 @@ +/* The head-file for the Shark + * by Alexander Schulz + * + * Does the following: + * - get the memory layout from firmware. This can only be done as long as the mmu + * is still on. + * - switch the mmu off, so we have physical addresses + * - copy the kernel to 0x08508000. This is done to have a fixed address where the + * C-parts (misc.c) are executed. This address must be known at compile-time, + * but the load-address of the kernel depends on how much memory is installed. + * - Jump to this location. + * - Set r8 with 0, r7 with the architecture ID for head.S + */ + +#include <linux/linkage.h> + +#include <asm/assembler.h> + + .section ".start", "ax" + + b __beginning + +__ofw_data: .long 0 @ the number of memory blocks + .space 128 @ (startaddr,size) ... + .space 128 @ bootargs + .align + +__beginning: mov r4, r0 @ save the entry to the firmware + + mov r0, #0xC0 @ disable irq and fiq + mov r1, r0 + mrs r3, cpsr + bic r2, r3, r0 + eor r2, r2, r1 + msr cpsr_c, r2 + + mov r0, r4 @ get the Memory layout from firmware + adr r1, __ofw_data + add r2, r1, #4 + mov lr, pc + b ofw_init + mov r1, #0 + + adr r2, __mmu_off @ calculate physical address + sub r2, r2, #0xf0000000 @ openprom maps us at f000 virt, 0e50 phys + adr r0, __ofw_data + ldr r0, [r0, #4] + add r2, r2, r0 + add r2, r2, #0x00500000 + + mrc p15, 0, r3, c1, c0 + bic r3, r3, #0xC @ Write Buffer and DCache + bic r3, r3, #0x1000 @ ICache + mcr p15, 0, r3, c1, c0 @ disabled + + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4 + + bic r3, r3, #0x1 @ MMU + mcr p15, 0, r3, c1, c0 @ disabled + + mov pc, r2 + +__copy_target: .long 0x08508000 +__copy_end: .long 0x08608000 + + .word _start + .word __bss_start + + .align +__temp_stack: .space 128 + +__mmu_off: + adr r0, __ofw_data + ldr r0, [r0, #4] + orr r0, r0, #0x00600000 + + ldr r1, __copy_end + ldr r3, __copy_target + +/* r0 = 0x0e600000 (current end of kernelcode) + * r3 = 0x08508000 (where it should begin) + * r1 = 0x08608000 (end of copying area, 1MB) + * The kernel is compressed, so 1 MB should be enough. + * copy the kernel to the beginning of physical memory + * We start from the highest address, so we can copy + * from 0x08500000 to 0x08508000 if we have only 8MB + */ + + +__Copy: ldr r2, [r0], #-4 + str r2, [r1], #-4 + teq r1, r3 + bne __Copy + /* and jump to it */ + adr r2, __go_on + adr r0, __ofw_data + ldr r0, [r0, #4] + sub r2, r2, r0 + sub r2, r2, #0x00500000 + ldr r0, __copy_target + add r2, r2, r0 + mov pc, r2 + +__go_on: + adr sp, __temp_stack + add sp, sp, #128 + adr r0, __ofw_data + mov lr, pc + b create_params + + mov r8, #0 + mov r7, #15 diff --git a/arch/arm/boot/compressed/head-sharpsl.S b/arch/arm/boot/compressed/head-sharpsl.S new file mode 100644 index 0000000..d6bf8a2 --- /dev/null +++ b/arch/arm/boot/compressed/head-sharpsl.S @@ -0,0 +1,92 @@ +/* + * linux/arch/arm/boot/compressed/head-sharpsl.S + * + * Copyright (C) 2004-2005 Richard Purdie <rpurdie@rpsys.net> + * + * Sharp's bootloader doesn't pass any kind of machine ID + * so we have to figure out the machine for ourselves... + * + * Support for Poodle, Corgi (SL-C700), Shepherd (SL-C750) + * and Husky (SL-C760). + * + */ + +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/mach-types.h> + +#ifndef CONFIG_PXA_SHARPSL +#error What am I doing here... +#endif + + .section ".start", "ax" + +__SharpSL_start: + + ldr r1, .W100ADDR @ Base address of w100 chip + regs offset + + mov r6, #0x31 @ Load Magic Init value + str r6, [r1, #0x280] @ to SCRATCH_UMSK + mov r5, #0x3000 +.W100LOOP: + subs r5, r5, #1 + bne .W100LOOP + mov r6, #0x30 @ Load 2nd Magic Init value + str r6, [r1, #0x280] @ to SCRATCH_UMSK + + ldr r6, [r1, #0] @ Load Chip ID + ldr r3, .W100ID + ldr r7, .POODLEID + cmp r6, r3 + bne .SHARPEND @ We have no w100 - Poodle + + mrc p15, 0, r6, c0, c0 @ Get Processor ID + and r6, r6, #0xffffff00 + ldr r7, .CORGIID + ldr r3, .PXA255ID + cmp r6, r3 + blo .SHARPEND @ We have a PXA250 - Corgi + + mov r1, #0x0c000000 @ Base address of NAND chip + ldrb r3, [r1, #24] @ Load FLASHCTL + bic r3, r3, #0x11 @ SET NCE + orr r3, r3, #0x0a @ SET CLR + FLWP + strb r3, [r1, #24] @ Save to FLASHCTL + mov r2, #0x90 @ Command "readid" + strb r2, [r1, #20] @ Save to FLASHIO + bic r3, r3, #2 @ CLR CLE + orr r3, r3, #4 @ SET ALE + strb r3, [r1, #24] @ Save to FLASHCTL + mov r2, #0 @ Address 0x00 + strb r2, [r1, #20] @ Save to FLASHIO + bic r3, r3, #4 @ CLR ALE + strb r3, [r1, #24] @ Save to FLASHCTL +.SHARP1: + ldrb r3, [r1, #24] @ Load FLASHCTL + tst r3, #32 @ Is chip ready? + beq .SHARP1 + ldrb r2, [r1, #20] @ NAND Manufacturer ID + ldrb r3, [r1, #20] @ NAND Chip ID + ldr r7, .SHEPHERDID + cmp r3, #0x76 @ 64MiB flash + beq .SHARPEND @ We have Shepherd + ldr r7, .HUSKYID @ Must be Husky + b .SHARPEND + +.PXA255ID: + .word 0x69052d00 @ PXA255 Processor ID +.W100ID: + .word 0x57411002 @ w100 Chip ID +.W100ADDR: + .word 0x08010000 @ w100 Chip ID Reg Address +.POODLEID: + .word MACH_TYPE_POODLE +.CORGIID: + .word MACH_TYPE_CORGI +.SHEPHERDID: + .word MACH_TYPE_SHEPHERD +.HUSKYID: + .word MACH_TYPE_HUSKY +.SHARPEND: + + diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S new file mode 100644 index 0000000..665bd2c --- /dev/null +++ b/arch/arm/boot/compressed/head-xscale.S @@ -0,0 +1,49 @@ +/* + * linux/arch/arm/boot/compressed/head-xscale.S + * + * XScale specific tweaks. This is merged into head.S by the linker. + * + */ + +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/mach-types.h> + + .section ".start", "ax" + +__XScale_start: + + @ Preserve r8/r7 i.e. kernel entry values + + @ Data cache might be active. + @ Be sure to flush kernel binary out of the cache, + @ whatever state it is, before it is turned off. + @ This is done by fetching through currently executed + @ memory to be sure we hit the same cache. + bic r2, pc, #0x1f + add r3, r2, #0x10000 @ 64 kb is quite enough... +1: ldr r0, [r2], #32 + teq r2, r3 + bne 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches + + @ disabling MMU and caches + mrc p15, 0, r0, c1, c0, 0 @ read control reg + bic r0, r0, #0x05 @ clear DC, MMU + bic r0, r0, #0x1000 @ clear Icache + mcr p15, 0, r0, c1, c0, 0 + +#ifdef CONFIG_ARCH_LUBBOCK + mov r7, #MACH_TYPE_LUBBOCK +#endif + +#ifdef CONFIG_ARCH_COTULLA_IDP + mov r7, #MACH_TYPE_COTULLA_IDP +#endif + +#ifdef CONFIG_MACH_GTWX5715 + mov r7, #(MACH_TYPE_GTWX5715 & 0xff) + orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) +#endif + diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S new file mode 100644 index 0000000..c0e7aff --- /dev/null +++ b/arch/arm/boot/compressed/head.S @@ -0,0 +1,786 @@ +/* + * linux/arch/arm/boot/compressed/head.S + * + * Copyright (C) 1996-2002 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/linkage.h> + +/* + * Debugging stuff + * + * Note that these macros must not contain any code which is not + * 100% relocatable. Any attempt to do so will result in a crash. + * Please select one of the following when turning on debugging. + */ +#ifdef DEBUG +#if defined(CONFIG_DEBUG_DC21285_PORT) + .macro loadsp, rb + mov \rb, #0x42000000 + .endm + .macro writeb, rb + str \rb, [r3, #0x160] + .endm +#elif defined(CONFIG_DEBUG_ICEDCC) + .macro loadsp, rb + .endm + .macro writeb, rb + mcr p14, 0, \rb, c0, c1, 0 + .endm +#elif defined(CONFIG_FOOTBRIDGE) + .macro loadsp, rb + mov \rb, #0x7c000000 + .endm + .macro writeb, rb + strb \rb, [r3, #0x3f8] + .endm +#elif defined(CONFIG_ARCH_RPC) + .macro loadsp, rb + mov \rb, #0x03000000 + orr \rb, \rb, #0x00010000 + .endm + .macro writeb, rb + strb \rb, [r3, #0x3f8 << 2] + .endm +#elif defined(CONFIG_ARCH_INTEGRATOR) + .macro loadsp, rb + mov \rb, #0x16000000 + .endm + .macro writeb, rb + strb \rb, [r3, #0] + .endm +#elif defined(CONFIG_ARCH_PXA) /* Xscale-type */ + .macro loadsp, rb + mov \rb, #0x40000000 + orr \rb, \rb, #0x00100000 + .endm + .macro writeb, rb + strb \rb, [r3, #0] + .endm +#elif defined(CONFIG_ARCH_SA1100) + .macro loadsp, rb + mov \rb, #0x80000000 @ physical base address +# if defined(CONFIG_DEBUG_LL_SER3) + add \rb, \rb, #0x00050000 @ Ser3 +# else + add \rb, \rb, #0x00010000 @ Ser1 +# endif + .endm + .macro writeb, rb + str \rb, [r3, #0x14] @ UTDR + .endm +#elif defined(CONFIG_ARCH_IXP4XX) + .macro loadsp, rb + mov \rb, #0xc8000000 + .endm + .macro writeb, rb + str \rb, [r3, #0] +#elif defined(CONFIG_ARCH_IXP2000) + .macro loadsp, rb + mov \rb, #0xc0000000 + orr \rb, \rb, #0x00030000 + .endm + .macro writeb, rb + str \rb, [r3, #0] + .endm +#elif defined(CONFIG_ARCH_LH7A40X) + .macro loadsp, rb + ldr \rb, =0x80000700 @ UART2 UARTBASE + .endm + .macro writeb, rb + strb \rb, [r3, #0] + .endm +#elif defined(CONFIG_ARCH_OMAP) + .macro loadsp, rb + mov \rb, #0xff000000 @ physical base address + add \rb, \rb, #0x00fb0000 +#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3) + add \rb, \rb, #0x00000800 +#endif +#ifdef CONFIG_OMAP_LL_DEBUG_UART3 + add \rb, \rb, #0x00009000 +#endif + .endm + .macro writeb, rb + strb \rb, [r3] + .endm +#elif defined(CONFIG_ARCH_IOP331) + .macro loadsp, rb + mov \rb, #0xff000000 + orr \rb, \rb, #0x00ff0000 + orr \rb, \rb, #0x0000f700 @ location of the UART + .endm + .macro writeb, rb + str \rb, [r3, #0] + .endm +#elif defined(CONFIG_ARCH_S3C2410) + .macro loadsp, rb + mov \rb, #0x50000000 + add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT + .endm + .macro writeb, rb + strb \rb, [r3, #0x20] + .endm +#else +#error no serial architecture defined +#endif +#endif + + .macro kputc,val + mov r0, \val + bl putc + .endm + + .macro kphex,val,len + mov r0, \val + mov r1, #\len + bl phex + .endm + + .macro debug_reloc_start +#ifdef DEBUG + kputc #'\n' + kphex r6, 8 /* processor id */ + kputc #':' + kphex r7, 8 /* architecture id */ + kputc #':' + mrc p15, 0, r0, c1, c0 + kphex r0, 8 /* control reg */ + kputc #'\n' + kphex r5, 8 /* decompressed kernel start */ + kputc #'-' + kphex r8, 8 /* decompressed kernel end */ + kputc #'>' + kphex r4, 8 /* kernel execution address */ + kputc #'\n' +#endif + .endm + + .macro debug_reloc_end +#ifdef DEBUG + kphex r5, 8 /* end of kernel */ + kputc #'\n' + mov r0, r4 + bl memdump /* dump 256 bytes at start of kernel */ +#endif + .endm + + .section ".start", #alloc, #execinstr +/* + * sort out different calling conventions + */ + .align +start: + .type start,#function + .rept 8 + mov r0, r0 + .endr + + b 1f + .word 0x016f2818 @ Magic numbers to help the loader + .word start @ absolute load/run zImage address + .word _edata @ zImage end address +1: mov r7, r1 @ save architecture ID + mov r8, #0 @ save r0 + +#ifndef __ARM_ARCH_2__ + /* + * Booting from Angel - need to enter SVC mode and disable + * FIQs/IRQs (numeric definitions from angel arm.h source). + * We only do this if we were in user mode on entry. + */ + mrs r2, cpsr @ get current mode + tst r2, #3 @ not user? + bne not_angel + mov r0, #0x17 @ angel_SWIreason_EnterSVC + swi 0x123456 @ angel_SWI_ARM +not_angel: + mrs r2, cpsr @ turn off interrupts to + orr r2, r2, #0xc0 @ prevent angel from running + msr cpsr_c, r2 +#else + teqp pc, #0x0c000003 @ turn off interrupts +#endif + + /* + * Note that some cache flushing and other stuff may + * be needed here - is there an Angel SWI call for this? + */ + + /* + * some architecture specific code can be inserted + * by the linker here, but it should preserve r7 and r8. + */ + + .text + adr r0, LC0 + ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} + subs r0, r0, r1 @ calculate the delta offset + + @ if delta is zero, we are + beq not_relocated @ running at the address we + @ were linked at. + + /* + * We're running at a different address. We need to fix + * up various pointers: + * r5 - zImage base address + * r6 - GOT start + * ip - GOT end + */ + add r5, r5, r0 + add r6, r6, r0 + add ip, ip, r0 + +#ifndef CONFIG_ZBOOT_ROM + /* + * If we're running fully PIC === CONFIG_ZBOOT_ROM = n, + * we need to fix up pointers into the BSS region. + * r2 - BSS start + * r3 - BSS end + * sp - stack pointer + */ + add r2, r2, r0 + add r3, r3, r0 + add sp, sp, r0 + + /* + * Relocate all entries in the GOT table. + */ +1: ldr r1, [r6, #0] @ relocate entries in the GOT + add r1, r1, r0 @ table. This fixes up the + str r1, [r6], #4 @ C references. + cmp r6, ip + blo 1b +#else + + /* + * Relocate entries in the GOT table. We only relocate + * the entries that are outside the (relocated) BSS region. + */ +1: ldr r1, [r6, #0] @ relocate entries in the GOT + cmp r1, r2 @ entry < bss_start || + cmphs r3, r1 @ _end < entry + addlo r1, r1, r0 @ table. This fixes up the + str r1, [r6], #4 @ C references. + cmp r6, ip + blo 1b +#endif + +not_relocated: mov r0, #0 +1: str r0, [r2], #4 @ clear bss + str r0, [r2], #4 + str r0, [r2], #4 + str r0, [r2], #4 + cmp r2, r3 + blo 1b + + /* + * The C runtime environment should now be setup + * sufficiently. Turn the cache on, set up some + * pointers, and start decompressing. + */ + bl cache_on + + mov r1, sp @ malloc space above stack + add r2, sp, #0x10000 @ 64k max + +/* + * Check to see if we will overwrite ourselves. + * r4 = final kernel address + * r5 = start of this image + * r2 = end of malloc space (and therefore this image) + * We basically want: + * r4 >= r2 -> OK + * r4 + image length <= r5 -> OK + */ + cmp r4, r2 + bhs wont_overwrite + add r0, r4, #4096*1024 @ 4MB largest kernel size + cmp r0, r5 + bls wont_overwrite + + mov r5, r2 @ decompress after malloc space + mov r0, r5 + mov r3, r7 + bl decompress_kernel + + add r0, r0, #127 + bic r0, r0, #127 @ align the kernel length +/* + * r0 = decompressed kernel length + * r1-r3 = unused + * r4 = kernel execution address + * r5 = decompressed kernel start + * r6 = processor ID + * r7 = architecture ID + * r8-r14 = unused + */ + add r1, r5, r0 @ end of decompressed kernel + adr r2, reloc_start + ldr r3, LC1 + add r3, r2, r3 +1: ldmia r2!, {r8 - r13} @ copy relocation code + stmia r1!, {r8 - r13} + ldmia r2!, {r8 - r13} + stmia r1!, {r8 - r13} + cmp r2, r3 + blo 1b + + bl cache_clean_flush + add pc, r5, r0 @ call relocation code + +/* + * We're not in danger of overwriting ourselves. Do this the simple way. + * + * r4 = kernel execution address + * r7 = architecture ID + */ +wont_overwrite: mov r0, r4 + mov r3, r7 + bl decompress_kernel + b call_kernel + + .type LC0, #object +LC0: .word LC0 @ r1 + .word __bss_start @ r2 + .word _end @ r3 + .word zreladdr @ r4 + .word _start @ r5 + .word _got_start @ r6 + .word _got_end @ ip + .word user_stack+4096 @ sp +LC1: .word reloc_end - reloc_start + .size LC0, . - LC0 + +#ifdef CONFIG_ARCH_RPC + .globl params +params: ldr r0, =params_phys + mov pc, lr + .ltorg + .align +#endif + +/* + * Turn on the cache. We need to setup some page tables so that we + * can have both the I and D caches on. + * + * We place the page tables 16k down from the kernel execution address, + * and we hope that nothing else is using it. If we're using it, we + * will go pop! + * + * On entry, + * r4 = kernel execution address + * r6 = processor ID + * r7 = architecture number + * r8 = run-time address of "start" + * On exit, + * r1, r2, r3, r8, r9, r12 corrupted + * This routine must preserve: + * r4, r5, r6, r7 + */ + .align 5 +cache_on: mov r3, #8 @ cache_on function + b call_cache_fn + +__setup_mmu: sub r3, r4, #16384 @ Page directory size + bic r3, r3, #0xff @ Align the pointer + bic r3, r3, #0x3f00 +/* + * Initialise the page tables, turning on the cacheable and bufferable + * bits for the RAM area only. + */ + mov r0, r3 + mov r8, r0, lsr #18 + mov r8, r8, lsl #18 @ start of RAM + add r9, r8, #0x10000000 @ a reasonable RAM size + mov r1, #0x12 + orr r1, r1, #3 << 10 + add r2, r3, #16384 +1: cmp r1, r8 @ if virt > start of RAM + orrhs r1, r1, #0x0c @ set cacheable, bufferable + cmp r1, r9 @ if virt > end of RAM + bichs r1, r1, #0x0c @ clear cacheable, bufferable + str r1, [r0], #4 @ 1:1 mapping + add r1, r1, #1048576 + teq r0, r2 + bne 1b +/* + * If ever we are running from Flash, then we surely want the cache + * to be enabled also for our execution instance... We map 2MB of it + * so there is no map overlap problem for up to 1 MB compressed kernel. + * If the execution is in RAM then we would only be duplicating the above. + */ + mov r1, #0x1e + orr r1, r1, #3 << 10 + mov r2, pc, lsr #20 + orr r1, r1, r2, lsl #20 + add r0, r3, r2, lsl #2 + str r1, [r0], #4 + add r1, r1, #1048576 + str r1, [r0] + mov pc, lr + +__armv4_cache_on: + mov r12, lr + bl __setup_mmu + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs + mrc p15, 0, r0, c1, c0, 0 @ read control reg + orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement + orr r0, r0, #0x0030 + bl __common_cache_on + mov r0, #0 + mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs + mov pc, r12 + +__arm6_cache_on: + mov r12, lr + bl __setup_mmu + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 + mov r0, #0x30 + bl __common_cache_on + mov r0, #0 + mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 + mov pc, r12 + +__common_cache_on: +#ifndef DEBUG + orr r0, r0, #0x000d @ Write buffer, mmu +#endif + mov r1, #-1 + mcr p15, 0, r3, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c3, c0, 0 @ load domain access control + mcr p15, 0, r0, c1, c0, 0 @ load control register + mov pc, lr + +/* + * All code following this line is relocatable. It is relocated by + * the above code to the end of the decompressed kernel image and + * executed there. During this time, we have no stacks. + * + * r0 = decompressed kernel length + * r1-r3 = unused + * r4 = kernel execution address + * r5 = decompressed kernel start + * r6 = processor ID + * r7 = architecture ID + * r8-r14 = unused + */ + .align 5 +reloc_start: add r8, r5, r0 + debug_reloc_start + mov r1, r4 +1: + .rept 4 + ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel + stmia r1!, {r0, r2, r3, r9 - r13} + .endr + + cmp r5, r8 + blo 1b + debug_reloc_end + +call_kernel: bl cache_clean_flush + bl cache_off + mov r0, #0 + mov r1, r7 @ restore architecture number + mov pc, r4 @ call kernel + +/* + * Here follow the relocatable cache support functions for the + * various processors. This is a generic hook for locating an + * entry and jumping to an instruction at the specified offset + * from the start of the block. Please note this is all position + * independent code. + * + * r1 = corrupted + * r2 = corrupted + * r3 = block offset + * r6 = corrupted + * r12 = corrupted + */ + +call_cache_fn: adr r12, proc_types + mrc p15, 0, r6, c0, c0 @ get processor ID +1: ldr r1, [r12, #0] @ get value + ldr r2, [r12, #4] @ get mask + eor r1, r1, r6 @ (real ^ match) + tst r1, r2 @ & mask + addeq pc, r12, r3 @ call cache function + add r12, r12, #4*5 + b 1b + +/* + * Table for cache operations. This is basically: + * - CPU ID match + * - CPU ID mask + * - 'cache on' method instruction + * - 'cache off' method instruction + * - 'cache flush' method instruction + * + * We match an entry using: ((real_id ^ match) & mask) == 0 + * + * Writethrough caches generally only need 'on' and 'off' + * methods. Writeback caches _must_ have the flush method + * defined. + */ + .type proc_types,#object +proc_types: + .word 0x41560600 @ ARM6/610 + .word 0xffffffe0 + b __arm6_cache_off @ works, but slow + b __arm6_cache_off + mov pc, lr +@ b __arm6_cache_on @ untested +@ b __arm6_cache_off +@ b __armv3_cache_flush + + .word 0x00000000 @ old ARM ID + .word 0x0000f000 + mov pc, lr + mov pc, lr + mov pc, lr + + .word 0x41007000 @ ARM7/710 + .word 0xfff8fe00 + b __arm7_cache_off + b __arm7_cache_off + mov pc, lr + + .word 0x41807200 @ ARM720T (writethrough) + .word 0xffffff00 + b __armv4_cache_on + b __armv4_cache_off + mov pc, lr + + .word 0x00007000 @ ARM7 IDs + .word 0x0000f000 + mov pc, lr + mov pc, lr + mov pc, lr + + @ Everything from here on will be the new ID system. + + .word 0x4401a100 @ sa110 / sa1100 + .word 0xffffffe0 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0x6901b110 @ sa1110 + .word 0xfffffff0 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + @ These match on the architecture ID + + .word 0x00020000 @ ARMv4T + .word 0x000f0000 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0x00050000 @ ARMv5TE + .word 0x000f0000 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0x00060000 @ ARMv5TEJ + .word 0x000f0000 + b __armv4_cache_on + b __armv4_cache_off + b __armv4_cache_flush + + .word 0x00070000 @ ARMv6 + .word 0x000f0000 + b __armv4_cache_on + b __armv4_cache_off + b __armv6_cache_flush + + .word 0 @ unrecognised type + .word 0 + mov pc, lr + mov pc, lr + mov pc, lr + + .size proc_types, . - proc_types + +/* + * Turn off the Cache and MMU. ARMv3 does not support + * reading the control register, but ARMv4 does. + * + * On entry, r6 = processor ID + * On exit, r0, r1, r2, r3, r12 corrupted + * This routine must preserve: r4, r6, r7 + */ + .align 5 +cache_off: mov r3, #12 @ cache_off function + b call_cache_fn + +__armv4_cache_off: + mrc p15, 0, r0, c1, c0 + bic r0, r0, #0x000d + mcr p15, 0, r0, c1, c0 @ turn MMU and cache off + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4 + mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 + mov pc, lr + +__arm6_cache_off: + mov r0, #0x00000030 @ ARM6 control reg. + b __armv3_cache_off + +__arm7_cache_off: + mov r0, #0x00000070 @ ARM7 control reg. + b __armv3_cache_off + +__armv3_cache_off: + mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3 + mov pc, lr + +/* + * Clean and flush the cache to maintain consistency. + * + * On entry, + * r6 = processor ID + * On exit, + * r1, r2, r3, r11, r12 corrupted + * This routine must preserve: + * r0, r4, r5, r6, r7 + */ + .align 5 +cache_clean_flush: + mov r3, #16 + b call_cache_fn + +__armv6_cache_flush: + mov r1, #0 + mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D + mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB + mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +__armv4_cache_flush: + mov r2, #64*1024 @ default: 32K dcache size (*2) + mov r11, #32 @ default: 32 byte line size + mrc p15, 0, r3, c0, c0, 1 @ read cache type + teq r3, r6 @ cache ID register present? + beq no_cache_id + mov r1, r3, lsr #18 + and r1, r1, #7 + mov r2, #1024 + mov r2, r2, lsl r1 @ base dcache size *2 + tst r3, #1 << 14 @ test M bit + addne r2, r2, r2, lsr #1 @ +1/2 size if M == 1 + mov r3, r3, lsr #12 + and r3, r3, #3 + mov r11, #8 + mov r11, r11, lsl r3 @ cache line size in bytes +no_cache_id: + bic r1, pc, #63 @ align to longest cache line + add r2, r1, r2 +1: ldr r3, [r1], r11 @ s/w flush D cache + teq r1, r2 + bne 1b + + mcr p15, 0, r1, c7, c5, 0 @ flush I cache + mcr p15, 0, r1, c7, c6, 0 @ flush D cache + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +__armv3_cache_flush: + mov r1, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 + mov pc, lr + +/* + * Various debugging routines for printing hex characters and + * memory, which again must be relocatable. + */ +#ifdef DEBUG + .type phexbuf,#object +phexbuf: .space 12 + .size phexbuf, . - phexbuf + +phex: adr r3, phexbuf + mov r2, #0 + strb r2, [r3, r1] +1: subs r1, r1, #1 + movmi r0, r3 + bmi puts + and r2, r0, #15 + mov r0, r0, lsr #4 + cmp r2, #10 + addge r2, r2, #7 + add r2, r2, #'0' + strb r2, [r3, r1] + b 1b + +puts: loadsp r3 +1: ldrb r2, [r0], #1 + teq r2, #0 + moveq pc, lr +2: writeb r2 + mov r1, #0x00020000 +3: subs r1, r1, #1 + bne 3b + teq r2, #'\n' + moveq r2, #'\r' + beq 2b + teq r0, #0 + bne 1b + mov pc, lr +putc: + mov r2, r0 + mov r0, #0 + loadsp r3 + b 2b + +memdump: mov r12, r0 + mov r10, lr + mov r11, #0 +2: mov r0, r11, lsl #2 + add r0, r0, r12 + mov r1, #8 + bl phex + mov r0, #':' + bl putc +1: mov r0, #' ' + bl putc + ldr r0, [r12, r11, lsl #2] + mov r1, #8 + bl phex + and r0, r11, #7 + teq r0, #3 + moveq r0, #' ' + bleq putc + and r0, r11, #7 + add r11, r11, #1 + teq r0, #7 + bne 1b + mov r0, #'\n' + bl putc + cmp r11, #64 + blt 2b + mov pc, r10 +#endif + +reloc_end: + + .align + .section ".stack", "w" +user_stack: .space 4096 diff --git a/arch/arm/boot/compressed/ice-dcc.S b/arch/arm/boot/compressed/ice-dcc.S new file mode 100644 index 0000000..104377a --- /dev/null +++ b/arch/arm/boot/compressed/ice-dcc.S @@ -0,0 +1,17 @@ + + + .text + + .global icedcc_putc + +icedcc_putc: + mov r2, #0x4000000 +1: + subs r2, r2, #1 + movlt pc, r14 + mrc p14, 0, r1, c0, c0, 0 + tst r1, #2 + bne 1b + + mcr p14, 0, r0, c1, c0, 0 + mov pc, r14 diff --git a/arch/arm/boot/compressed/ll_char_wr.S b/arch/arm/boot/compressed/ll_char_wr.S new file mode 100644 index 0000000..d7bbd9d --- /dev/null +++ b/arch/arm/boot/compressed/ll_char_wr.S @@ -0,0 +1,134 @@ +/* + * linux/arch/arm/lib/ll_char_wr.S + * + * Copyright (C) 1995, 1996 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. + * + * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King. + * + * 10-04-96 RMK Various cleanups & reduced register usage. + * 08-04-98 RMK Shifts re-ordered + */ + +@ Regs: [] = corruptible +@ {} = used +@ () = do not use + +#include <linux/linkage.h> +#include <asm/assembler.h> + .text + +LC0: .word LC0 + .word bytes_per_char_h + .word video_size_row + .word acorndata_8x8 + .word con_charconvtable + +/* + * r0 = ptr + * r1 = char + * r2 = white + */ +ENTRY(ll_write_char) + stmfd sp!, {r4 - r7, lr} +@ +@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc) +@ + /* + * calculate offset into character table + */ + mov r1, r1, lsl #3 + /* + * calculate offset required for each row. + */ + adr ip, LC0 + ldmia ip, {r3, r4, r5, r6, lr} + sub ip, ip, r3 + add r6, r6, ip + add lr, lr, ip + ldr r4, [r4, ip] + ldr r5, [r5, ip] + /* + * Go to resolution-dependent routine... + */ + cmp r4, #4 + blt Lrow1bpp + add r0, r0, r5, lsl #3 @ Move to bottom of character + orr r1, r1, #7 + ldrb r7, [r6, r1] + teq r4, #8 + beq Lrow8bpplp +@ +@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc) +@ +Lrow4bpplp: + ldr r7, [lr, r7, lsl #2] + mul r7, r2, r7 + sub r1, r1, #1 @ avoid using r7 directly after + str r7, [r0, -r5]! + ldrb r7, [r6, r1] + ldr r7, [lr, r7, lsl #2] + mul r7, r2, r7 + tst r1, #7 @ avoid using r7 directly after + str r7, [r0, -r5]! + subne r1, r1, #1 + ldrneb r7, [r6, r1] + bne Lrow4bpplp + LOADREGS(fd, sp!, {r4 - r7, pc}) + +@ +@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc) +@ +Lrow8bpplp: + mov ip, r7, lsr #4 + ldr ip, [lr, ip, lsl #2] + mul r4, r2, ip + and ip, r7, #15 @ avoid r4 + ldr ip, [lr, ip, lsl #2] @ avoid r4 + mul ip, r2, ip @ avoid r4 + sub r1, r1, #1 @ avoid ip + sub r0, r0, r5 @ avoid ip + stmia r0, {r4, ip} + ldrb r7, [r6, r1] + mov ip, r7, lsr #4 + ldr ip, [lr, ip, lsl #2] + mul r4, r2, ip + and ip, r7, #15 @ avoid r4 + ldr ip, [lr, ip, lsl #2] @ avoid r4 + mul ip, r2, ip @ avoid r4 + tst r1, #7 @ avoid ip + sub r0, r0, r5 @ avoid ip + stmia r0, {r4, ip} + subne r1, r1, #1 + ldrneb r7, [r6, r1] + bne Lrow8bpplp + LOADREGS(fd, sp!, {r4 - r7, pc}) + +@ +@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc) +@ +Lrow1bpp: + add r6, r6, r1 + ldmia r6, {r4, r7} + strb r4, [r0], r5 + mov r4, r4, lsr #8 + strb r4, [r0], r5 + mov r4, r4, lsr #8 + strb r4, [r0], r5 + mov r4, r4, lsr #8 + strb r4, [r0], r5 + strb r7, [r0], r5 + mov r7, r7, lsr #8 + strb r7, [r0], r5 + mov r7, r7, lsr #8 + strb r7, [r0], r5 + mov r7, r7, lsr #8 + strb r7, [r0], r5 + LOADREGS(fd, sp!, {r4 - r7, pc}) + + .bss +ENTRY(con_charconvtable) + .space 1024 diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c new file mode 100644 index 0000000..23434b5 --- /dev/null +++ b/arch/arm/boot/compressed/misc.c @@ -0,0 +1,329 @@ +/* + * misc.c + * + * This is a collection of several routines from gzip-1.0.3 + * adapted for Linux. + * + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 + * + * Modified for ARM Linux by Russell King + * + * Nicolas Pitre <nico@visuaide.com> 1999/04/14 : + * For this code to run directly from Flash, all constant variables must + * be marked with 'const' and all other variables initialized at run-time + * only. This way all non constant variables will end up in the bss segment, + * which should point to addresses in RAM and cleared to 0 on start. + * This allows for a much quicker boot time. + */ + +unsigned int __machine_arch_type; + +#include <linux/string.h> + +#include <asm/arch/uncompress.h> + +#ifdef STANDALONE_DEBUG +#define putstr printf +#endif + +#ifdef CONFIG_DEBUG_ICEDCC +#define putstr icedcc_putstr +#define putc icedcc_putc + +extern void idedcc_putc(int ch); + +static void +icedcc_putstr(const char *ptr) +{ + for (; *ptr != '\0'; ptr++) { + icedcc_putc(*ptr); + } +} + +#endif + +#define __ptr_t void * + +/* + * Optimised C version of memzero for the ARM. + */ +void __memzero (__ptr_t s, size_t n) +{ + union { void *vp; unsigned long *ulp; unsigned char *ucp; } u; + int i; + + u.vp = s; + + for (i = n >> 5; i > 0; i--) { + *u.ulp++ = 0; + *u.ulp++ = 0; + *u.ulp++ = 0; + *u.ulp++ = 0; + *u.ulp++ = 0; + *u.ulp++ = 0; + *u.ulp++ = 0; + *u.ulp++ = 0; + } + + if (n & 1 << 4) { + *u.ulp++ = 0; + *u.ulp++ = 0; + *u.ulp++ = 0; + *u.ulp++ = 0; + } + + if (n & 1 << 3) { + *u.ulp++ = 0; + *u.ulp++ = 0; + } + + if (n & 1 << 2) + *u.ulp++ = 0; + + if (n & 1 << 1) { + *u.ucp++ = 0; + *u.ucp++ = 0; + } + + if (n & 1) + *u.ucp++ = 0; +} + +static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src, + size_t __n) +{ + int i = 0; + unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; + + for (i = __n >> 3; i > 0; i--) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } + + if (__n & 1 << 2) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } + + if (__n & 1 << 1) { + *d++ = *s++; + *d++ = *s++; + } + + if (__n & 1) + *d++ = *s++; + + return __dest; +} + +/* + * gzip delarations + */ +#define OF(args) args +#define STATIC static + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ + +static uch *inbuf; /* input buffer */ +static uch window[WSIZE]; /* Sliding window buffer */ + +static unsigned insize; /* valid bytes in inbuf */ +static unsigned inptr; /* index of next byte to be processed in inbuf */ +static unsigned outcnt; /* bytes in output buffer */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions */ +#ifdef DEBUG +# define Assert(cond,msg) {if(!(cond)) error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +extern char input_data[]; +extern char input_data_end[]; + +static uch *output_data; +static ulg output_ptr; +static ulg bytes_out; + +static void *malloc(int size); +static void free(void *where); +static void error(char *m); +static void gzip_mark(void **); +static void gzip_release(void **); + +static void putstr(const char *); + +extern int end; +static ulg free_mem_ptr; +static ulg free_mem_ptr_end; + +#define HEAP_SIZE 0x2000 + +#include "../../../../lib/inflate.c" + +#ifndef STANDALONE_DEBUG +static void *malloc(int size) +{ + void *p; + + if (size <0) error("Malloc error"); + if (free_mem_ptr <= 0) error("Memory error"); + + free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ + + p = (void *)free_mem_ptr; + free_mem_ptr += size; + + if (free_mem_ptr >= free_mem_ptr_end) + error("Out of memory"); + return p; +} + +static void free(void *where) +{ /* gzip_mark & gzip_release do the free */ +} + +static void gzip_mark(void **ptr) +{ + arch_decomp_wdog(); + *ptr = (void *) free_mem_ptr; +} + +static void gzip_release(void **ptr) +{ + arch_decomp_wdog(); + free_mem_ptr = (long) *ptr; +} +#else +static void gzip_mark(void **ptr) +{ +} + +static void gzip_release(void **ptr) +{ +} +#endif + +/* =========================================================================== + * Fill the input buffer. This is called only when the buffer is empty + * and at least one byte is really needed. + */ +int fill_inbuf(void) +{ + if (insize != 0) + error("ran out of input data"); + + inbuf = input_data; + insize = &input_data_end[0] - &input_data[0]; + + inptr = 1; + return inbuf[0]; +} + +/* =========================================================================== + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ +void flush_window(void) +{ + ulg c = crc; + unsigned n; + uch *in, *out, ch; + + in = window; + out = &output_data[output_ptr]; + for (n = 0; n < outcnt; n++) { + ch = *out++ = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + outcnt = 0; + putstr("."); +} + +static void error(char *x) +{ + putstr("\n\n"); + putstr(x); + putstr("\n\n -- System halted"); + + while(1); /* Halt */ +} + +#ifndef STANDALONE_DEBUG + +ulg +decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, + int arch_id) +{ + output_data = (uch *)output_start; /* Points to kernel start */ + free_mem_ptr = free_mem_ptr_p; + free_mem_ptr_end = free_mem_ptr_end_p; + __machine_arch_type = arch_id; + + arch_decomp_setup(); + + makecrc(); + putstr("Uncompressing Linux..."); + gunzip(); + putstr(" done, booting the kernel.\n"); + return output_ptr; +} +#else + +char output_buffer[1500*1024]; + +int main() +{ + output_data = output_buffer; + + makecrc(); + putstr("Uncompressing Linux..."); + gunzip(); + putstr("done.\n"); + return 0; +} +#endif + diff --git a/arch/arm/boot/compressed/ofw-shark.c b/arch/arm/boot/compressed/ofw-shark.c new file mode 100644 index 0000000..7f6f5db --- /dev/null +++ b/arch/arm/boot/compressed/ofw-shark.c @@ -0,0 +1,260 @@ +/* + * linux/arch/arm/boot/compressed/ofw-shark.c + * + * by Alexander Schulz + * + * This file is used to get some basic information + * about the memory layout of the shark we are running + * on. Memory is usually divided in blocks a 8 MB. + * And bootargs are copied from OpenFirmware. + */ + + +#include <linux/kernel.h> +#include <linux/types.h> +#include <asm/setup.h> +#include <asm/page.h> + + +asmlinkage void +create_params (unsigned long *buffer) +{ + /* Is there a better address? Also change in mach-shark/core.c */ + struct tag *tag = (struct tag *) 0x08003000; + int j,i,m,k,nr_banks,size; + unsigned char *c; + + k = 0; + + /* Head of the taglist */ + tag->hdr.tag = ATAG_CORE; + tag->hdr.size = tag_size(tag_core); + tag->u.core.flags = 1; + tag->u.core.pagesize = PAGE_SIZE; + tag->u.core.rootdev = 0; + + /* Build up one tagged block for each memory region */ + size=0; + nr_banks=(unsigned int) buffer[0]; + for (j=0;j<nr_banks;j++){ + /* search the lowest address and put it into the next entry */ + /* not a fast sort algorithm, but there are at most 8 entries */ + /* and this is used only once anyway */ + m=0xffffffff; + for (i=0;i<(unsigned int) buffer[0];i++){ + if (buffer[2*i+1]<m) { + m=buffer[2*i+1]; + k=i; + } + } + + tag = tag_next(tag); + tag->hdr.tag = ATAG_MEM; + tag->hdr.size = tag_size(tag_mem32); + tag->u.mem.size = buffer[2*k+2]; + tag->u.mem.start = buffer[2*k+1]; + + size += buffer[2*k+2]; + + buffer[2*k+1]=0xffffffff; /* mark as copied */ + } + + /* The command line */ + tag = tag_next(tag); + tag->hdr.tag = ATAG_CMDLINE; + + c=(unsigned char *)(&buffer[34]); + j=0; + while (*c) tag->u.cmdline.cmdline[j++]=*c++; + + tag->u.cmdline.cmdline[j]=0; + tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2; + + /* Hardware revision */ + tag = tag_next(tag); + tag->hdr.tag = ATAG_REVISION; + tag->hdr.size = tag_size(tag_revision); + tag->u.revision.rev = ((unsigned char) buffer[33])-'0'; + + /* End of the taglist */ + tag = tag_next(tag); + tag->hdr.tag = 0; + tag->hdr.size = 0; +} + + +typedef int (*ofw_handle_t)(void *); + +/* Everything below is called with a wrong MMU setting. + * This means: no string constants, no initialization of + * arrays, no global variables! This is ugly but I didn't + * want to write this in assembler :-) + */ + +int +of_decode_int(const unsigned char *p) +{ + unsigned int i = *p++ << 8; + i = (i + *p++) << 8; + i = (i + *p++) << 8; + return (i + *p); +} + +int +OF_finddevice(ofw_handle_t openfirmware, char *name) +{ + unsigned int args[8]; + char service[12]; + + service[0]='f'; + service[1]='i'; + service[2]='n'; + service[3]='d'; + service[4]='d'; + service[5]='e'; + service[6]='v'; + service[7]='i'; + service[8]='c'; + service[9]='e'; + service[10]='\0'; + + args[0]=(unsigned int)service; + args[1]=1; + args[2]=1; + args[3]=(unsigned int)name; + + if (openfirmware(args) == -1) + return -1; + return args[4]; +} + +int +OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop) +{ + unsigned int args[8]; + char service[12]; + + service[0]='g'; + service[1]='e'; + service[2]='t'; + service[3]='p'; + service[4]='r'; + service[5]='o'; + service[6]='p'; + service[7]='l'; + service[8]='e'; + service[9]='n'; + service[10]='\0'; + + args[0] = (unsigned int)service; + args[1] = 2; + args[2] = 1; + args[3] = (unsigned int)handle; + args[4] = (unsigned int)prop; + + if (openfirmware(args) == -1) + return -1; + return args[5]; +} + +int +OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen) +{ + unsigned int args[8]; + char service[8]; + + service[0]='g'; + service[1]='e'; + service[2]='t'; + service[3]='p'; + service[4]='r'; + service[5]='o'; + service[6]='p'; + service[7]='\0'; + + args[0] = (unsigned int)service; + args[1] = 4; + args[2] = 1; + args[3] = (unsigned int)handle; + args[4] = (unsigned int)prop; + args[5] = (unsigned int)buf; + args[6] = buflen; + + if (openfirmware(args) == -1) + return -1; + return args[7]; +} + +asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer) +{ + int phandle,i,mem_len,buffer[32]; + char temp[15]; + + temp[0]='/'; + temp[1]='m'; + temp[2]='e'; + temp[3]='m'; + temp[4]='o'; + temp[5]='r'; + temp[6]='y'; + temp[7]='\0'; + + phandle=OF_finddevice(o,temp); + + temp[0]='r'; + temp[1]='e'; + temp[2]='g'; + temp[3]='\0'; + + mem_len = OF_getproplen(o,phandle, temp); + OF_getprop(o,phandle, temp, buffer, mem_len); + *nomr=mem_len >> 3; + + for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]); + + temp[0]='/'; + temp[1]='c'; + temp[2]='h'; + temp[3]='o'; + temp[4]='s'; + temp[5]='e'; + temp[6]='n'; + temp[7]='\0'; + + phandle=OF_finddevice(o,temp); + + temp[0]='b'; + temp[1]='o'; + temp[2]='o'; + temp[3]='t'; + temp[4]='a'; + temp[5]='r'; + temp[6]='g'; + temp[7]='s'; + temp[8]='\0'; + + mem_len = OF_getproplen(o,phandle, temp); + OF_getprop(o,phandle, temp, buffer, mem_len); + if (mem_len > 128) mem_len=128; + for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i]; + pointer[i+33]=0; + + temp[0]='/'; + temp[1]='\0'; + phandle=OF_finddevice(o,temp); + temp[0]='b'; + temp[1]='a'; + temp[2]='n'; + temp[3]='n'; + temp[4]='e'; + temp[5]='r'; + temp[6]='-'; + temp[7]='n'; + temp[8]='a'; + temp[9]='m'; + temp[10]='e'; + temp[11]='\0'; + mem_len = OF_getproplen(o,phandle, temp); + OF_getprop(o,phandle, temp, buffer, mem_len); + (unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2]; +} diff --git a/arch/arm/boot/compressed/piggy.S b/arch/arm/boot/compressed/piggy.S new file mode 100644 index 0000000..54c9518 --- /dev/null +++ b/arch/arm/boot/compressed/piggy.S @@ -0,0 +1,6 @@ + .section .piggydata,#alloc + .globl input_data +input_data: + .incbin "arch/arm/boot/compressed/piggy.gz" + .globl input_data_end +input_data_end: diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in new file mode 100644 index 0000000..eed6161 --- /dev/null +++ b/arch/arm/boot/compressed/vmlinux.lds.in @@ -0,0 +1,55 @@ +/* + * linux/arch/arm/boot/compressed/vmlinux.lds.in + * + * Copyright (C) 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. + */ +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = TEXT_START; + _text = .; + + .text : { + _start = .; + *(.start) + *(.text) + *(.fixup) + *(.gnu.warning) + *(.rodata) + *(.rodata.*) + *(.glue_7) + *(.glue_7t) + *(.piggydata) + . = ALIGN(4); + } + + _etext = .; + + _got_start = .; + .got : { *(.got) } + _got_end = .; + .got.plt : { *(.got.plt) } + .data : { *(.data) } + _edata = .; + + . = BSS_START; + __bss_start = .; + .bss : { *(.bss) } + _end = .; + + .stack (NOLOAD) : { *(.stack) } + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} + diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh new file mode 100644 index 0000000..935bb27 --- /dev/null +++ b/arch/arm/boot/install.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# +# arch/arm/boot/install.sh +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1995 by Linus Torvalds +# +# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin +# Adapted from code in arch/i386/boot/install.sh by Russell King +# +# "make install" script for arm architecture +# +# Arguments: +# $1 - kernel version +# $2 - kernel image file +# $3 - kernel map file +# $4 - default install path (blank if root directory) +# + +# User may have a custom install script +if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi +if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi + +if [ "$(basename $2)" = "zImage" ]; then +# Compressed install + echo "Installing compressed kernel" + base=vmlinuz +else +# Normal install + echo "Installing normal kernel" + base=vmlinux +fi + +if [ -f $4/$base-$1 ]; then + mv $4/$base-$1 $4/$base-$1.old +fi +cat $2 > $4/$base-$1 + +# Install system map file +if [ -f $4/System.map-$1 ]; then + mv $4/System.map-$1 $4/System.map-$1.old +fi +cp $3 $4/System.map-$1 + +if [ -x /sbin/loadmap ]; then + /sbin/loadmap +else + echo "You have to install it yourself" +fi diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig new file mode 100644 index 0000000..692af6b --- /dev/null +++ b/arch/arm/common/Kconfig @@ -0,0 +1,24 @@ +config ICST525 + bool + +config ICST307 + bool + +config SA1111 + bool + select DMABOUNCE + +config DMABOUNCE + bool + +config TIMER_ACORN + bool + +config SHARP_LOCOMO + bool + +config SHARP_PARAM + bool + +config SHARP_SCOOP + bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile new file mode 100644 index 0000000..11f20a4 --- /dev/null +++ b/arch/arm/common/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for the linux kernel. +# + +obj-y += rtctime.o +obj-$(CONFIG_ARM_AMBA) += amba.o +obj-$(CONFIG_ICST525) += icst525.o +obj-$(CONFIG_ICST307) += icst307.o +obj-$(CONFIG_SA1111) += sa1111.o +obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o +obj-$(CONFIG_DMABOUNCE) += dmabounce.o +obj-$(CONFIG_TIMER_ACORN) += time-acorn.o +obj-$(CONFIG_SHARP_LOCOMO) += locomo.o +obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o +obj-$(CONFIG_SHARP_SCOOP) += scoop.o diff --git a/arch/arm/common/amba.c b/arch/arm/common/amba.c new file mode 100644 index 0000000..a0507f8 --- /dev/null +++ b/arch/arm/common/amba.c @@ -0,0 +1,357 @@ +/* + * linux/arch/arm/common/amba.c + * + * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved. + * + * 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/module.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/hardware/amba.h> +#include <asm/sizes.h> + +#define to_amba_device(d) container_of(d, struct amba_device, dev) +#define to_amba_driver(d) container_of(d, struct amba_driver, drv) + +static struct amba_id * +amba_lookup(struct amba_id *table, struct amba_device *dev) +{ + int ret = 0; + + while (table->mask) { + ret = (dev->periphid & table->mask) == table->id; + if (ret) + break; + table++; + } + + return ret ? table : NULL; +} + +static int amba_match(struct device *dev, struct device_driver *drv) +{ + struct amba_device *pcdev = to_amba_device(dev); + struct amba_driver *pcdrv = to_amba_driver(drv); + + return amba_lookup(pcdrv->id_table, pcdev) != NULL; +} + +#ifdef CONFIG_HOTPLUG +static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz) +{ + struct amba_device *pcdev = to_amba_device(dev); + + if (nr_env < 2) + return -ENOMEM; + + snprintf(buf, bufsz, "AMBA_ID=%08x", pcdev->periphid); + *envp++ = buf; + *envp++ = NULL; + return 0; +} +#else +#define amba_hotplug NULL +#endif + +static int amba_suspend(struct device *dev, pm_message_t state) +{ + struct amba_driver *drv = to_amba_driver(dev->driver); + int ret = 0; + + if (dev->driver && drv->suspend) + ret = drv->suspend(to_amba_device(dev), state); + return ret; +} + +static int amba_resume(struct device *dev) +{ + struct amba_driver *drv = to_amba_driver(dev->driver); + int ret = 0; + + if (dev->driver && drv->resume) + ret = drv->resume(to_amba_device(dev)); + return ret; +} + +/* + * Primecells are part of the Advanced Microcontroller Bus Architecture, + * so we call the bus "amba". + */ +static struct bus_type amba_bustype = { + .name = "amba", + .match = amba_match, + .hotplug = amba_hotplug, + .suspend = amba_suspend, + .resume = amba_resume, +}; + +static int __init amba_init(void) +{ + return bus_register(&amba_bustype); +} + +postcore_initcall(amba_init); + +/* + * These are the device model conversion veneers; they convert the + * device model structures to our more specific structures. + */ +static int amba_probe(struct device *dev) +{ + struct amba_device *pcdev = to_amba_device(dev); + struct amba_driver *pcdrv = to_amba_driver(dev->driver); + struct amba_id *id; + + id = amba_lookup(pcdrv->id_table, pcdev); + + return pcdrv->probe(pcdev, id); +} + +static int amba_remove(struct device *dev) +{ + struct amba_driver *drv = to_amba_driver(dev->driver); + return drv->remove(to_amba_device(dev)); +} + +static void amba_shutdown(struct device *dev) +{ + struct amba_driver *drv = to_amba_driver(dev->driver); + drv->shutdown(to_amba_device(dev)); +} + +/** + * amba_driver_register - register an AMBA device driver + * @drv: amba device driver structure + * + * Register an AMBA device driver with the Linux device model + * core. If devices pre-exist, the drivers probe function will + * be called. + */ +int amba_driver_register(struct amba_driver *drv) +{ + drv->drv.bus = &amba_bustype; + +#define SETFN(fn) if (drv->fn) drv->drv.fn = amba_##fn + SETFN(probe); + SETFN(remove); + SETFN(shutdown); + + return driver_register(&drv->drv); +} + +/** + * amba_driver_unregister - remove an AMBA device driver + * @drv: AMBA device driver structure to remove + * + * Unregister an AMBA device driver from the Linux device + * model. The device model will call the drivers remove function + * for each device the device driver is currently handling. + */ +void amba_driver_unregister(struct amba_driver *drv) +{ + driver_unregister(&drv->drv); +} + + +static void amba_device_release(struct device *dev) +{ + struct amba_device *d = to_amba_device(dev); + + if (d->res.parent) + release_resource(&d->res); + kfree(d); +} + +#define amba_attr(name,fmt,arg...) \ +static ssize_t show_##name(struct device *_dev, char *buf) \ +{ \ + struct amba_device *dev = to_amba_device(_dev); \ + return sprintf(buf, fmt, arg); \ +} \ +static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) + +amba_attr(id, "%08x\n", dev->periphid); +amba_attr(irq0, "%u\n", dev->irq[0]); +amba_attr(irq1, "%u\n", dev->irq[1]); +amba_attr(resource, "\t%08lx\t%08lx\t%08lx\n", + dev->res.start, dev->res.end, dev->res.flags); + +/** + * amba_device_register - register an AMBA device + * @dev: AMBA device to register + * @parent: parent memory resource + * + * Setup the AMBA device, reading the cell ID if present. + * Claim the resource, and register the AMBA device with + * the Linux device manager. + */ +int amba_device_register(struct amba_device *dev, struct resource *parent) +{ + u32 pid, cid; + void __iomem *tmp; + int i, ret; + + dev->dev.release = amba_device_release; + dev->dev.bus = &amba_bustype; + dev->dev.dma_mask = &dev->dma_mask; + dev->res.name = dev->dev.bus_id; + + if (!dev->dev.coherent_dma_mask && dev->dma_mask) + dev_warn(&dev->dev, "coherent dma mask is unset\n"); + + ret = request_resource(parent, &dev->res); + if (ret == 0) { + tmp = ioremap(dev->res.start, SZ_4K); + if (!tmp) { + ret = -ENOMEM; + goto out; + } + + for (pid = 0, i = 0; i < 4; i++) + pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8); + for (cid = 0, i = 0; i < 4; i++) + cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8); + + iounmap(tmp); + + if (cid == 0xb105f00d) + dev->periphid = pid; + + if (dev->periphid) + ret = device_register(&dev->dev); + else + ret = -ENODEV; + + if (ret == 0) { + device_create_file(&dev->dev, &dev_attr_id); + if (dev->irq[0] != NO_IRQ) + device_create_file(&dev->dev, &dev_attr_irq0); + if (dev->irq[1] != NO_IRQ) + device_create_file(&dev->dev, &dev_attr_irq1); + device_create_file(&dev->dev, &dev_attr_resource); + } else { + out: + release_resource(&dev->res); + } + } + return ret; +} + +/** + * amba_device_unregister - unregister an AMBA device + * @dev: AMBA device to remove + * + * Remove the specified AMBA device from the Linux device + * manager. All files associated with this object will be + * destroyed, and device drivers notified that the device has + * been removed. The AMBA device's resources including + * the amba_device structure will be freed once all + * references to it have been dropped. + */ +void amba_device_unregister(struct amba_device *dev) +{ + device_unregister(&dev->dev); +} + + +struct find_data { + struct amba_device *dev; + struct device *parent; + const char *busid; + unsigned int id; + unsigned int mask; +}; + +static int amba_find_match(struct device *dev, void *data) +{ + struct find_data *d = data; + struct amba_device *pcdev = to_amba_device(dev); + int r; + + r = (pcdev->periphid & d->mask) == d->id; + if (d->parent) + r &= d->parent == dev->parent; + if (d->busid) + r &= strcmp(dev->bus_id, d->busid) == 0; + + if (r) { + get_device(dev); + d->dev = pcdev; + } + + return r; +} + +/** + * amba_find_device - locate an AMBA device given a bus id + * @busid: bus id for device (or NULL) + * @parent: parent device (or NULL) + * @id: peripheral ID (or 0) + * @mask: peripheral ID mask (or 0) + * + * Return the AMBA device corresponding to the supplied parameters. + * If no device matches, returns NULL. + * + * NOTE: When a valid device is found, its refcount is + * incremented, and must be decremented before the returned + * reference. + */ +struct amba_device * +amba_find_device(const char *busid, struct device *parent, unsigned int id, + unsigned int mask) +{ + struct find_data data; + + data.dev = NULL; + data.parent = parent; + data.busid = busid; + data.id = id; + data.mask = mask; + + bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match); + + return data.dev; +} + +/** + * amba_request_regions - request all mem regions associated with device + * @dev: amba_device structure for device + * @name: name, or NULL to use driver name + */ +int amba_request_regions(struct amba_device *dev, const char *name) +{ + int ret = 0; + + if (!name) + name = dev->dev.driver->name; + + if (!request_mem_region(dev->res.start, SZ_4K, name)) + ret = -EBUSY; + + return ret; +} + +/** + * amba_release_regions - release mem regions assoicated with device + * @dev: amba_device structure for device + * + * Release regions claimed by a successful call to amba_request_regions. + */ +void amba_release_regions(struct amba_device *dev) +{ + release_mem_region(dev->res.start, SZ_4K); +} + +EXPORT_SYMBOL(amba_driver_register); +EXPORT_SYMBOL(amba_driver_unregister); +EXPORT_SYMBOL(amba_device_register); +EXPORT_SYMBOL(amba_device_unregister); +EXPORT_SYMBOL(amba_find_device); +EXPORT_SYMBOL(amba_request_regions); +EXPORT_SYMBOL(amba_release_regions); diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c new file mode 100644 index 0000000..5797b1b --- /dev/null +++ b/arch/arm/common/dmabounce.c @@ -0,0 +1,682 @@ +/* + * arch/arm/common/dmabounce.c + * + * Special dma_{map/unmap/dma_sync}_* routines for systems that have + * limited DMA windows. These functions utilize bounce buffers to + * copy data to/from buffers located outside the DMA region. This + * only works for systems in which DMA memory is at the bottom of + * RAM and the remainder of memory is at the top an the DMA memory + * can be marked as ZONE_DMA. Anything beyond that such as discontigous + * DMA windows will require custom implementations that reserve memory + * areas at early bootup. + * + * Original version by Brad Parker (brad@heeltoe.com) + * Re-written by Christopher Hoover <ch@murgatroid.com> + * Made generic by Deepak Saxena <dsaxena@plexity.net> + * + * Copyright (C) 2002 Hewlett Packard Company. + * Copyright (C) 2004 MontaVista Software, Inc. + * + * 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/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/dmapool.h> +#include <linux/list.h> + +#undef DEBUG + +#undef STATS +#ifdef STATS +#define DO_STATS(X) do { X ; } while (0) +#else +#define DO_STATS(X) do { } while (0) +#endif + +/* ************************************************** */ + +struct safe_buffer { + struct list_head node; + + /* original request */ + void *ptr; + size_t size; + int direction; + + /* safe buffer info */ + struct dma_pool *pool; + void *safe; + dma_addr_t safe_dma_addr; +}; + +struct dmabounce_device_info { + struct list_head node; + + struct device *dev; + struct dma_pool *small_buffer_pool; + struct dma_pool *large_buffer_pool; + struct list_head safe_buffers; + unsigned long small_buffer_size, large_buffer_size; +#ifdef STATS + unsigned long sbp_allocs; + unsigned long lbp_allocs; + unsigned long total_allocs; + unsigned long map_op_count; + unsigned long bounce_count; +#endif +}; + +static LIST_HEAD(dmabounce_devs); + +#ifdef STATS +static void print_alloc_stats(struct dmabounce_device_info *device_info) +{ + printk(KERN_INFO + "%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n", + device_info->dev->bus_id, + device_info->sbp_allocs, device_info->lbp_allocs, + device_info->total_allocs - device_info->sbp_allocs - + device_info->lbp_allocs, + device_info->total_allocs); +} +#endif + +/* find the given device in the dmabounce device list */ +static inline struct dmabounce_device_info * +find_dmabounce_dev(struct device *dev) +{ + struct list_head *entry; + + list_for_each(entry, &dmabounce_devs) { + struct dmabounce_device_info *d = + list_entry(entry, struct dmabounce_device_info, node); + + if (d->dev == dev) + return d; + } + return NULL; +} + + +/* allocate a 'safe' buffer and keep track of it */ +static inline struct safe_buffer * +alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr, + size_t size, enum dma_data_direction dir) +{ + struct safe_buffer *buf; + struct dma_pool *pool; + struct device *dev = device_info->dev; + void *safe; + dma_addr_t safe_dma_addr; + + dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n", + __func__, ptr, size, dir); + + DO_STATS ( device_info->total_allocs++ ); + + buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC); + if (buf == NULL) { + dev_warn(dev, "%s: kmalloc failed\n", __func__); + return NULL; + } + + if (size <= device_info->small_buffer_size) { + pool = device_info->small_buffer_pool; + safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); + + DO_STATS ( device_info->sbp_allocs++ ); + } else if (size <= device_info->large_buffer_size) { + pool = device_info->large_buffer_pool; + safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); + + DO_STATS ( device_info->lbp_allocs++ ); + } else { + pool = NULL; + safe = dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC); + } + + if (safe == NULL) { + dev_warn(device_info->dev, + "%s: could not alloc dma memory (size=%d)\n", + __func__, size); + kfree(buf); + return NULL; + } + +#ifdef STATS + if (device_info->total_allocs % 1000 == 0) + print_alloc_stats(device_info); +#endif + + buf->ptr = ptr; + buf->size = size; + buf->direction = dir; + buf->pool = pool; + buf->safe = safe; + buf->safe_dma_addr = safe_dma_addr; + + list_add(&buf->node, &device_info->safe_buffers); + + return buf; +} + +/* determine if a buffer is from our "safe" pool */ +static inline struct safe_buffer * +find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr) +{ + struct list_head *entry; + + list_for_each(entry, &device_info->safe_buffers) { + struct safe_buffer *b = + list_entry(entry, struct safe_buffer, node); + + if (b->safe_dma_addr == safe_dma_addr) + return b; + } + + return NULL; +} + +static inline void +free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *buf) +{ + dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf); + + list_del(&buf->node); + + if (buf->pool) + dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr); + else + dma_free_coherent(device_info->dev, buf->size, buf->safe, + buf->safe_dma_addr); + + kfree(buf); +} + +/* ************************************************** */ + +#ifdef STATS + +static void print_map_stats(struct dmabounce_device_info *device_info) +{ + printk(KERN_INFO + "%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n", + device_info->dev->bus_id, + device_info->map_op_count, device_info->bounce_count); +} +#endif + +static inline dma_addr_t +map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction dir) +{ + struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); + dma_addr_t dma_addr; + int needs_bounce = 0; + + if (device_info) + DO_STATS ( device_info->map_op_count++ ); + + dma_addr = virt_to_dma(dev, ptr); + + if (dev->dma_mask) { + unsigned long mask = *dev->dma_mask; + unsigned long limit; + + limit = (mask + 1) & ~mask; + if (limit && size > limit) { + dev_err(dev, "DMA mapping too big (requested %#x " + "mask %#Lx)\n", size, *dev->dma_mask); + return ~0; + } + + /* + * Figure out if we need to bounce from the DMA mask. + */ + needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask; + } + + if (device_info && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) { + struct safe_buffer *buf; + + buf = alloc_safe_buffer(device_info, ptr, size, dir); + if (buf == 0) { + dev_err(dev, "%s: unable to map unsafe buffer %p!\n", + __func__, ptr); + return 0; + } + + dev_dbg(dev, + "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + if ((dir == DMA_TO_DEVICE) || + (dir == DMA_BIDIRECTIONAL)) { + dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n", + __func__, ptr, buf->safe, size); + memcpy(buf->safe, ptr, size); + } + consistent_sync(buf->safe, size, dir); + + dma_addr = buf->safe_dma_addr; + } else { + consistent_sync(ptr, size, dir); + } + + return dma_addr; +} + +static inline void +unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction dir) +{ + struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); + struct safe_buffer *buf = NULL; + + /* + * Trying to unmap an invalid mapping + */ + if (dma_addr == ~0) { + dev_err(dev, "Trying to unmap invalid mapping\n"); + return; + } + + if (device_info) + buf = find_safe_buffer(device_info, dma_addr); + + if (buf) { + BUG_ON(buf->size != size); + + dev_dbg(dev, + "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + + DO_STATS ( device_info->bounce_count++ ); + + if ((dir == DMA_FROM_DEVICE) || + (dir == DMA_BIDIRECTIONAL)) { + dev_dbg(dev, + "%s: copy back safe %p to unsafe %p size %d\n", + __func__, buf->safe, buf->ptr, size); + memcpy(buf->ptr, buf->safe, size); + } + free_safe_buffer(device_info, buf); + } +} + +static inline void +sync_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction dir) +{ + struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); + struct safe_buffer *buf = NULL; + + if (device_info) + buf = find_safe_buffer(device_info, dma_addr); + + if (buf) { + /* + * Both of these checks from original code need to be + * commented out b/c some drivers rely on the following: + * + * 1) Drivers may map a large chunk of memory into DMA space + * but only sync a small portion of it. Good example is + * allocating a large buffer, mapping it, and then + * breaking it up into small descriptors. No point + * in syncing the whole buffer if you only have to + * touch one descriptor. + * + * 2) Buffers that are mapped as DMA_BIDIRECTIONAL are + * usually only synced in one dir at a time. + * + * See drivers/net/eepro100.c for examples of both cases. + * + * -ds + * + * BUG_ON(buf->size != size); + * BUG_ON(buf->direction != dir); + */ + + dev_dbg(dev, + "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + DO_STATS ( device_info->bounce_count++ ); + + switch (dir) { + case DMA_FROM_DEVICE: + dev_dbg(dev, + "%s: copy back safe %p to unsafe %p size %d\n", + __func__, buf->safe, buf->ptr, size); + memcpy(buf->ptr, buf->safe, size); + break; + case DMA_TO_DEVICE: + dev_dbg(dev, + "%s: copy out unsafe %p to safe %p, size %d\n", + __func__,buf->ptr, buf->safe, size); + memcpy(buf->safe, buf->ptr, size); + break; + case DMA_BIDIRECTIONAL: + BUG(); /* is this allowed? what does it mean? */ + default: + BUG(); + } + consistent_sync(buf->safe, size, dir); + } else { + consistent_sync(dma_to_virt(dev, dma_addr), size, dir); + } +} + +/* ************************************************** */ + +/* + * see if a buffer address is in an 'unsafe' range. if it is + * allocate a 'safe' buffer and copy the unsafe buffer into it. + * substitute the safe buffer for the unsafe one. + * (basically move the buffer from an unsafe area to a safe one) + */ +dma_addr_t +dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction dir) +{ + unsigned long flags; + dma_addr_t dma_addr; + + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", + __func__, ptr, size, dir); + + BUG_ON(dir == DMA_NONE); + + local_irq_save(flags); + + dma_addr = map_single(dev, ptr, size, dir); + + local_irq_restore(flags); + + return dma_addr; +} + +/* + * see if a mapped address was really a "safe" buffer and if so, copy + * the data from the safe buffer back to the unsafe buffer and free up + * the safe buffer. (basically return things back to the way they + * should be) + */ + +void +dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction dir) +{ + unsigned long flags; + + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", + __func__, (void *) dma_addr, size, dir); + + BUG_ON(dir == DMA_NONE); + + local_irq_save(flags); + + unmap_single(dev, dma_addr, size, dir); + + local_irq_restore(flags); +} + +int +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + unsigned long flags; + int i; + + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", + __func__, sg, nents, dir); + + BUG_ON(dir == DMA_NONE); + + local_irq_save(flags); + + for (i = 0; i < nents; i++, sg++) { + struct page *page = sg->page; + unsigned int offset = sg->offset; + unsigned int length = sg->length; + void *ptr = page_address(page) + offset; + + sg->dma_address = + map_single(dev, ptr, length, dir); + } + + local_irq_restore(flags); + + return nents; +} + +void +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + unsigned long flags; + int i; + + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", + __func__, sg, nents, dir); + + BUG_ON(dir == DMA_NONE); + + local_irq_save(flags); + + for (i = 0; i < nents; i++, sg++) { + dma_addr_t dma_addr = sg->dma_address; + unsigned int length = sg->length; + + unmap_single(dev, dma_addr, length, dir); + } + + local_irq_restore(flags); +} + +void +dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction dir) +{ + unsigned long flags; + + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", + __func__, (void *) dma_addr, size, dir); + + local_irq_save(flags); + + sync_single(dev, dma_addr, size, dir); + + local_irq_restore(flags); +} + +void +dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction dir) +{ + unsigned long flags; + + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", + __func__, (void *) dma_addr, size, dir); + + local_irq_save(flags); + + sync_single(dev, dma_addr, size, dir); + + local_irq_restore(flags); +} + +void +dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + unsigned long flags; + int i; + + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", + __func__, sg, nents, dir); + + BUG_ON(dir == DMA_NONE); + + local_irq_save(flags); + + for (i = 0; i < nents; i++, sg++) { + dma_addr_t dma_addr = sg->dma_address; + unsigned int length = sg->length; + + sync_single(dev, dma_addr, length, dir); + } + + local_irq_restore(flags); +} + +void +dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + unsigned long flags; + int i; + + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", + __func__, sg, nents, dir); + + BUG_ON(dir == DMA_NONE); + + local_irq_save(flags); + + for (i = 0; i < nents; i++, sg++) { + dma_addr_t dma_addr = sg->dma_address; + unsigned int length = sg->length; + + sync_single(dev, dma_addr, length, dir); + } + + local_irq_restore(flags); +} + +int +dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, + unsigned long large_buffer_size) +{ + struct dmabounce_device_info *device_info; + + device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC); + if (!device_info) { + printk(KERN_ERR + "Could not allocated dmabounce_device_info for %s", + dev->bus_id); + return -ENOMEM; + } + + device_info->small_buffer_pool = + dma_pool_create("small_dmabounce_pool", + dev, + small_buffer_size, + 0 /* byte alignment */, + 0 /* no page-crossing issues */); + if (!device_info->small_buffer_pool) { + printk(KERN_ERR + "dmabounce: could not allocate small DMA pool for %s\n", + dev->bus_id); + kfree(device_info); + return -ENOMEM; + } + + if (large_buffer_size) { + device_info->large_buffer_pool = + dma_pool_create("large_dmabounce_pool", + dev, + large_buffer_size, + 0 /* byte alignment */, + 0 /* no page-crossing issues */); + if (!device_info->large_buffer_pool) { + printk(KERN_ERR + "dmabounce: could not allocate large DMA pool for %s\n", + dev->bus_id); + dma_pool_destroy(device_info->small_buffer_pool); + + return -ENOMEM; + } + } + + device_info->dev = dev; + device_info->small_buffer_size = small_buffer_size; + device_info->large_buffer_size = large_buffer_size; + INIT_LIST_HEAD(&device_info->safe_buffers); + +#ifdef STATS + device_info->sbp_allocs = 0; + device_info->lbp_allocs = 0; + device_info->total_allocs = 0; + device_info->map_op_count = 0; + device_info->bounce_count = 0; +#endif + + list_add(&device_info->node, &dmabounce_devs); + + printk(KERN_INFO "dmabounce: registered device %s on %s bus\n", + dev->bus_id, dev->bus->name); + + return 0; +} + +void +dmabounce_unregister_dev(struct device *dev) +{ + struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); + + if (!device_info) { + printk(KERN_WARNING + "%s: Never registered with dmabounce but attempting" \ + "to unregister!\n", dev->bus_id); + return; + } + + if (!list_empty(&device_info->safe_buffers)) { + printk(KERN_ERR + "%s: Removing from dmabounce with pending buffers!\n", + dev->bus_id); + BUG(); + } + + if (device_info->small_buffer_pool) + dma_pool_destroy(device_info->small_buffer_pool); + if (device_info->large_buffer_pool) + dma_pool_destroy(device_info->large_buffer_pool); + +#ifdef STATS + print_alloc_stats(device_info); + print_map_stats(device_info); +#endif + + list_del(&device_info->node); + + kfree(device_info); + + printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n", + dev->bus_id, dev->bus->name); +} + + +EXPORT_SYMBOL(dma_map_single); +EXPORT_SYMBOL(dma_unmap_single); +EXPORT_SYMBOL(dma_map_sg); +EXPORT_SYMBOL(dma_unmap_sg); +EXPORT_SYMBOL(dma_sync_single); +EXPORT_SYMBOL(dma_sync_sg); +EXPORT_SYMBOL(dmabounce_register_dev); +EXPORT_SYMBOL(dmabounce_unregister_dev); + +MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>, Deepak Saxena <dsaxena@plexity.net>"); +MODULE_DESCRIPTION("Special dma_{map/unmap/dma_sync}_* routines for systems with limited DMA windows"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c new file mode 100644 index 0000000..bafe8b1 --- /dev/null +++ b/arch/arm/common/icst307.c @@ -0,0 +1,161 @@ +/* + * linux/arch/arm/common/icst307.c + * + * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. + * + * 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. + * + * Support functions for calculating clocks/divisors for the ICST307 + * clock generators. See http://www.icst.com/ for more information + * on these devices. + * + * This is an almost identical implementation to the ICST525 clock generator. + * The s2div and idx2s files are different + */ +#include <linux/module.h> +#include <linux/kernel.h> + +#include <asm/hardware/icst307.h> + +/* + * Divisors for each OD setting. + */ +static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; + +unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco) +{ + return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); +} + +EXPORT_SYMBOL(icst307_khz); + +/* + * Ascending divisor S values. + */ +static unsigned char idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; + +struct icst307_vco +icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq) +{ + struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + unsigned long f; + unsigned int i = 0, rd, best = (unsigned int)-1; + + /* + * First, find the PLL output divisor such + * that the PLL output is within spec. + */ + do { + f = freq * s2div[idx2s[i]]; + + /* + * f must be between 6MHz and 200MHz (3.3 or 5V) + */ + if (f > 6000 && f <= p->vco_max) + break; + } while (i < ARRAY_SIZE(idx2s)); + + if (i > ARRAY_SIZE(idx2s)) + return vco; + + vco.s = idx2s[i]; + + /* + * Now find the closest divisor combination + * which gives a PLL output of 'f'. + */ + for (rd = p->rd_min; rd <= p->rd_max; rd++) { + unsigned long fref_div, f_pll; + unsigned int vd; + int f_diff; + + fref_div = (2 * p->ref) / rd; + + vd = (f + fref_div / 2) / fref_div; + if (vd < p->vd_min || vd > p->vd_max) + continue; + + f_pll = fref_div * vd; + f_diff = f_pll - f; + if (f_diff < 0) + f_diff = -f_diff; + + if ((unsigned)f_diff < best) { + vco.v = vd - 8; + vco.r = rd - 2; + if (f_diff == 0) + break; + best = f_diff; + } + } + + return vco; +} + +EXPORT_SYMBOL(icst307_khz_to_vco); + +struct icst307_vco +icst307_ps_to_vco(const struct icst307_params *p, unsigned long period) +{ + struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + unsigned long f, ps; + unsigned int i = 0, rd, best = (unsigned int)-1; + + ps = 1000000000UL / p->vco_max; + + /* + * First, find the PLL output divisor such + * that the PLL output is within spec. + */ + do { + f = period / s2div[idx2s[i]]; + + /* + * f must be between 6MHz and 200MHz (3.3 or 5V) + */ + if (f >= ps && f < 1000000000UL / 6000 + 1) + break; + } while (i < ARRAY_SIZE(idx2s)); + + if (i > ARRAY_SIZE(idx2s)) + return vco; + + vco.s = idx2s[i]; + + ps = 500000000UL / p->ref; + + /* + * Now find the closest divisor combination + * which gives a PLL output of 'f'. + */ + for (rd = p->rd_min; rd <= p->rd_max; rd++) { + unsigned long f_in_div, f_pll; + unsigned int vd; + int f_diff; + + f_in_div = ps * rd; + + vd = (f_in_div + f / 2) / f; + if (vd < p->vd_min || vd > p->vd_max) + continue; + + f_pll = (f_in_div + vd / 2) / vd; + f_diff = f_pll - f; + if (f_diff < 0) + f_diff = -f_diff; + + if ((unsigned)f_diff < best) { + vco.v = vd - 8; + vco.r = rd - 2; + if (f_diff == 0) + break; + best = f_diff; + } + } + + return vco; +} + +EXPORT_SYMBOL(icst307_ps_to_vco); diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c new file mode 100644 index 0000000..943ef88 --- /dev/null +++ b/arch/arm/common/icst525.c @@ -0,0 +1,160 @@ +/* + * linux/arch/arm/common/icst525.c + * + * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. + * + * 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. + * + * Support functions for calculating clocks/divisors for the ICST525 + * clock generators. See http://www.icst.com/ for more information + * on these devices. + */ +#include <linux/module.h> +#include <linux/kernel.h> + +#include <asm/hardware/icst525.h> + +/* + * Divisors for each OD setting. + */ +static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 }; + +unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco) +{ + return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); +} + +EXPORT_SYMBOL(icst525_khz); + +/* + * Ascending divisor S values. + */ +static unsigned char idx2s[] = { 1, 3, 4, 7, 5, 2, 6, 0 }; + +struct icst525_vco +icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq) +{ + struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + unsigned long f; + unsigned int i = 0, rd, best = (unsigned int)-1; + + /* + * First, find the PLL output divisor such + * that the PLL output is within spec. + */ + do { + f = freq * s2div[idx2s[i]]; + + /* + * f must be between 10MHz and + * 320MHz (5V) or 200MHz (3V) + */ + if (f > 10000 && f <= p->vco_max) + break; + } while (i < ARRAY_SIZE(idx2s)); + + if (i > ARRAY_SIZE(idx2s)) + return vco; + + vco.s = idx2s[i]; + + /* + * Now find the closest divisor combination + * which gives a PLL output of 'f'. + */ + for (rd = p->rd_min; rd <= p->rd_max; rd++) { + unsigned long fref_div, f_pll; + unsigned int vd; + int f_diff; + + fref_div = (2 * p->ref) / rd; + + vd = (f + fref_div / 2) / fref_div; + if (vd < p->vd_min || vd > p->vd_max) + continue; + + f_pll = fref_div * vd; + f_diff = f_pll - f; + if (f_diff < 0) + f_diff = -f_diff; + + if ((unsigned)f_diff < best) { + vco.v = vd - 8; + vco.r = rd - 2; + if (f_diff == 0) + break; + best = f_diff; + } + } + + return vco; +} + +EXPORT_SYMBOL(icst525_khz_to_vco); + +struct icst525_vco +icst525_ps_to_vco(const struct icst525_params *p, unsigned long period) +{ + struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + unsigned long f, ps; + unsigned int i = 0, rd, best = (unsigned int)-1; + + ps = 1000000000UL / p->vco_max; + + /* + * First, find the PLL output divisor such + * that the PLL output is within spec. + */ + do { + f = period / s2div[idx2s[i]]; + + /* + * f must be between 10MHz and + * 320MHz (5V) or 200MHz (3V) + */ + if (f >= ps && f < 100000) + break; + } while (i < ARRAY_SIZE(idx2s)); + + if (i > ARRAY_SIZE(idx2s)) + return vco; + + vco.s = idx2s[i]; + + ps = 500000000UL / p->ref; + + /* + * Now find the closest divisor combination + * which gives a PLL output of 'f'. + */ + for (rd = p->rd_min; rd <= p->rd_max; rd++) { + unsigned long f_in_div, f_pll; + unsigned int vd; + int f_diff; + + f_in_div = ps * rd; + + vd = (f_in_div + f / 2) / f; + if (vd < p->vd_min || vd > p->vd_max) + continue; + + f_pll = (f_in_div + vd / 2) / vd; + f_diff = f_pll - f; + if (f_diff < 0) + f_diff = -f_diff; + + if ((unsigned)f_diff < best) { + vco.v = vd - 8; + vco.r = rd - 2; + if (f_diff == 0) + break; + best = f_diff; + } + } + + return vco; +} + +EXPORT_SYMBOL(icst525_ps_to_vco); diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c new file mode 100644 index 0000000..41f1265 --- /dev/null +++ b/arch/arm/common/locomo.c @@ -0,0 +1,1058 @@ +/* + * linux/arch/arm/common/locomo.c + * + * Sharp LoCoMo support + * + * 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. + * + * This file contains all generic LoCoMo support. + * + * All initialization functions provided here are intended to be called + * from machine specific code with proper arguments when required. + * + * Based on sa1111.c + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/ioport.h> +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> + +#include <asm/hardware/locomo.h> + +/* M62332 output channel selection */ +#define M62332_EVR_CH 1 /* M62332 volume channel number */ + /* 0 : CH.1 , 1 : CH. 2 */ +/* DAC send data */ +#define M62332_SLAVE_ADDR 0x4e /* Slave address */ +#define M62332_W_BIT 0x00 /* W bit (0 only) */ +#define M62332_SUB_ADDR 0x00 /* Sub address */ +#define M62332_A_BIT 0x00 /* A bit (0 only) */ + +/* DAC setup and hold times (expressed in us) */ +#define DAC_BUS_FREE_TIME 5 /* 4.7 us */ +#define DAC_START_SETUP_TIME 5 /* 4.7 us */ +#define DAC_STOP_SETUP_TIME 4 /* 4.0 us */ +#define DAC_START_HOLD_TIME 5 /* 4.7 us */ +#define DAC_SCL_LOW_HOLD_TIME 5 /* 4.7 us */ +#define DAC_SCL_HIGH_HOLD_TIME 4 /* 4.0 us */ +#define DAC_DATA_SETUP_TIME 1 /* 250 ns */ +#define DAC_DATA_HOLD_TIME 1 /* 300 ns */ +#define DAC_LOW_SETUP_TIME 1 /* 300 ns */ +#define DAC_HIGH_SETUP_TIME 1 /* 1000 ns */ + +/* the following is the overall data for the locomo chip */ +struct locomo { + struct device *dev; + unsigned long phys; + unsigned int irq; + spinlock_t lock; + void *base; +}; + +struct locomo_dev_info { + unsigned long offset; + unsigned long length; + unsigned int devid; + unsigned int irq[1]; + const char * name; +}; + +/* All the locomo devices. If offset is non-zero, the mapbase for the + * locomo_dev will be set to the chip base plus offset. If offset is + * zero, then the mapbase for the locomo_dev will be set to zero. An + * offset of zero means the device only uses GPIOs or other helper + * functions inside this file */ +static struct locomo_dev_info locomo_devices[] = { + { + .devid = LOCOMO_DEVID_KEYBOARD, + .irq = { + IRQ_LOCOMO_KEY, + }, + .name = "locomo-keyboard", + .offset = LOCOMO_KEYBOARD, + .length = 16, + }, + { + .devid = LOCOMO_DEVID_FRONTLIGHT, + .irq = {}, + .name = "locomo-frontlight", + .offset = LOCOMO_FRONTLIGHT, + .length = 8, + + }, + { + .devid = LOCOMO_DEVID_BACKLIGHT, + .irq = {}, + .name = "locomo-backlight", + .offset = LOCOMO_BACKLIGHT, + .length = 8, + }, + { + .devid = LOCOMO_DEVID_AUDIO, + .irq = {}, + .name = "locomo-audio", + .offset = LOCOMO_AUDIO, + .length = 4, + }, + { + .devid = LOCOMO_DEVID_LED, + .irq = {}, + .name = "locomo-led", + .offset = LOCOMO_LED, + .length = 8, + }, + { + .devid = LOCOMO_DEVID_UART, + .irq = {}, + .name = "locomo-uart", + .offset = 0, + .length = 0, + }, +}; + + +/** LoCoMo interrupt handling stuff. + * NOTE: LoCoMo has a 1 to many mapping on all of its IRQs. + * that is, there is only one real hardware interrupt + * we determine which interrupt it is by reading some IO memory. + * We have two levels of expansion, first in the handler for the + * hardware interrupt we generate an interrupt + * IRQ_LOCOMO_*_BASE and those handlers generate more interrupts + * + * hardware irq reads LOCOMO_ICR & 0x0f00 + * IRQ_LOCOMO_KEY_BASE + * IRQ_LOCOMO_GPIO_BASE + * IRQ_LOCOMO_LT_BASE + * IRQ_LOCOMO_SPI_BASE + * IRQ_LOCOMO_KEY_BASE reads LOCOMO_KIC & 0x0001 + * IRQ_LOCOMO_KEY + * IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff + * IRQ_LOCOMO_GPIO[0-15] + * IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001 + * IRQ_LOCOMO_LT + * IRQ_LOCOMO_SPI_BASE reads LOCOMO_SPIIR & 0x000F + * IRQ_LOCOMO_SPI_RFR + * IRQ_LOCOMO_SPI_RFW + * IRQ_LOCOMO_SPI_OVRN + * IRQ_LOCOMO_SPI_TEND + */ + +#define LOCOMO_IRQ_START (IRQ_LOCOMO_KEY_BASE) +#define LOCOMO_IRQ_KEY_START (IRQ_LOCOMO_KEY) +#define LOCOMO_IRQ_GPIO_START (IRQ_LOCOMO_GPIO0) +#define LOCOMO_IRQ_LT_START (IRQ_LOCOMO_LT) +#define LOCOMO_IRQ_SPI_START (IRQ_LOCOMO_SPI_RFR) + +static void locomo_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + int req, i; + struct irqdesc *d; + void *mapbase = get_irq_chipdata(irq); + + /* Acknowledge the parent IRQ */ + desc->chip->ack(irq); + + /* check why this interrupt was generated */ + req = locomo_readl(mapbase + LOCOMO_ICR) & 0x0f00; + + if (req) { + /* generate the next interrupt(s) */ + irq = LOCOMO_IRQ_START; + d = irq_desc + irq; + for (i = 0; i <= 3; i++, d++, irq++) { + if (req & (0x0100 << i)) { + d->handle(irq, d, regs); + } + + } + } +} + +static void locomo_ack_irq(unsigned int irq) +{ +} + +static void locomo_mask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_ICR); + r &= ~(0x0010 << (irq - LOCOMO_IRQ_START)); + locomo_writel(r, mapbase + LOCOMO_ICR); +} + +static void locomo_unmask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_ICR); + r |= (0x0010 << (irq - LOCOMO_IRQ_START)); + locomo_writel(r, mapbase + LOCOMO_ICR); +} + +static struct irqchip locomo_chip = { + .ack = locomo_ack_irq, + .mask = locomo_mask_irq, + .unmask = locomo_unmask_irq, +}; + +static void locomo_key_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + struct irqdesc *d; + void *mapbase = get_irq_chipdata(irq); + + if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { + d = irq_desc + LOCOMO_IRQ_KEY_START; + d->handle(LOCOMO_IRQ_KEY_START, d, regs); + } +} + +static void locomo_key_ack_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); + r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START)); + locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); +} + +static void locomo_key_mask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); + r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START)); + locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); +} + +static void locomo_key_unmask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); + r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START)); + locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); +} + +static struct irqchip locomo_key_chip = { + .ack = locomo_key_ack_irq, + .mask = locomo_key_mask_irq, + .unmask = locomo_key_unmask_irq, +}; + +static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + int req, i; + struct irqdesc *d; + void *mapbase = get_irq_chipdata(irq); + + req = locomo_readl(mapbase + LOCOMO_GIR) & + locomo_readl(mapbase + LOCOMO_GPD) & + 0xffff; + + if (req) { + irq = LOCOMO_IRQ_GPIO_START; + d = irq_desc + LOCOMO_IRQ_GPIO_START; + for (i = 0; i <= 15; i++, irq++, d++) { + if (req & (0x0001 << i)) { + d->handle(irq, d, regs); + } + } + } +} + +static void locomo_gpio_ack_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_GWE); + r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); + locomo_writel(r, mapbase + LOCOMO_GWE); + + r = locomo_readl(mapbase + LOCOMO_GIS); + r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); + locomo_writel(r, mapbase + LOCOMO_GIS); + + r = locomo_readl(mapbase + LOCOMO_GWE); + r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); + locomo_writel(r, mapbase + LOCOMO_GWE); +} + +static void locomo_gpio_mask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_GIE); + r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); + locomo_writel(r, mapbase + LOCOMO_GIE); +} + +static void locomo_gpio_unmask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_GIE); + r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); + locomo_writel(r, mapbase + LOCOMO_GIE); +} + +static struct irqchip locomo_gpio_chip = { + .ack = locomo_gpio_ack_irq, + .mask = locomo_gpio_mask_irq, + .unmask = locomo_gpio_unmask_irq, +}; + +static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + struct irqdesc *d; + void *mapbase = get_irq_chipdata(irq); + + if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) { + d = irq_desc + LOCOMO_IRQ_LT_START; + d->handle(LOCOMO_IRQ_LT_START, d, regs); + } +} + +static void locomo_lt_ack_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_LTINT); + r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START)); + locomo_writel(r, mapbase + LOCOMO_LTINT); +} + +static void locomo_lt_mask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_LTINT); + r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START)); + locomo_writel(r, mapbase + LOCOMO_LTINT); +} + +static void locomo_lt_unmask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_LTINT); + r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START)); + locomo_writel(r, mapbase + LOCOMO_LTINT); +} + +static struct irqchip locomo_lt_chip = { + .ack = locomo_lt_ack_irq, + .mask = locomo_lt_mask_irq, + .unmask = locomo_lt_unmask_irq, +}; + +static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + int req, i; + struct irqdesc *d; + void *mapbase = get_irq_chipdata(irq); + + req = locomo_readl(mapbase + LOCOMO_SPIIR) & 0x000F; + if (req) { + irq = LOCOMO_IRQ_SPI_START; + d = irq_desc + irq; + + for (i = 0; i <= 3; i++, irq++, d++) { + if (req & (0x0001 << i)) { + d->handle(irq, d, regs); + } + } + } +} + +static void locomo_spi_ack_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_SPIWE); + r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); + locomo_writel(r, mapbase + LOCOMO_SPIWE); + + r = locomo_readl(mapbase + LOCOMO_SPIIS); + r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); + locomo_writel(r, mapbase + LOCOMO_SPIIS); + + r = locomo_readl(mapbase + LOCOMO_SPIWE); + r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); + locomo_writel(r, mapbase + LOCOMO_SPIWE); +} + +static void locomo_spi_mask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_SPIIE); + r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); + locomo_writel(r, mapbase + LOCOMO_SPIIE); +} + +static void locomo_spi_unmask_irq(unsigned int irq) +{ + void *mapbase = get_irq_chipdata(irq); + unsigned int r; + r = locomo_readl(mapbase + LOCOMO_SPIIE); + r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); + locomo_writel(r, mapbase + LOCOMO_SPIIE); +} + +static struct irqchip locomo_spi_chip = { + .ack = locomo_spi_ack_irq, + .mask = locomo_spi_mask_irq, + .unmask = locomo_spi_unmask_irq, +}; + +static void locomo_setup_irq(struct locomo *lchip) +{ + int irq; + void *irqbase = lchip->base; + + /* + * Install handler for IRQ_LOCOMO_HW. + */ + set_irq_type(lchip->irq, IRQT_FALLING); + set_irq_chipdata(lchip->irq, irqbase); + set_irq_chained_handler(lchip->irq, locomo_handler); + + /* Install handlers for IRQ_LOCOMO_*_BASE */ + set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip); + set_irq_chipdata(IRQ_LOCOMO_KEY_BASE, irqbase); + set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler); + set_irq_flags(IRQ_LOCOMO_KEY_BASE, IRQF_VALID | IRQF_PROBE); + + set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip); + set_irq_chipdata(IRQ_LOCOMO_GPIO_BASE, irqbase); + set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler); + set_irq_flags(IRQ_LOCOMO_GPIO_BASE, IRQF_VALID | IRQF_PROBE); + + set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip); + set_irq_chipdata(IRQ_LOCOMO_LT_BASE, irqbase); + set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler); + set_irq_flags(IRQ_LOCOMO_LT_BASE, IRQF_VALID | IRQF_PROBE); + + set_irq_chip(IRQ_LOCOMO_SPI_BASE, &locomo_chip); + set_irq_chipdata(IRQ_LOCOMO_SPI_BASE, irqbase); + set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler); + set_irq_flags(IRQ_LOCOMO_SPI_BASE, IRQF_VALID | IRQF_PROBE); + + /* install handlers for IRQ_LOCOMO_KEY_BASE generated interrupts */ + set_irq_chip(LOCOMO_IRQ_KEY_START, &locomo_key_chip); + set_irq_chipdata(LOCOMO_IRQ_KEY_START, irqbase); + set_irq_handler(LOCOMO_IRQ_KEY_START, do_edge_IRQ); + set_irq_flags(LOCOMO_IRQ_KEY_START, IRQF_VALID | IRQF_PROBE); + + /* install handlers for IRQ_LOCOMO_GPIO_BASE generated interrupts */ + for (irq = LOCOMO_IRQ_GPIO_START; irq < LOCOMO_IRQ_GPIO_START + 16; irq++) { + set_irq_chip(irq, &locomo_gpio_chip); + set_irq_chipdata(irq, irqbase); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + /* install handlers for IRQ_LOCOMO_LT_BASE generated interrupts */ + set_irq_chip(LOCOMO_IRQ_LT_START, &locomo_lt_chip); + set_irq_chipdata(LOCOMO_IRQ_LT_START, irqbase); + set_irq_handler(LOCOMO_IRQ_LT_START, do_edge_IRQ); + set_irq_flags(LOCOMO_IRQ_LT_START, IRQF_VALID | IRQF_PROBE); + + /* install handlers for IRQ_LOCOMO_SPI_BASE generated interrupts */ + for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 3; irq++) { + set_irq_chip(irq, &locomo_spi_chip); + set_irq_chipdata(irq, irqbase); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } +} + + +static void locomo_dev_release(struct device *_dev) +{ + struct locomo_dev *dev = LOCOMO_DEV(_dev); + + kfree(dev); +} + +static int +locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info) +{ + struct locomo_dev *dev; + int ret; + + dev = kmalloc(sizeof(struct locomo_dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto out; + } + memset(dev, 0, sizeof(struct locomo_dev)); + + strncpy(dev->dev.bus_id,info->name,sizeof(dev->dev.bus_id)); + /* + * If the parent device has a DMA mask associated with it, + * propagate it down to the children. + */ + if (lchip->dev->dma_mask) { + dev->dma_mask = *lchip->dev->dma_mask; + dev->dev.dma_mask = &dev->dma_mask; + } + + dev->devid = info->devid; + dev->dev.parent = lchip->dev; + dev->dev.bus = &locomo_bus_type; + dev->dev.release = locomo_dev_release; + dev->dev.coherent_dma_mask = lchip->dev->coherent_dma_mask; + + if (info->offset) + dev->mapbase = lchip->base + info->offset; + else + dev->mapbase = 0; + dev->length = info->length; + + memmove(dev->irq, info->irq, sizeof(dev->irq)); + + ret = device_register(&dev->dev); + if (ret) { + out: + kfree(dev); + } + return ret; +} + +/** + * locomo_probe - probe for a single LoCoMo chip. + * @phys_addr: physical address of device. + * + * Probe for a LoCoMo chip. This must be called + * before any other locomo-specific code. + * + * Returns: + * %-ENODEV device not found. + * %-EBUSY physical address already marked in-use. + * %0 successful. + */ +static int +__locomo_probe(struct device *me, struct resource *mem, int irq) +{ + struct locomo *lchip; + unsigned long r; + int i, ret = -ENODEV; + + lchip = kmalloc(sizeof(struct locomo), GFP_KERNEL); + if (!lchip) + return -ENOMEM; + + memset(lchip, 0, sizeof(struct locomo)); + + spin_lock_init(&lchip->lock); + + lchip->dev = me; + dev_set_drvdata(lchip->dev, lchip); + + lchip->phys = mem->start; + lchip->irq = irq; + + /* + * Map the whole region. This also maps the + * registers for our children. + */ + lchip->base = ioremap(mem->start, PAGE_SIZE); + if (!lchip->base) { + ret = -ENOMEM; + goto out; + } + + /* locomo initialize */ + locomo_writel(0, lchip->base + LOCOMO_ICR); + /* KEYBOARD */ + locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC); + + /* GPIO */ + locomo_writel(0, lchip->base + LOCOMO_GPO); + locomo_writel( (LOCOMO_GPIO(2) | LOCOMO_GPIO(3) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14)) + , lchip->base + LOCOMO_GPE); + locomo_writel( (LOCOMO_GPIO(2) | LOCOMO_GPIO(3) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14)) + , lchip->base + LOCOMO_GPD); + locomo_writel(0, lchip->base + LOCOMO_GIE); + + /* FrontLight */ + locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); + locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); + /* Longtime timer */ + locomo_writel(0, lchip->base + LOCOMO_LTINT); + /* SPI */ + locomo_writel(0, lchip->base + LOCOMO_SPIIE); + + locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD); + r = locomo_readl(lchip->base + LOCOMO_ASD); + r |= 0x8000; + locomo_writel(r, lchip->base + LOCOMO_ASD); + + locomo_writel(6 + 8 + 320 + 30 - 10 - 128 + 4, lchip->base + LOCOMO_HSD); + r = locomo_readl(lchip->base + LOCOMO_HSD); + r |= 0x8000; + locomo_writel(r, lchip->base + LOCOMO_HSD); + + locomo_writel(128 / 8, lchip->base + LOCOMO_HSC); + + /* XON */ + locomo_writel(0x80, lchip->base + LOCOMO_TADC); + udelay(1000); + /* CLK9MEN */ + r = locomo_readl(lchip->base + LOCOMO_TADC); + r |= 0x10; + locomo_writel(r, lchip->base + LOCOMO_TADC); + udelay(100); + + /* init DAC */ + r = locomo_readl(lchip->base + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB; + locomo_writel(r, lchip->base + LOCOMO_DAC); + + r = locomo_readl(lchip->base + LOCOMO_VER); + printk(KERN_INFO "LoCoMo Chip: %lu%lu\n", (r >> 8), (r & 0xff)); + + /* + * The interrupt controller must be initialised before any + * other device to ensure that the interrupts are available. + */ + if (lchip->irq != NO_IRQ) + locomo_setup_irq(lchip); + + for (i = 0; i < ARRAY_SIZE(locomo_devices); i++) + locomo_init_one_child(lchip, &locomo_devices[i]); + + return 0; + + out: + kfree(lchip); + return ret; +} + +static void __locomo_remove(struct locomo *lchip) +{ + struct list_head *l, *n; + + list_for_each_safe(l, n, &lchip->dev->children) { + struct device *d = list_to_dev(l); + + device_unregister(d); + } + + if (lchip->irq != NO_IRQ) { + set_irq_chained_handler(lchip->irq, NULL); + set_irq_data(lchip->irq, NULL); + } + + iounmap(lchip->base); + kfree(lchip); +} + +static int locomo_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct resource *mem; + int irq; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) + return -EINVAL; + irq = platform_get_irq(pdev, 0); + + return __locomo_probe(dev, mem, irq); +} + +static int locomo_remove(struct device *dev) +{ + struct locomo *lchip = dev_get_drvdata(dev); + + if (lchip) { + __locomo_remove(lchip); + dev_set_drvdata(dev, NULL); + } + + return 0; +} + +/* + * Not sure if this should be on the system bus or not yet. + * We really want some way to register a system device at + * the per-machine level, and then have this driver pick + * up the registered devices. + */ +static struct device_driver locomo_device_driver = { + .name = "locomo", + .bus = &platform_bus_type, + .probe = locomo_probe, + .remove = locomo_remove, +}; + +/* + * Get the parent device driver (us) structure + * from a child function device + */ +static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev) +{ + return (struct locomo *)dev_get_drvdata(ldev->dev.parent); +} + +void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + unsigned long flags; + unsigned int r; + + spin_lock_irqsave(&lchip->lock, flags); + + r = locomo_readl(lchip->base + LOCOMO_GPD); + r &= ~bits; + locomo_writel(r, lchip->base + LOCOMO_GPD); + + r = locomo_readl(lchip->base + LOCOMO_GPE); + if (dir) + r |= bits; + else + r &= ~bits; + locomo_writel(r, lchip->base + LOCOMO_GPE); + + spin_unlock_irqrestore(&lchip->lock, flags); +} + +unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + unsigned long flags; + unsigned int ret; + + spin_lock_irqsave(&lchip->lock, flags); + ret = locomo_readl(lchip->base + LOCOMO_GPL); + spin_unlock_irqrestore(&lchip->lock, flags); + + ret &= bits; + return ret; +} + +unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + unsigned long flags; + unsigned int ret; + + spin_lock_irqsave(&lchip->lock, flags); + ret = locomo_readl(lchip->base + LOCOMO_GPO); + spin_unlock_irqrestore(&lchip->lock, flags); + + ret &= bits; + return ret; +} + +void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + unsigned long flags; + unsigned int r; + + spin_lock_irqsave(&lchip->lock, flags); + + r = locomo_readl(lchip->base + LOCOMO_GPO); + if (set) + r |= bits; + else + r &= ~bits; + locomo_writel(r, lchip->base + LOCOMO_GPO); + + spin_unlock_irqrestore(&lchip->lock, flags); +} + +static void locomo_m62332_sendbit(void *mapbase, int bit) +{ + unsigned int r; + + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_DATA_HOLD_TIME); /* 300 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + + if (bit & 1) { + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SDAOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + } else { + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + } + + udelay(DAC_DATA_SETUP_TIME); /* 250 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.0 usec */ +} + +void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel) +{ + struct locomo *lchip = locomo_chip_driver(ldev); + int i; + unsigned char data; + unsigned int r; + void *mapbase = lchip->base; + unsigned long flags; + + spin_lock_irqsave(&lchip->lock, flags); + + /* Start */ + udelay(DAC_BUS_FREE_TIME); /* 5.0 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.0 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_START_HOLD_TIME); /* 5.0 usec */ + udelay(DAC_DATA_HOLD_TIME); /* 300 nsec */ + + /* Send slave address and W bit (LSB is W bit) */ + data = (M62332_SLAVE_ADDR << 1) | M62332_W_BIT; + for (i = 1; i <= 8; i++) { + locomo_m62332_sendbit(mapbase, data >> (8 - i)); + } + + /* Check A bit */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ + if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ + printk(KERN_WARNING "locomo: m62332_senddata Error 1\n"); + return; + } + + /* Send Sub address (LSB is channel select) */ + /* channel = 0 : ch1 select */ + /* = 1 : ch2 select */ + data = M62332_SUB_ADDR + channel; + for (i = 1; i <= 8; i++) { + locomo_m62332_sendbit(mapbase, data >> (8 - i)); + } + + /* Check A bit */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ + if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ + printk(KERN_WARNING "locomo: m62332_senddata Error 2\n"); + return; + } + + /* Send DAC data */ + for (i = 1; i <= 8; i++) { + locomo_m62332_sendbit(mapbase, dac_data >> (8 - i)); + } + + /* Check A bit */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SDAOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ + if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ + printk(KERN_WARNING "locomo: m62332_senddata Error 3\n"); + return; + } + + /* stop */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r &= ~(LOCOMO_DAC_SCLOEB); + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4 usec */ + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SDAOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4 usec */ + + r = locomo_readl(mapbase + LOCOMO_DAC); + r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB; + locomo_writel(r, mapbase + LOCOMO_DAC); + udelay(DAC_LOW_SETUP_TIME); /* 1000 nsec */ + udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */ + + spin_unlock_irqrestore(&lchip->lock, flags); +} + +/* + * LoCoMo "Register Access Bus." + * + * We model this as a regular bus type, and hang devices directly + * off this. + */ +static int locomo_match(struct device *_dev, struct device_driver *_drv) +{ + struct locomo_dev *dev = LOCOMO_DEV(_dev); + struct locomo_driver *drv = LOCOMO_DRV(_drv); + + return dev->devid == drv->devid; +} + +static int locomo_bus_suspend(struct device *dev, pm_message_t state) +{ + struct locomo_dev *ldev = LOCOMO_DEV(dev); + struct locomo_driver *drv = LOCOMO_DRV(dev->driver); + int ret = 0; + + if (drv && drv->suspend) + ret = drv->suspend(ldev, state); + return ret; +} + +static int locomo_bus_resume(struct device *dev) +{ + struct locomo_dev *ldev = LOCOMO_DEV(dev); + struct locomo_driver *drv = LOCOMO_DRV(dev->driver); + int ret = 0; + + if (drv && drv->resume) + ret = drv->resume(ldev); + return ret; +} + +static int locomo_bus_probe(struct device *dev) +{ + struct locomo_dev *ldev = LOCOMO_DEV(dev); + struct locomo_driver *drv = LOCOMO_DRV(dev->driver); + int ret = -ENODEV; + + if (drv->probe) + ret = drv->probe(ldev); + return ret; +} + +static int locomo_bus_remove(struct device *dev) +{ + struct locomo_dev *ldev = LOCOMO_DEV(dev); + struct locomo_driver *drv = LOCOMO_DRV(dev->driver); + int ret = 0; + + if (drv->remove) + ret = drv->remove(ldev); + return ret; +} + +struct bus_type locomo_bus_type = { + .name = "locomo-bus", + .match = locomo_match, + .suspend = locomo_bus_suspend, + .resume = locomo_bus_resume, +}; + +int locomo_driver_register(struct locomo_driver *driver) +{ + driver->drv.probe = locomo_bus_probe; + driver->drv.remove = locomo_bus_remove; + driver->drv.bus = &locomo_bus_type; + return driver_register(&driver->drv); +} + +void locomo_driver_unregister(struct locomo_driver *driver) +{ + driver_unregister(&driver->drv); +} + +static int __init locomo_init(void) +{ + int ret = bus_register(&locomo_bus_type); + if (ret == 0) + driver_register(&locomo_device_driver); + return ret; +} + +static void __exit locomo_exit(void) +{ + driver_unregister(&locomo_device_driver); + bus_unregister(&locomo_bus_type); +} + +module_init(locomo_init); +module_exit(locomo_exit); + +MODULE_DESCRIPTION("Sharp LoCoMo core driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>"); + +EXPORT_SYMBOL(locomo_driver_register); +EXPORT_SYMBOL(locomo_driver_unregister); +EXPORT_SYMBOL(locomo_gpio_set_dir); +EXPORT_SYMBOL(locomo_gpio_read_level); +EXPORT_SYMBOL(locomo_gpio_read_output); +EXPORT_SYMBOL(locomo_gpio_write); +EXPORT_SYMBOL(locomo_m62332_senddata); diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c new file mode 100644 index 0000000..c397e71 --- /dev/null +++ b/arch/arm/common/rtctime.c @@ -0,0 +1,506 @@ +/* + * linux/arch/arm/common/rtctime.c + * + * Copyright (C) 2003 Deep Blue Solutions Ltd. + * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre. + * Based on rtc.c by Paul Gortmaker + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/time.h> +#include <linux/rtc.h> +#include <linux/poll.h> +#include <linux/proc_fs.h> +#include <linux/miscdevice.h> +#include <linux/spinlock.h> +#include <linux/device.h> + +#include <asm/rtc.h> +#include <asm/semaphore.h> + +static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); +static struct fasync_struct *rtc_async_queue; + +/* + * rtc_lock protects rtc_irq_data + */ +static DEFINE_SPINLOCK(rtc_lock); +static unsigned long rtc_irq_data; + +/* + * rtc_sem protects rtc_inuse and rtc_ops + */ +static DECLARE_MUTEX(rtc_sem); +static unsigned long rtc_inuse; +static struct rtc_ops *rtc_ops; + +#define rtc_epoch 1900UL + +static const unsigned char days_in_month[] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) +#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) + +static int month_days(unsigned int month, unsigned int year) +{ + return days_in_month[month] + (LEAP_YEAR(year) && month == 1); +} + +/* + * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. + */ +void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) +{ + int days, month, year; + + days = time / 86400; + time -= days * 86400; + + tm->tm_wday = (days + 4) % 7; + + year = 1970 + days / 365; + days -= (year - 1970) * 365 + + LEAPS_THRU_END_OF(year - 1) + - LEAPS_THRU_END_OF(1970 - 1); + if (days < 0) { + year -= 1; + days += 365 + LEAP_YEAR(year); + } + tm->tm_year = year - 1900; + tm->tm_yday = days + 1; + + for (month = 0; month < 11; month++) { + int newdays; + + newdays = days - month_days(month, year); + if (newdays < 0) + break; + days = newdays; + } + tm->tm_mon = month; + tm->tm_mday = days + 1; + + tm->tm_hour = time / 3600; + time -= tm->tm_hour * 3600; + tm->tm_min = time / 60; + tm->tm_sec = time - tm->tm_min * 60; +} +EXPORT_SYMBOL(rtc_time_to_tm); + +/* + * Does the rtc_time represent a valid date/time? + */ +int rtc_valid_tm(struct rtc_time *tm) +{ + if (tm->tm_year < 70 || + tm->tm_mon >= 12 || + tm->tm_mday < 1 || + tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) || + tm->tm_hour >= 24 || + tm->tm_min >= 60 || + tm->tm_sec >= 60) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL(rtc_valid_tm); + +/* + * Convert Gregorian date to seconds since 01-01-1970 00:00:00. + */ +int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) +{ + *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + + return 0; +} +EXPORT_SYMBOL(rtc_tm_to_time); + +/* + * Calculate the next alarm time given the requested alarm time mask + * and the current time. + * + * FIXME: for now, we just copy the alarm time because we're lazy (and + * is therefore buggy - setting a 10am alarm at 8pm will not result in + * the alarm triggering.) + */ +void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) +{ + next->tm_year = now->tm_year; + next->tm_mon = now->tm_mon; + next->tm_mday = now->tm_mday; + next->tm_hour = alrm->tm_hour; + next->tm_min = alrm->tm_min; + next->tm_sec = alrm->tm_sec; +} + +static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) +{ + memset(tm, 0, sizeof(struct rtc_time)); + ops->read_time(tm); +} + +static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) +{ + int ret; + + ret = rtc_valid_tm(tm); + if (ret == 0) + ret = ops->set_time(tm); + + return ret; +} + +static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) +{ + int ret = -EINVAL; + if (ops->read_alarm) { + memset(alrm, 0, sizeof(struct rtc_wkalrm)); + ops->read_alarm(alrm); + ret = 0; + } + return ret; +} + +static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) +{ + int ret = -EINVAL; + if (ops->set_alarm) + ret = ops->set_alarm(alrm); + return ret; +} + +void rtc_update(unsigned long num, unsigned long events) +{ + spin_lock(&rtc_lock); + rtc_irq_data = (rtc_irq_data + (num << 8)) | events; + spin_unlock(&rtc_lock); + + wake_up_interruptible(&rtc_wait); + kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); +} +EXPORT_SYMBOL(rtc_update); + + +static ssize_t +rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long data; + ssize_t ret; + + if (count < sizeof(unsigned long)) + return -EINVAL; + + add_wait_queue(&rtc_wait, &wait); + do { + __set_current_state(TASK_INTERRUPTIBLE); + + spin_lock_irq(&rtc_lock); + data = rtc_irq_data; + rtc_irq_data = 0; + spin_unlock_irq(&rtc_lock); + + if (data != 0) { + ret = 0; + break; + } + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + break; + } + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + schedule(); + } while (1); + set_current_state(TASK_RUNNING); + remove_wait_queue(&rtc_wait, &wait); + + if (ret == 0) { + ret = put_user(data, (unsigned long __user *)buf); + if (ret == 0) + ret = sizeof(unsigned long); + } + return ret; +} + +static unsigned int rtc_poll(struct file *file, poll_table *wait) +{ + unsigned long data; + + poll_wait(file, &rtc_wait, wait); + + spin_lock_irq(&rtc_lock); + data = rtc_irq_data; + spin_unlock_irq(&rtc_lock); + + return data != 0 ? POLLIN | POLLRDNORM : 0; +} + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct rtc_ops *ops = file->private_data; + struct rtc_time tm; + struct rtc_wkalrm alrm; + void __user *uarg = (void __user *)arg; + int ret = -EINVAL; + + switch (cmd) { + case RTC_ALM_READ: + ret = rtc_read_alarm(ops, &alrm); + if (ret) + break; + ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); + if (ret) + ret = -EFAULT; + break; + + case RTC_ALM_SET: + ret = copy_from_user(&alrm.time, uarg, sizeof(tm)); + if (ret) { + ret = -EFAULT; + break; + } + alrm.enabled = 0; + alrm.pending = 0; + alrm.time.tm_mday = -1; + alrm.time.tm_mon = -1; + alrm.time.tm_year = -1; + alrm.time.tm_wday = -1; + alrm.time.tm_yday = -1; + alrm.time.tm_isdst = -1; + ret = rtc_set_alarm(ops, &alrm); + break; + + case RTC_RD_TIME: + rtc_read_time(ops, &tm); + ret = copy_to_user(uarg, &tm, sizeof(tm)); + if (ret) + ret = -EFAULT; + break; + + case RTC_SET_TIME: + if (!capable(CAP_SYS_TIME)) { + ret = -EACCES; + break; + } + ret = copy_from_user(&tm, uarg, sizeof(tm)); + if (ret) { + ret = -EFAULT; + break; + } + ret = rtc_set_time(ops, &tm); + break; + + case RTC_EPOCH_SET: +#ifndef rtc_epoch + /* + * There were no RTC clocks before 1900. + */ + if (arg < 1900) { + ret = -EINVAL; + break; + } + if (!capable(CAP_SYS_TIME)) { + ret = -EACCES; + break; + } + rtc_epoch = arg; + ret = 0; +#endif + break; + + case RTC_EPOCH_READ: + ret = put_user(rtc_epoch, (unsigned long __user *)uarg); + break; + + case RTC_WKALM_SET: + ret = copy_from_user(&alrm, uarg, sizeof(alrm)); + if (ret) { + ret = -EFAULT; + break; + } + ret = rtc_set_alarm(ops, &alrm); + break; + + case RTC_WKALM_RD: + ret = rtc_read_alarm(ops, &alrm); + if (ret) + break; + ret = copy_to_user(uarg, &alrm, sizeof(alrm)); + if (ret) + ret = -EFAULT; + break; + + default: + if (ops->ioctl) + ret = ops->ioctl(cmd, arg); + break; + } + return ret; +} + +static int rtc_open(struct inode *inode, struct file *file) +{ + int ret; + + down(&rtc_sem); + + if (rtc_inuse) { + ret = -EBUSY; + } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) { + ret = -ENODEV; + } else { + file->private_data = rtc_ops; + + ret = rtc_ops->open ? rtc_ops->open() : 0; + if (ret == 0) { + spin_lock_irq(&rtc_lock); + rtc_irq_data = 0; + spin_unlock_irq(&rtc_lock); + + rtc_inuse = 1; + } + } + up(&rtc_sem); + + return ret; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + struct rtc_ops *ops = file->private_data; + + if (ops->release) + ops->release(); + + spin_lock_irq(&rtc_lock); + rtc_irq_data = 0; + spin_unlock_irq(&rtc_lock); + + module_put(rtc_ops->owner); + rtc_inuse = 0; + + return 0; +} + +static int rtc_fasync(int fd, struct file *file, int on) +{ + return fasync_helper(fd, file, on, &rtc_async_queue); +} + +static struct file_operations rtc_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = rtc_read, + .poll = rtc_poll, + .ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, + .fasync = rtc_fasync, +}; + +static struct miscdevice rtc_miscdev = { + .minor = RTC_MINOR, + .name = "rtc", + .fops = &rtc_fops, +}; + + +static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct rtc_ops *ops = data; + struct rtc_wkalrm alrm; + struct rtc_time tm; + char *p = page; + + rtc_read_time(ops, &tm); + + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + rtc_epoch); + + if (rtc_read_alarm(ops, &alrm) == 0) { + p += sprintf(p, "alrm_time\t: "); + if ((unsigned int)alrm.time.tm_hour <= 24) + p += sprintf(p, "%02d:", alrm.time.tm_hour); + else + p += sprintf(p, "**:"); + if ((unsigned int)alrm.time.tm_min <= 59) + p += sprintf(p, "%02d:", alrm.time.tm_min); + else + p += sprintf(p, "**:"); + if ((unsigned int)alrm.time.tm_sec <= 59) + p += sprintf(p, "%02d\n", alrm.time.tm_sec); + else + p += sprintf(p, "**\n"); + + p += sprintf(p, "alrm_date\t: "); + if ((unsigned int)alrm.time.tm_year <= 200) + p += sprintf(p, "%04d-", alrm.time.tm_year + 1900); + else + p += sprintf(p, "****-"); + if ((unsigned int)alrm.time.tm_mon <= 11) + p += sprintf(p, "%02d-", alrm.time.tm_mon + 1); + else + p += sprintf(p, "**-"); + if ((unsigned int)alrm.time.tm_mday <= 31) + p += sprintf(p, "%02d\n", alrm.time.tm_mday); + else + p += sprintf(p, "**\n"); + p += sprintf(p, "alrm_wakeup\t: %s\n", + alrm.enabled ? "yes" : "no"); + p += sprintf(p, "alrm_pending\t: %s\n", + alrm.pending ? "yes" : "no"); + } + + if (ops->proc) + p += ops->proc(p); + + return p - page; +} + +int register_rtc(struct rtc_ops *ops) +{ + int ret = -EBUSY; + + down(&rtc_sem); + if (rtc_ops == NULL) { + rtc_ops = ops; + + ret = misc_register(&rtc_miscdev); + if (ret == 0) + create_proc_read_entry("driver/rtc", 0, NULL, + rtc_read_proc, ops); + } + up(&rtc_sem); + + return ret; +} +EXPORT_SYMBOL(register_rtc); + +void unregister_rtc(struct rtc_ops *rtc) +{ + down(&rtc_sem); + if (rtc == rtc_ops) { + remove_proc_entry("driver/rtc", NULL); + misc_deregister(&rtc_miscdev); + rtc_ops = NULL; + } + up(&rtc_sem); +} +EXPORT_SYMBOL(unregister_rtc); diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c new file mode 100644 index 0000000..21fce34 --- /dev/null +++ b/arch/arm/common/sa1111.c @@ -0,0 +1,1292 @@ +/* + * linux/arch/arm/mach-sa1100/sa1111.c + * + * SA1111 support + * + * Original code by John Dorsey + * + * 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. + * + * This file contains all generic SA1111 support. + * + * All initialization functions provided here are intended to be called + * from machine specific code with proper arguments when required. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/ptrace.h> +#include <linux/errno.h> +#include <linux/ioport.h> +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/dma-mapping.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> + +#include <asm/hardware/sa1111.h> + +#ifdef CONFIG_ARCH_PXA +#include <asm/arch/pxa-regs.h> +#endif + +extern void __init sa1110_mb_enable(void); + +/* + * We keep the following data for the overall SA1111. Note that the + * struct device and struct resource are "fake"; they should be supplied + * by the bus above us. However, in the interests of getting all SA1111 + * drivers converted over to the device model, we provide this as an + * anchor point for all the other drivers. + */ +struct sa1111 { + struct device *dev; + unsigned long phys; + int irq; + spinlock_t lock; + void __iomem *base; +}; + +/* + * We _really_ need to eliminate this. Its only users + * are the PWM and DMA checking code. + */ +static struct sa1111 *g_sa1111; + +struct sa1111_dev_info { + unsigned long offset; + unsigned long skpcr_mask; + unsigned int devid; + unsigned int irq[6]; +}; + +static struct sa1111_dev_info sa1111_devices[] = { + { + .offset = SA1111_USB, + .skpcr_mask = SKPCR_UCLKEN, + .devid = SA1111_DEVID_USB, + .irq = { + IRQ_USBPWR, + IRQ_HCIM, + IRQ_HCIBUFFACC, + IRQ_HCIRMTWKP, + IRQ_NHCIMFCIR, + IRQ_USB_PORT_RESUME + }, + }, + { + .offset = 0x0600, + .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, + .devid = SA1111_DEVID_SAC, + .irq = { + AUDXMTDMADONEA, + AUDXMTDMADONEB, + AUDRCVDMADONEA, + AUDRCVDMADONEB + }, + }, + { + .offset = 0x0800, + .skpcr_mask = SKPCR_SCLKEN, + .devid = SA1111_DEVID_SSP, + }, + { + .offset = SA1111_KBD, + .skpcr_mask = SKPCR_PTCLKEN, + .devid = SA1111_DEVID_PS2, + .irq = { + IRQ_TPRXINT, + IRQ_TPTXINT + }, + }, + { + .offset = SA1111_MSE, + .skpcr_mask = SKPCR_PMCLKEN, + .devid = SA1111_DEVID_PS2, + .irq = { + IRQ_MSRXINT, + IRQ_MSTXINT + }, + }, + { + .offset = 0x1800, + .skpcr_mask = 0, + .devid = SA1111_DEVID_PCMCIA, + .irq = { + IRQ_S0_READY_NINT, + IRQ_S0_CD_VALID, + IRQ_S0_BVD1_STSCHG, + IRQ_S1_READY_NINT, + IRQ_S1_CD_VALID, + IRQ_S1_BVD1_STSCHG, + }, + }, +}; + +/* + * SA1111 interrupt support. Since clearing an IRQ while there are + * active IRQs causes the interrupt output to pulse, the upper levels + * will call us again if there are more interrupts to process. + */ +static void +sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + unsigned int stat0, stat1, i; + void __iomem *base = desc->data; + + stat0 = sa1111_readl(base + SA1111_INTSTATCLR0); + stat1 = sa1111_readl(base + SA1111_INTSTATCLR1); + + sa1111_writel(stat0, base + SA1111_INTSTATCLR0); + + desc->chip->ack(irq); + + sa1111_writel(stat1, base + SA1111_INTSTATCLR1); + + if (stat0 == 0 && stat1 == 0) { + do_bad_IRQ(irq, desc, regs); + return; + } + + for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1) + if (stat0 & 1) + do_edge_IRQ(i, irq_desc + i, regs); + + for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1) + if (stat1 & 1) + do_edge_IRQ(i, irq_desc + i, regs); + + /* For level-based interrupts */ + desc->chip->unmask(irq); +} + +#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START)) +#define SA1111_IRQMASK_HI(x) (1 << (x - IRQ_SA1111_START - 32)) + +static void sa1111_ack_irq(unsigned int irq) +{ +} + +static void sa1111_mask_lowirq(unsigned int irq) +{ + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long ie0; + + ie0 = sa1111_readl(mapbase + SA1111_INTEN0); + ie0 &= ~SA1111_IRQMASK_LO(irq); + writel(ie0, mapbase + SA1111_INTEN0); +} + +static void sa1111_unmask_lowirq(unsigned int irq) +{ + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long ie0; + + ie0 = sa1111_readl(mapbase + SA1111_INTEN0); + ie0 |= SA1111_IRQMASK_LO(irq); + sa1111_writel(ie0, mapbase + SA1111_INTEN0); +} + +/* + * Attempt to re-trigger the interrupt. The SA1111 contains a register + * (INTSET) which claims to do this. However, in practice no amount of + * manipulation of INTEN and INTSET guarantees that the interrupt will + * be triggered. In fact, its very difficult, if not impossible to get + * INTSET to re-trigger the interrupt. + */ +static int sa1111_retrigger_lowirq(unsigned int irq) +{ + unsigned int mask = SA1111_IRQMASK_LO(irq); + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long ip0; + int i; + + ip0 = sa1111_readl(mapbase + SA1111_INTPOL0); + for (i = 0; i < 8; i++) { + sa1111_writel(ip0 ^ mask, mapbase + SA1111_INTPOL0); + sa1111_writel(ip0, mapbase + SA1111_INTPOL0); + if (sa1111_readl(mapbase + SA1111_INTSTATCLR1) & mask) + break; + } + + if (i == 8) + printk(KERN_ERR "Danger Will Robinson: failed to " + "re-trigger IRQ%d\n", irq); + return i == 8 ? -1 : 0; +} + +static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) +{ + unsigned int mask = SA1111_IRQMASK_LO(irq); + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long ip0; + + if (flags == IRQT_PROBE) + return 0; + + if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) + return -EINVAL; + + ip0 = sa1111_readl(mapbase + SA1111_INTPOL0); + if (flags & __IRQT_RISEDGE) + ip0 &= ~mask; + else + ip0 |= mask; + sa1111_writel(ip0, mapbase + SA1111_INTPOL0); + sa1111_writel(ip0, mapbase + SA1111_WAKEPOL0); + + return 0; +} + +static int sa1111_wake_lowirq(unsigned int irq, unsigned int on) +{ + unsigned int mask = SA1111_IRQMASK_LO(irq); + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long we0; + + we0 = sa1111_readl(mapbase + SA1111_WAKEEN0); + if (on) + we0 |= mask; + else + we0 &= ~mask; + sa1111_writel(we0, mapbase + SA1111_WAKEEN0); + + return 0; +} + +static struct irqchip sa1111_low_chip = { + .ack = sa1111_ack_irq, + .mask = sa1111_mask_lowirq, + .unmask = sa1111_unmask_lowirq, + .retrigger = sa1111_retrigger_lowirq, + .type = sa1111_type_lowirq, + .wake = sa1111_wake_lowirq, +}; + +static void sa1111_mask_highirq(unsigned int irq) +{ + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long ie1; + + ie1 = sa1111_readl(mapbase + SA1111_INTEN1); + ie1 &= ~SA1111_IRQMASK_HI(irq); + sa1111_writel(ie1, mapbase + SA1111_INTEN1); +} + +static void sa1111_unmask_highirq(unsigned int irq) +{ + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long ie1; + + ie1 = sa1111_readl(mapbase + SA1111_INTEN1); + ie1 |= SA1111_IRQMASK_HI(irq); + sa1111_writel(ie1, mapbase + SA1111_INTEN1); +} + +/* + * Attempt to re-trigger the interrupt. The SA1111 contains a register + * (INTSET) which claims to do this. However, in practice no amount of + * manipulation of INTEN and INTSET guarantees that the interrupt will + * be triggered. In fact, its very difficult, if not impossible to get + * INTSET to re-trigger the interrupt. + */ +static int sa1111_retrigger_highirq(unsigned int irq) +{ + unsigned int mask = SA1111_IRQMASK_HI(irq); + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long ip1; + int i; + + ip1 = sa1111_readl(mapbase + SA1111_INTPOL1); + for (i = 0; i < 8; i++) { + sa1111_writel(ip1 ^ mask, mapbase + SA1111_INTPOL1); + sa1111_writel(ip1, mapbase + SA1111_INTPOL1); + if (sa1111_readl(mapbase + SA1111_INTSTATCLR1) & mask) + break; + } + + if (i == 8) + printk(KERN_ERR "Danger Will Robinson: failed to " + "re-trigger IRQ%d\n", irq); + return i == 8 ? -1 : 0; +} + +static int sa1111_type_highirq(unsigned int irq, unsigned int flags) +{ + unsigned int mask = SA1111_IRQMASK_HI(irq); + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long ip1; + + if (flags == IRQT_PROBE) + return 0; + + if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) + return -EINVAL; + + ip1 = sa1111_readl(mapbase + SA1111_INTPOL1); + if (flags & __IRQT_RISEDGE) + ip1 &= ~mask; + else + ip1 |= mask; + sa1111_writel(ip1, mapbase + SA1111_INTPOL1); + sa1111_writel(ip1, mapbase + SA1111_WAKEPOL1); + + return 0; +} + +static int sa1111_wake_highirq(unsigned int irq, unsigned int on) +{ + unsigned int mask = SA1111_IRQMASK_HI(irq); + void __iomem *mapbase = get_irq_chipdata(irq); + unsigned long we1; + + we1 = sa1111_readl(mapbase + SA1111_WAKEEN1); + if (on) + we1 |= mask; + else + we1 &= ~mask; + sa1111_writel(we1, mapbase + SA1111_WAKEEN1); + + return 0; +} + +static struct irqchip sa1111_high_chip = { + .ack = sa1111_ack_irq, + .mask = sa1111_mask_highirq, + .unmask = sa1111_unmask_highirq, + .retrigger = sa1111_retrigger_highirq, + .type = sa1111_type_highirq, + .wake = sa1111_wake_highirq, +}; + +static void sa1111_setup_irq(struct sa1111 *sachip) +{ + void __iomem *irqbase = sachip->base + SA1111_INTC; + unsigned int irq; + + /* + * We're guaranteed that this region hasn't been taken. + */ + request_mem_region(sachip->phys + SA1111_INTC, 512, "irq"); + + /* disable all IRQs */ + sa1111_writel(0, irqbase + SA1111_INTEN0); + sa1111_writel(0, irqbase + SA1111_INTEN1); + sa1111_writel(0, irqbase + SA1111_WAKEEN0); + sa1111_writel(0, irqbase + SA1111_WAKEEN1); + + /* + * detect on rising edge. Note: Feb 2001 Errata for SA1111 + * specifies that S0ReadyInt and S1ReadyInt should be '1'. + */ + sa1111_writel(0, irqbase + SA1111_INTPOL0); + sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) | + SA1111_IRQMASK_HI(IRQ_S1_READY_NINT), + irqbase + SA1111_INTPOL1); + + /* clear all IRQs */ + sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); + sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); + + for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { + set_irq_chip(irq, &sa1111_low_chip); + set_irq_chipdata(irq, irqbase); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { + set_irq_chip(irq, &sa1111_high_chip); + set_irq_chipdata(irq, irqbase); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + /* + * Register SA1111 interrupt + */ + set_irq_type(sachip->irq, IRQT_RISING); + set_irq_data(sachip->irq, irqbase); + set_irq_chained_handler(sachip->irq, sa1111_irq_handler); +} + +/* + * Bring the SA1111 out of reset. This requires a set procedure: + * 1. nRESET asserted (by hardware) + * 2. CLK turned on from SA1110 + * 3. nRESET deasserted + * 4. VCO turned on, PLL_BYPASS turned off + * 5. Wait lock time, then assert RCLKEn + * 7. PCR set to allow clocking of individual functions + * + * Until we've done this, the only registers we can access are: + * SBI_SKCR + * SBI_SMCR + * SBI_SKID + */ +static void sa1111_wake(struct sa1111 *sachip) +{ + unsigned long flags, r; + + spin_lock_irqsave(&sachip->lock, flags); + +#ifdef CONFIG_ARCH_SA1100 + /* + * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: + * (SA-1110 Developer's Manual, section 9.1.2.1) + */ + GAFR |= GPIO_32_768kHz; + GPDR |= GPIO_32_768kHz; + TUCR = TUCR_3_6864MHz; +#elif CONFIG_ARCH_PXA + pxa_gpio_mode(GPIO11_3_6MHz_MD); +#else +#error missing clock setup +#endif + + /* + * Turn VCO on, and disable PLL Bypass. + */ + r = sa1111_readl(sachip->base + SA1111_SKCR); + r &= ~SKCR_VCO_OFF; + sa1111_writel(r, sachip->base + SA1111_SKCR); + r |= SKCR_PLL_BYPASS | SKCR_OE_EN; + sa1111_writel(r, sachip->base + SA1111_SKCR); + + /* + * Wait lock time. SA1111 manual _doesn't_ + * specify a figure for this! We choose 100us. + */ + udelay(100); + + /* + * Enable RCLK. We also ensure that RDYEN is set. + */ + r |= SKCR_RCLKEN | SKCR_RDYEN; + sa1111_writel(r, sachip->base + SA1111_SKCR); + + /* + * Wait 14 RCLK cycles for the chip to finish coming out + * of reset. (RCLK=24MHz). This is 590ns. + */ + udelay(1); + + /* + * Ensure all clocks are initially off. + */ + sa1111_writel(0, sachip->base + SA1111_SKPCR); + + spin_unlock_irqrestore(&sachip->lock, flags); +} + +#ifdef CONFIG_ARCH_SA1100 + +static u32 sa1111_dma_mask[] = { + ~0, + ~(1 << 20), + ~(1 << 23), + ~(1 << 24), + ~(1 << 25), + ~(1 << 20), + ~(1 << 20), + 0, +}; + +/* + * Configure the SA1111 shared memory controller. + */ +void +sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, + unsigned int cas_latency) +{ + unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC); + + if (cas_latency == 3) + smcr |= SMCR_CLAT; + + sa1111_writel(smcr, sachip->base + SA1111_SMCR); + + /* + * Now clear the bits in the DMA mask to work around the SA1111 + * DMA erratum (Intel StrongARM SA-1111 Microprocessor Companion + * Chip Specification Update, June 2000, Erratum #7). + */ + if (sachip->dev->dma_mask) + *sachip->dev->dma_mask &= sa1111_dma_mask[drac >> 2]; + + sachip->dev->coherent_dma_mask &= sa1111_dma_mask[drac >> 2]; +} + +#endif + +static void sa1111_dev_release(struct device *_dev) +{ + struct sa1111_dev *dev = SA1111_DEV(_dev); + + release_resource(&dev->res); + kfree(dev); +} + +static int +sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, + struct sa1111_dev_info *info) +{ + struct sa1111_dev *dev; + int ret; + + dev = kmalloc(sizeof(struct sa1111_dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto out; + } + memset(dev, 0, sizeof(struct sa1111_dev)); + + snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), + "%4.4lx", info->offset); + + dev->devid = info->devid; + dev->dev.parent = sachip->dev; + dev->dev.bus = &sa1111_bus_type; + dev->dev.release = sa1111_dev_release; + dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask; + dev->res.start = sachip->phys + info->offset; + dev->res.end = dev->res.start + 511; + dev->res.name = dev->dev.bus_id; + dev->res.flags = IORESOURCE_MEM; + dev->mapbase = sachip->base + info->offset; + dev->skpcr_mask = info->skpcr_mask; + memmove(dev->irq, info->irq, sizeof(dev->irq)); + + ret = request_resource(parent, &dev->res); + if (ret) { + printk("SA1111: failed to allocate resource for %s\n", + dev->res.name); + kfree(dev); + goto out; + } + + + ret = device_register(&dev->dev); + if (ret) { + release_resource(&dev->res); + kfree(dev); + goto out; + } + + /* + * If the parent device has a DMA mask associated with it, + * propagate it down to the children. + */ + if (sachip->dev->dma_mask) { + dev->dma_mask = *sachip->dev->dma_mask; + dev->dev.dma_mask = &dev->dma_mask; + + if (dev->dma_mask != 0xffffffffUL) { + ret = dmabounce_register_dev(&dev->dev, 1024, 4096); + if (ret) { + printk("SA1111: Failed to register %s with dmabounce", dev->dev.bus_id); + device_unregister(&dev->dev); + } + } + } + +out: + return ret; +} + +/** + * sa1111_probe - probe for a single SA1111 chip. + * @phys_addr: physical address of device. + * + * Probe for a SA1111 chip. This must be called + * before any other SA1111-specific code. + * + * Returns: + * %-ENODEV device not found. + * %-EBUSY physical address already marked in-use. + * %0 successful. + */ +static int +__sa1111_probe(struct device *me, struct resource *mem, int irq) +{ + struct sa1111 *sachip; + unsigned long id; + unsigned int has_devs, val; + int i, ret = -ENODEV; + + sachip = kmalloc(sizeof(struct sa1111), GFP_KERNEL); + if (!sachip) + return -ENOMEM; + + memset(sachip, 0, sizeof(struct sa1111)); + + spin_lock_init(&sachip->lock); + + sachip->dev = me; + dev_set_drvdata(sachip->dev, sachip); + + sachip->phys = mem->start; + sachip->irq = irq; + + /* + * Map the whole region. This also maps the + * registers for our children. + */ + sachip->base = ioremap(mem->start, PAGE_SIZE * 2); + if (!sachip->base) { + ret = -ENOMEM; + goto out; + } + + /* + * Probe for the chip. Only touch the SBI registers. + */ + id = sa1111_readl(sachip->base + SA1111_SKID); + if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { + printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id); + ret = -ENODEV; + goto unmap; + } + + printk(KERN_INFO "SA1111 Microprocessor Companion Chip: " + "silicon revision %lx, metal revision %lx\n", + (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK)); + + /* + * We found it. Wake the chip up, and initialise. + */ + sa1111_wake(sachip); + +#ifdef CONFIG_ARCH_SA1100 + /* + * The SDRAM configuration of the SA1110 and the SA1111 must + * match. This is very important to ensure that SA1111 accesses + * don't corrupt the SDRAM. Note that this ungates the SA1111's + * MBGNT signal, so we must have called sa1110_mb_disable() + * beforehand. + */ + sa1111_configure_smc(sachip, 1, + FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), + FExtr(MDCNFG, MDCNFG_SA1110_TDL0)); + + /* + * We only need to turn on DCLK whenever we want to use the + * DMA. It can otherwise be held firmly in the off position. + * (currently, we always enable it.) + */ + val = sa1111_readl(sachip->base + SA1111_SKPCR); + sa1111_writel(val | SKPCR_DCLKEN, sachip->base + SA1111_SKPCR); + + /* + * Enable the SA1110 memory bus request and grant signals. + */ + sa1110_mb_enable(); +#endif + + /* + * The interrupt controller must be initialised before any + * other device to ensure that the interrupts are available. + */ + if (sachip->irq != NO_IRQ) + sa1111_setup_irq(sachip); + + g_sa1111 = sachip; + + has_devs = ~0; + if (machine_is_assabet() || machine_is_jornada720() || + machine_is_badge4()) + has_devs &= ~(1 << 4); + else + has_devs &= ~(1 << 1); + + for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) + if (has_devs & (1 << i)) + sa1111_init_one_child(sachip, mem, &sa1111_devices[i]); + + return 0; + + unmap: + iounmap(sachip->base); + out: + kfree(sachip); + return ret; +} + +static void __sa1111_remove(struct sa1111 *sachip) +{ + struct list_head *l, *n; + void __iomem *irqbase = sachip->base + SA1111_INTC; + + list_for_each_safe(l, n, &sachip->dev->children) { + struct device *d = list_to_dev(l); + + device_unregister(d); + } + + /* disable all IRQs */ + sa1111_writel(0, irqbase + SA1111_INTEN0); + sa1111_writel(0, irqbase + SA1111_INTEN1); + sa1111_writel(0, irqbase + SA1111_WAKEEN0); + sa1111_writel(0, irqbase + SA1111_WAKEEN1); + + if (sachip->irq != NO_IRQ) { + set_irq_chained_handler(sachip->irq, NULL); + set_irq_data(sachip->irq, NULL); + + release_mem_region(sachip->phys + SA1111_INTC, 512); + } + + iounmap(sachip->base); + kfree(sachip); +} + +/* + * According to the "Intel StrongARM SA-1111 Microprocessor Companion + * Chip Specification Update" (June 2000), erratum #7, there is a + * significant bug in the SA1111 SDRAM shared memory controller. If + * an access to a region of memory above 1MB relative to the bank base, + * it is important that address bit 10 _NOT_ be asserted. Depending + * on the configuration of the RAM, bit 10 may correspond to one + * of several different (processor-relative) address bits. + * + * This routine only identifies whether or not a given DMA address + * is susceptible to the bug. + * + * This should only get called for sa1111_device types due to the + * way we configure our device dma_masks. + */ +int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) +{ + /* + * Section 4.6 of the "Intel StrongARM SA-1111 Development Module + * User's Guide" mentions that jumpers R51 and R52 control the + * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or + * SDRAM bank 1 on Neponset). The default configuration selects + * Assabet, so any address in bank 1 is necessarily invalid. + */ + return ((machine_is_assabet() || machine_is_pfs168()) && + (addr >= 0xc8000000 || (addr + size) >= 0xc8000000)); +} + +struct sa1111_save_data { + unsigned int skcr; + unsigned int skpcr; + unsigned int skcdr; + unsigned char skaud; + unsigned char skpwm0; + unsigned char skpwm1; + + /* + * Interrupt controller + */ + unsigned int intpol0; + unsigned int intpol1; + unsigned int inten0; + unsigned int inten1; + unsigned int wakepol0; + unsigned int wakepol1; + unsigned int wakeen0; + unsigned int wakeen1; +}; + +#ifdef CONFIG_PM + +static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level) +{ + struct sa1111 *sachip = dev_get_drvdata(dev); + struct sa1111_save_data *save; + unsigned long flags; + unsigned int val; + void __iomem *base; + + if (level != SUSPEND_DISABLE) + return 0; + + save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL); + if (!save) + return -ENOMEM; + dev->power.saved_state = save; + + spin_lock_irqsave(&sachip->lock, flags); + + /* + * Save state. + */ + base = sachip->base; + save->skcr = sa1111_readl(base + SA1111_SKCR); + save->skpcr = sa1111_readl(base + SA1111_SKPCR); + save->skcdr = sa1111_readl(base + SA1111_SKCDR); + save->skaud = sa1111_readl(base + SA1111_SKAUD); + save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); + save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); + + base = sachip->base + SA1111_INTC; + save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); + save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); + save->inten0 = sa1111_readl(base + SA1111_INTEN0); + save->inten1 = sa1111_readl(base + SA1111_INTEN1); + save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0); + save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1); + save->wakeen0 = sa1111_readl(base + SA1111_WAKEEN0); + save->wakeen1 = sa1111_readl(base + SA1111_WAKEEN1); + + /* + * Disable. + */ + val = sa1111_readl(sachip->base + SA1111_SKCR); + sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR); + sa1111_writel(0, sachip->base + SA1111_SKPWM0); + sa1111_writel(0, sachip->base + SA1111_SKPWM1); + + spin_unlock_irqrestore(&sachip->lock, flags); + + return 0; +} + +/* + * sa1111_resume - Restore the SA1111 device state. + * @dev: device to restore + * @level: resume level + * + * Restore the general state of the SA1111; clock control and + * interrupt controller. Other parts of the SA1111 must be + * restored by their respective drivers, and must be called + * via LDM after this function. + */ +static int sa1111_resume(struct device *dev, u32 level) +{ + struct sa1111 *sachip = dev_get_drvdata(dev); + struct sa1111_save_data *save; + unsigned long flags, id; + void __iomem *base; + + if (level != RESUME_ENABLE) + return 0; + + save = (struct sa1111_save_data *)dev->power.saved_state; + if (!save) + return 0; + + spin_lock_irqsave(&sachip->lock, flags); + + /* + * Ensure that the SA1111 is still here. + * FIXME: shouldn't do this here. + */ + id = sa1111_readl(sachip->base + SA1111_SKID); + if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { + __sa1111_remove(sachip); + dev_set_drvdata(dev, NULL); + kfree(save); + return 0; + } + + /* + * First of all, wake up the chip. + */ + sa1111_wake(sachip); + sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0); + sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1); + + base = sachip->base; + sa1111_writel(save->skcr, base + SA1111_SKCR); + sa1111_writel(save->skpcr, base + SA1111_SKPCR); + sa1111_writel(save->skcdr, base + SA1111_SKCDR); + sa1111_writel(save->skaud, base + SA1111_SKAUD); + sa1111_writel(save->skpwm0, base + SA1111_SKPWM0); + sa1111_writel(save->skpwm1, base + SA1111_SKPWM1); + + base = sachip->base + SA1111_INTC; + sa1111_writel(save->intpol0, base + SA1111_INTPOL0); + sa1111_writel(save->intpol1, base + SA1111_INTPOL1); + sa1111_writel(save->inten0, base + SA1111_INTEN0); + sa1111_writel(save->inten1, base + SA1111_INTEN1); + sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0); + sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1); + sa1111_writel(save->wakeen0, base + SA1111_WAKEEN0); + sa1111_writel(save->wakeen1, base + SA1111_WAKEEN1); + + spin_unlock_irqrestore(&sachip->lock, flags); + + dev->power.saved_state = NULL; + kfree(save); + + return 0; +} + +#else +#define sa1111_suspend NULL +#define sa1111_resume NULL +#endif + +static int sa1111_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct resource *mem; + int irq; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) + return -EINVAL; + irq = platform_get_irq(pdev, 0); + + return __sa1111_probe(dev, mem, irq); +} + +static int sa1111_remove(struct device *dev) +{ + struct sa1111 *sachip = dev_get_drvdata(dev); + + if (sachip) { + __sa1111_remove(sachip); + dev_set_drvdata(dev, NULL); + +#ifdef CONFIG_PM + kfree(dev->power.saved_state); + dev->power.saved_state = NULL; +#endif + } + + return 0; +} + +/* + * Not sure if this should be on the system bus or not yet. + * We really want some way to register a system device at + * the per-machine level, and then have this driver pick + * up the registered devices. + * + * We also need to handle the SDRAM configuration for + * PXA250/SA1110 machine classes. + */ +static struct device_driver sa1111_device_driver = { + .name = "sa1111", + .bus = &platform_bus_type, + .probe = sa1111_probe, + .remove = sa1111_remove, + .suspend = sa1111_suspend, + .resume = sa1111_resume, +}; + +/* + * Get the parent device driver (us) structure + * from a child function device + */ +static inline struct sa1111 *sa1111_chip_driver(struct sa1111_dev *sadev) +{ + return (struct sa1111 *)dev_get_drvdata(sadev->dev.parent); +} + +/* + * The bits in the opdiv field are non-linear. + */ +static unsigned char opdiv_table[] = { 1, 4, 2, 8 }; + +static unsigned int __sa1111_pll_clock(struct sa1111 *sachip) +{ + unsigned int skcdr, fbdiv, ipdiv, opdiv; + + skcdr = sa1111_readl(sachip->base + SA1111_SKCDR); + + fbdiv = (skcdr & 0x007f) + 2; + ipdiv = ((skcdr & 0x0f80) >> 7) + 2; + opdiv = opdiv_table[(skcdr & 0x3000) >> 12]; + + return 3686400 * fbdiv / (ipdiv * opdiv); +} + +/** + * sa1111_pll_clock - return the current PLL clock frequency. + * @sadev: SA1111 function block + * + * BUG: we should look at SKCR. We also blindly believe that + * the chip is being fed with the 3.6864MHz clock. + * + * Returns the PLL clock in Hz. + */ +unsigned int sa1111_pll_clock(struct sa1111_dev *sadev) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + + return __sa1111_pll_clock(sachip); +} + +/** + * sa1111_select_audio_mode - select I2S or AC link mode + * @sadev: SA1111 function block + * @mode: One of %SA1111_AUDIO_ACLINK or %SA1111_AUDIO_I2S + * + * Frob the SKCR to select AC Link mode or I2S mode for + * the audio block. + */ +void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&sachip->lock, flags); + + val = sa1111_readl(sachip->base + SA1111_SKCR); + if (mode == SA1111_AUDIO_I2S) { + val &= ~SKCR_SELAC; + } else { + val |= SKCR_SELAC; + } + sa1111_writel(val, sachip->base + SA1111_SKCR); + + spin_unlock_irqrestore(&sachip->lock, flags); +} + +/** + * sa1111_set_audio_rate - set the audio sample rate + * @sadev: SA1111 SAC function block + * @rate: sample rate to select + */ +int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned int div; + + if (sadev->devid != SA1111_DEVID_SAC) + return -EINVAL; + + div = (__sa1111_pll_clock(sachip) / 256 + rate / 2) / rate; + if (div == 0) + div = 1; + if (div > 128) + div = 128; + + sa1111_writel(div - 1, sachip->base + SA1111_SKAUD); + + return 0; +} + +/** + * sa1111_get_audio_rate - get the audio sample rate + * @sadev: SA1111 SAC function block device + */ +int sa1111_get_audio_rate(struct sa1111_dev *sadev) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long div; + + if (sadev->devid != SA1111_DEVID_SAC) + return -EINVAL; + + div = sa1111_readl(sachip->base + SA1111_SKAUD) + 1; + + return __sa1111_pll_clock(sachip) / (256 * div); +} + +void sa1111_set_io_dir(struct sa1111_dev *sadev, + unsigned int bits, unsigned int dir, + unsigned int sleep_dir) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + void __iomem *gpio = sachip->base + SA1111_GPIO; + +#define MODIFY_BITS(port, mask, dir) \ + if (mask) { \ + val = sa1111_readl(port); \ + val &= ~(mask); \ + val |= (dir) & (mask); \ + sa1111_writel(val, port); \ + } + + spin_lock_irqsave(&sachip->lock, flags); + MODIFY_BITS(gpio + SA1111_GPIO_PADDR, bits & 15, dir); + MODIFY_BITS(gpio + SA1111_GPIO_PBDDR, (bits >> 8) & 255, dir >> 8); + MODIFY_BITS(gpio + SA1111_GPIO_PCDDR, (bits >> 16) & 255, dir >> 16); + + MODIFY_BITS(gpio + SA1111_GPIO_PASDR, bits & 15, sleep_dir); + MODIFY_BITS(gpio + SA1111_GPIO_PBSDR, (bits >> 8) & 255, sleep_dir >> 8); + MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + void __iomem *gpio = sachip->base + SA1111_GPIO; + + spin_lock_irqsave(&sachip->lock, flags); + MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v); + MODIFY_BITS(gpio + SA1111_GPIO_PBDWR, (bits >> 8) & 255, v >> 8); + MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + void __iomem *gpio = sachip->base + SA1111_GPIO; + + spin_lock_irqsave(&sachip->lock, flags); + MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v); + MODIFY_BITS(gpio + SA1111_GPIO_PBSSR, (bits >> 8) & 255, v >> 8); + MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +/* + * Individual device operations. + */ + +/** + * sa1111_enable_device - enable an on-chip SA1111 function block + * @sadev: SA1111 function block device to enable + */ +void sa1111_enable_device(struct sa1111_dev *sadev) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&sachip->lock, flags); + val = sa1111_readl(sachip->base + SA1111_SKPCR); + sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +/** + * sa1111_disable_device - disable an on-chip SA1111 function block + * @sadev: SA1111 function block device to disable + */ +void sa1111_disable_device(struct sa1111_dev *sadev) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&sachip->lock, flags); + val = sa1111_readl(sachip->base + SA1111_SKPCR); + sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +/* + * SA1111 "Register Access Bus." + * + * We model this as a regular bus type, and hang devices directly + * off this. + */ +static int sa1111_match(struct device *_dev, struct device_driver *_drv) +{ + struct sa1111_dev *dev = SA1111_DEV(_dev); + struct sa1111_driver *drv = SA1111_DRV(_drv); + + return dev->devid == drv->devid; +} + +static int sa1111_bus_suspend(struct device *dev, pm_message_t state) +{ + struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + int ret = 0; + + if (drv && drv->suspend) + ret = drv->suspend(sadev, state); + return ret; +} + +static int sa1111_bus_resume(struct device *dev) +{ + struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + int ret = 0; + + if (drv && drv->resume) + ret = drv->resume(sadev); + return ret; +} + +static int sa1111_bus_probe(struct device *dev) +{ + struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + int ret = -ENODEV; + + if (drv->probe) + ret = drv->probe(sadev); + return ret; +} + +static int sa1111_bus_remove(struct device *dev) +{ + struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_driver *drv = SA1111_DRV(dev->driver); + int ret = 0; + + if (drv->remove) + ret = drv->remove(sadev); + return ret; +} + +struct bus_type sa1111_bus_type = { + .name = "sa1111-rab", + .match = sa1111_match, + .suspend = sa1111_bus_suspend, + .resume = sa1111_bus_resume, +}; + +int sa1111_driver_register(struct sa1111_driver *driver) +{ + driver->drv.probe = sa1111_bus_probe; + driver->drv.remove = sa1111_bus_remove; + driver->drv.bus = &sa1111_bus_type; + return driver_register(&driver->drv); +} + +void sa1111_driver_unregister(struct sa1111_driver *driver) +{ + driver_unregister(&driver->drv); +} + +static int __init sa1111_init(void) +{ + int ret = bus_register(&sa1111_bus_type); + if (ret == 0) + driver_register(&sa1111_device_driver); + return ret; +} + +static void __exit sa1111_exit(void) +{ + driver_unregister(&sa1111_device_driver); + bus_unregister(&sa1111_bus_type); +} + +module_init(sa1111_init); +module_exit(sa1111_exit); + +MODULE_DESCRIPTION("Intel Corporation SA1111 core driver"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(sa1111_select_audio_mode); +EXPORT_SYMBOL(sa1111_set_audio_rate); +EXPORT_SYMBOL(sa1111_get_audio_rate); +EXPORT_SYMBOL(sa1111_set_io_dir); +EXPORT_SYMBOL(sa1111_set_io); +EXPORT_SYMBOL(sa1111_set_sleep_io); +EXPORT_SYMBOL(sa1111_enable_device); +EXPORT_SYMBOL(sa1111_disable_device); +EXPORT_SYMBOL(sa1111_pll_clock); +EXPORT_SYMBOL(sa1111_bus_type); +EXPORT_SYMBOL(sa1111_driver_register); +EXPORT_SYMBOL(sa1111_driver_unregister); diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c new file mode 100644 index 0000000..cfd0d3e --- /dev/null +++ b/arch/arm/common/scoop.c @@ -0,0 +1,176 @@ +/* + * Support code for the SCOOP interface found on various Sharp PDAs + * + * Copyright (c) 2004 Richard Purdie + * + * Based on code written by Sharp/Lineo for 2.4 kernels + * + * 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/device.h> +#include <asm/io.h> +#include <asm/hardware/scoop.h> + +#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) + +struct scoop_dev { + void *base; + spinlock_t scoop_lock; + u32 scoop_gpwr; +}; + +void reset_scoop(struct device *dev) +{ + struct scoop_dev *sdev = dev_get_drvdata(dev); + + SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100; // 00 + SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000; // 04 + SCOOP_REG(sdev->base,SCOOP_CPR) = 0x0000; // 0C + SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000; // 10 + SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000; // 18 + SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF; // 14 + SCOOP_REG(sdev->base,SCOOP_ISR) = 0x0000; // 1C + SCOOP_REG(sdev->base,SCOOP_IRM) = 0x0000; +} + +unsigned short set_scoop_gpio(struct device *dev, unsigned short bit) +{ + unsigned short gpio_bit; + unsigned long flag; + struct scoop_dev *sdev = dev_get_drvdata(dev); + + spin_lock_irqsave(&sdev->scoop_lock, flag); + gpio_bit = SCOOP_REG(sdev->base, SCOOP_GPWR) | bit; + SCOOP_REG(sdev->base, SCOOP_GPWR) = gpio_bit; + spin_unlock_irqrestore(&sdev->scoop_lock, flag); + + return gpio_bit; +} + +unsigned short reset_scoop_gpio(struct device *dev, unsigned short bit) +{ + unsigned short gpio_bit; + unsigned long flag; + struct scoop_dev *sdev = dev_get_drvdata(dev); + + spin_lock_irqsave(&sdev->scoop_lock, flag); + gpio_bit = SCOOP_REG(sdev->base, SCOOP_GPWR) & ~bit; + SCOOP_REG(sdev->base,SCOOP_GPWR) = gpio_bit; + spin_unlock_irqrestore(&sdev->scoop_lock, flag); + + return gpio_bit; +} + +EXPORT_SYMBOL(set_scoop_gpio); +EXPORT_SYMBOL(reset_scoop_gpio); + +unsigned short read_scoop_reg(struct device *dev, unsigned short reg) +{ + struct scoop_dev *sdev = dev_get_drvdata(dev); + return SCOOP_REG(sdev->base,reg); +} + +void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data) +{ + struct scoop_dev *sdev = dev_get_drvdata(dev); + SCOOP_REG(sdev->base,reg)=data; +} + +EXPORT_SYMBOL(reset_scoop); +EXPORT_SYMBOL(read_scoop_reg); +EXPORT_SYMBOL(write_scoop_reg); + +#ifdef CONFIG_PM +static int scoop_suspend(struct device *dev, uint32_t state, uint32_t level) +{ + if (level == SUSPEND_POWER_DOWN) { + struct scoop_dev *sdev = dev_get_drvdata(dev); + + sdev->scoop_gpwr = SCOOP_REG(sdev->base,SCOOP_GPWR); + SCOOP_REG(sdev->base,SCOOP_GPWR) = 0; + } + return 0; +} + +static int scoop_resume(struct device *dev, uint32_t level) +{ + if (level == RESUME_POWER_ON) { + struct scoop_dev *sdev = dev_get_drvdata(dev); + + SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr; + } + return 0; +} +#else +#define scoop_suspend NULL +#define scoop_resume NULL +#endif + +int __init scoop_probe(struct device *dev) +{ + struct scoop_dev *devptr; + struct scoop_config *inf; + struct platform_device *pdev = to_platform_device(dev); + struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (!mem) + return -EINVAL; + + devptr = kmalloc(sizeof(struct scoop_dev), GFP_KERNEL); + + if (!devptr) + return -ENOMEM; + + memset(devptr, 0, sizeof(struct scoop_dev)); + spin_lock_init(&devptr->scoop_lock); + + inf = dev->platform_data; + devptr->base = ioremap(mem->start, mem->end - mem->start + 1); + + if (!devptr->base) { + kfree(devptr); + return -ENOMEM; + } + + dev_set_drvdata(dev, devptr); + + printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base); + + SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140; + reset_scoop(dev); + SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; + SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; + + return 0; +} + +static int scoop_remove(struct device *dev) +{ + struct scoop_dev *sdev = dev_get_drvdata(dev); + if (sdev) { + iounmap(sdev->base); + kfree(sdev); + dev_set_drvdata(dev, NULL); + } + return 0; +} + +static struct device_driver scoop_driver = { + .name = "sharp-scoop", + .bus = &platform_bus_type, + .probe = scoop_probe, + .remove = scoop_remove, + .suspend = scoop_suspend, + .resume = scoop_resume, +}; + +int __init scoop_init(void) +{ + return driver_register(&scoop_driver); +} + +subsys_initcall(scoop_init); diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c new file mode 100644 index 0000000..c2c557a --- /dev/null +++ b/arch/arm/common/sharpsl_param.c @@ -0,0 +1,60 @@ +/* + * Hardware parameter area specific to Sharp SL series devices + * + * Copyright (c) 2005 Richard Purdie + * + * Based on Sharp's 2.4 kernel patches + * + * 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/string.h> +#include <asm/mach/sharpsl_param.h> + +/* + * Certain hardware parameters determined at the time of device manufacture, + * typically including LCD parameters are loaded by the bootloader at the + * address PARAM_BASE. As the kernel will overwrite them, we need to store + * them early in the boot process, then pass them to the appropriate drivers. + * Not all devices use all paramaters but the format is common to all. + */ +#ifdef ARCH_SA1100 +#define PARAM_BASE 0xe8ffc000 +#else +#define PARAM_BASE 0xa0000a00 +#endif +#define MAGIC_CHG(a,b,c,d) ( ( d << 24 ) | ( c << 16 ) | ( b << 8 ) | a ) + +#define COMADJ_MAGIC MAGIC_CHG('C','M','A','D') +#define UUID_MAGIC MAGIC_CHG('U','U','I','D') +#define TOUCH_MAGIC MAGIC_CHG('T','U','C','H') +#define AD_MAGIC MAGIC_CHG('B','V','A','D') +#define PHAD_MAGIC MAGIC_CHG('P','H','A','D') + +struct sharpsl_param_info sharpsl_param; + +void sharpsl_save_param(void) +{ + memcpy(&sharpsl_param, (void *)PARAM_BASE, sizeof(struct sharpsl_param_info)); + + if (sharpsl_param.comadj_keyword != COMADJ_MAGIC) + sharpsl_param.comadj=-1; + + if (sharpsl_param.phad_keyword != PHAD_MAGIC) + sharpsl_param.phadadj=-1; + + if (sharpsl_param.uuid_keyword != UUID_MAGIC) + sharpsl_param.uuid[0]=-1; + + if (sharpsl_param.touch_keyword != TOUCH_MAGIC) + sharpsl_param.touch_xp=-1; + + if (sharpsl_param.adadj_keyword != AD_MAGIC) + sharpsl_param.adadj=-1; +} + + diff --git a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c new file mode 100644 index 0000000..486add8 --- /dev/null +++ b/arch/arm/common/time-acorn.c @@ -0,0 +1,96 @@ +/* + * linux/arch/arm/common/time-acorn.c + * + * Copyright (c) 1996-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. + * + * Changelog: + * 24-Sep-1996 RMK Created + * 10-Oct-1996 RMK Brought up to date with arch-sa110eval + * 04-Dec-1997 RMK Updated for new arch/arm/time.c + * 13=Jun-2004 DS Moved to arch/arm/common b/c shared w/CLPS7500 + */ +#include <linux/timex.h> +#include <linux/init.h> +#include <linux/interrupt.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/hardware/ioc.h> + +#include <asm/mach/time.h> + +unsigned long ioc_timer_gettimeoffset(void) +{ + unsigned int count1, count2, status; + long offset; + + ioc_writeb (0, IOC_T0LATCH); + barrier (); + count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); + barrier (); + status = ioc_readb(IOC_IRQREQA); + barrier (); + ioc_writeb (0, IOC_T0LATCH); + barrier (); + count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8); + + offset = count2; + if (count2 < count1) { + /* + * We have not had an interrupt between reading count1 + * and count2. + */ + if (status & (1 << 5)) + offset -= LATCH; + } else if (count2 > count1) { + /* + * We have just had another interrupt between reading + * count1 and count2. + */ + offset -= LATCH; + } + + offset = (LATCH - offset) * (tick_nsec / 1000); + return (offset + LATCH/2) / LATCH; +} + +void __init ioctime_init(void) +{ + ioc_writeb(LATCH & 255, IOC_T0LTCHL); + ioc_writeb(LATCH >> 8, IOC_T0LTCHH); + ioc_writeb(0, IOC_T0GO); +} + +static irqreturn_t +ioc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + timer_tick(regs); + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +static struct irqaction ioc_timer_irq = { + .name = "timer", + .flags = SA_INTERRUPT, + .handler = ioc_timer_interrupt +}; + +/* + * Set up timer interrupt. + */ +static void __init ioc_timer_init(void) +{ + ioctime_init(); + setup_irq(IRQ_TIMER, &ioc_timer_irq); +} + +struct sys_timer ioc_timer = { + .init = ioc_timer_init, + .offset = ioc_timer_gettimeoffset, +}; + diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c new file mode 100644 index 0000000..ef716a5 --- /dev/null +++ b/arch/arm/common/via82c505.c @@ -0,0 +1,94 @@ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/ptrace.h> +#include <linux/interrupt.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/ioport.h> + +#include <asm/io.h> +#include <asm/system.h> + +#include <asm/mach/pci.h> + +#define MAX_SLOTS 7 + +#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) + +static int +via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + outl(CONFIG_CMD(bus,devfn,where),0xCF8); + switch (size) { + case 1: + *value=inb(0xCFC + (where&3)); + break; + case 2: + *value=inw(0xCFC + (where&2)); + break; + case 4: + *value=inl(0xCFC); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int +via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + outl(CONFIG_CMD(bus,devfn,where),0xCF8); + switch (size) { + case 1: + outb(value, 0xCFC + (where&3)); + break; + case 2: + outw(value, 0xCFC + (where&2)); + break; + case 4: + outl(value, 0xCFC); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops via82c505_ops = { + .read = via82c505_read_config, + .write = via82c505_write_config, +}; + +void __init via82c505_preinit(void) +{ + printk(KERN_DEBUG "PCI: VIA 82c505\n"); + if (!request_region(0xA8,2,"via config")) { + printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n"); + return; + } + if (!request_region(0xCF8,8,"pci config")) { + printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n"); + release_region(0xA8, 2); + return; + } + + /* Enable compatible Mode */ + outb(0x96,0xA8); + outb(0x18,0xA9); + outb(0x93,0xA8); + outb(0xd0,0xA9); + +} + +int __init via82c505_setup(int nr, struct pci_sys_data *sys) +{ + return (nr == 0); +} + +struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata) +{ + if (nr == 0) + return pci_scan_bus(0, &via82c505_ops, sysdata); + + return NULL; +} diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig new file mode 100644 index 0000000..ccbb4c0 --- /dev/null +++ b/arch/arm/configs/assabet_defconfig @@ -0,0 +1,906 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.11 +# Wed Mar 9 13:13:30 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +CONFIG_SA1100_ASSABET=y +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_SA1100=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=32M console=ttySA0,38400n8 initrd=0xc0800000,3M root=/dev/ram" +# CONFIG_XIP_KERNEL is not set +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_SA1110=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_APM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRCOMM is not set +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +CONFIG_SA1100_FIR=m +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_TSDEV=y +CONFIG_INPUT_TSDEV_SCREEN_X=240 +CONFIG_INPUT_TSDEV_SCREEN_Y=320 +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=m +# CONFIG_SERIAL_8250_CS is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_SA1100=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +# CONFIG_USB is not set +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_VFAT_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig new file mode 100644 index 0000000..2b4059d --- /dev/null +++ b/arch/arm/configs/badge4_defconfig @@ -0,0 +1,1240 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sat Mar 26 21:32:26 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +CONFIG_SA1100_BADGE4=y +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +CONFIG_SA1111=y +CONFIG_DMABOUNCE=y +CONFIG_FORCE_MAX_ZONEORDER=9 + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="init=/linuxrc root=/dev/mtdblock3" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m +CONFIG_ARTHUR=m + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=0 +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +# CONFIG_PARPORT_PC is not set +CONFIG_PARPORT_NOT_PC=y +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=y +CONFIG_IRCOMM=y +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +CONFIG_SA1100_FIR=y +CONFIG_BT=m +CONFIG_BT_L2CAP=m +# CONFIG_BT_SCO is not set +# CONFIG_BT_RFCOMM is not set +# CONFIG_BT_BNEP is not set +# CONFIG_BT_HIDP is not set + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUSB=m +# CONFIG_BT_HCIUSB_SCO is not set +CONFIG_BT_HCIUART=m +# CONFIG_BT_HCIUART_H4 is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +CONFIG_BT_HCIVHCI=m +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set +CONFIG_MII=m + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_ATMEL is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_SA1100_WATCHDOG=m + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=m +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_ELEKTOR=m +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=y + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_OVCAMCHIP is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +CONFIG_USB_DEBUG=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_AUDIO=y + +# +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# +# CONFIG_USB_MIDI is not set +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DEBUG=y +# CONFIG_USB_STORAGE_RW_DETECT is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB Multimedia devices +# +CONFIG_USB_DABUSB=m +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +CONFIG_USB_PWC=m + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_USBNET=m + +# +# USB Host-to-Host Cables +# +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_GENESYS=y +CONFIG_USB_NET1080=y +CONFIG_USB_PL2301=y +CONFIG_USB_KC2190=y + +# +# Intelligent USB Devices/Gadgets +# +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_ZAURUS=y +CONFIG_USB_CDCETHER=y + +# +# USB Network Adapters +# +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_IPAQ is not set +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_TI is not set +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +CONFIG_USB_RIO500=m +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_TEST is not set + +# +# USB ATM/DSL drivers +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=m +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=m +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=m +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=y +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/bast_defconfig b/arch/arm/configs/bast_defconfig new file mode 100644 index 0000000..2d985e9 --- /dev/null +++ b/arch/arm/configs/bast_defconfig @@ -0,0 +1,952 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 02:24:16 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +CONFIG_ARCH_S3C2410=y +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# S3C24XX Implementations +# +CONFIG_ARCH_BAST=y +# CONFIG_ARCH_H1940 is not set +# CONFIG_MACH_N30 is not set +# CONFIG_ARCH_SMDK2410 is not set +# CONFIG_ARCH_S3C2440 is not set +CONFIG_MACH_VR1000=y +# CONFIG_MACH_RX3715 is not set +# CONFIG_MACH_OTOM is not set +# CONFIG_MACH_NEXCODER_2440 is not set +CONFIG_CPU_S3C2410=y + +# +# S3C2410 Boot +# +# CONFIG_S3C2410_BOOT_WATCHDOG is not set + +# +# S3C2410 Setup +# +CONFIG_S3C2410_DMA=y +# CONFIG_S3C2410_DMA_DEBUG is not set +# CONFIG_S3C2410_PM_DEBUG is not set +# CONFIG_S3C2410_PM_CHECK is not set +CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_APM=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MAP_BANK_WIDTH_16=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +CONFIG_MTD_BAST=y +CONFIG_MTD_BAST_MAXSIZE=4 + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=y +CONFIG_MTD_NAND_S3C2410=y +# CONFIG_MTD_NAND_S3C2410_DEBUG is not set +# CONFIG_MTD_NAND_S3C2410_HWECC is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +# CONFIG_PARPORT_PC is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDE_BAST=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_S3C2410=y +CONFIG_SERIAL_S3C2410_CONSOLE=y +CONFIG_SERIAL_BAST_SIO=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=y +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_S3C2410_WATCHDOG=y +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_S3C2410_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_S3C2410=y +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +CONFIG_SENSORS_LM75=m +# CONFIG_SENSORS_LM77 is not set +CONFIG_SENSORS_LM78=m +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +CONFIG_SENSORS_LM85=m +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=m +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SOFT_CURSOR is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS_FS=y +CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_JFFS_PROC_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_SOLARIS_X86_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C2410_PORT=y +CONFIG_DEBUG_S3C2410_UART=0 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig new file mode 100644 index 0000000..d8fe0f4 --- /dev/null +++ b/arch/arm/configs/cerfcube_defconfig @@ -0,0 +1,905 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 14:19:40 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +CONFIG_SA1100_CERF=y +# CONFIG_SA1100_CERF_FLASH_8MB is not set +CONFIG_SA1100_CERF_FLASH_16MB=y +# CONFIG_SA1100_CERF_FLASH_32MB is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m + +# +# PC-card bridges +# +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_SA1100=m + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttySA0,38400 root=/dev/mtdblock3 rootfstype=jffs2 rw mem=32M init=/linuxrc" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=m +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_SA1110=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +CONFIG_FPE_FASTFPE=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_APM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_SA1100_WATCHDOG=m + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=m +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=m +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=m +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/clps7500_defconfig b/arch/arm/configs/clps7500_defconfig new file mode 100644 index 0000000..9087583 --- /dev/null +++ b/arch/arm/configs/clps7500_defconfig @@ -0,0 +1,803 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 17:20:48 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_SYSCTL is not set +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +CONFIG_ARCH_CLPS7500=y +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM710=y +CONFIG_CPU_32v3=y +CONFIG_CPU_CACHE_V3=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V3=y +CONFIG_CPU_TLB_V3=y + +# +# Processor Features +# +CONFIG_TIMER_ACORN=y + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=16M root=nfs" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +CONFIG_CS89x0=y +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +CONFIG_SLIP=y +CONFIG_SLIP_COMPRESSED=y +# CONFIG_SLIP_SMART is not set +# CONFIG_SLIP_MODE_SLIP6 is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_RPCKBD=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_ACORN=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/ebsa110_defconfig b/arch/arm/configs/ebsa110_defconfig new file mode 100644 index 0000000..6f61929 --- /dev/null +++ b/arch/arm/configs/ebsa110_defconfig @@ -0,0 +1,749 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 18:29:48 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +CONFIG_ARCH_EBSA110=y +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA110=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WB=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m + +# +# PC-card bridges +# +CONFIG_I82365=m +# CONFIG_TCIC is not set +CONFIG_PCMCIA_PROBE=y +CONFIG_PCCARD_NONSTATIC=m + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +CONFIG_FPE_FASTFPE=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_PC_PCMCIA is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +CONFIG_IP_TCPDIAG_IPV6=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=y +CONFIG_IP_NF_IRC=y +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_LIMIT=y +CONFIG_IP_NF_MATCH_IPRANGE=y +CONFIG_IP_NF_MATCH_MAC=y +CONFIG_IP_NF_MATCH_PKTTYPE=y +CONFIG_IP_NF_MATCH_MARK=y +CONFIG_IP_NF_MATCH_MULTIPORT=y +CONFIG_IP_NF_MATCH_TOS=y +CONFIG_IP_NF_MATCH_RECENT=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_DSCP=y +CONFIG_IP_NF_MATCH_AH_ESP=y +CONFIG_IP_NF_MATCH_LENGTH=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_MATCH_TCPMSS=y +CONFIG_IP_NF_MATCH_HELPER=y +CONFIG_IP_NF_MATCH_STATE=y +CONFIG_IP_NF_MATCH_CONNTRACK=y +# CONFIG_IP_NF_MATCH_OWNER is not set +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_REALM is not set +# CONFIG_IP_NF_MATCH_SCTP is not set +# CONFIG_IP_NF_MATCH_COMMENT is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_LOG=y +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_SAME=y +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=y +CONFIG_IP_NF_NAT_FTP=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_TARGET_TOS=y +CONFIG_IP_NF_TARGET_ECN=y +CONFIG_IP_NF_TARGET_DSCP=y +CONFIG_IP_NF_TARGET_MARK=y +CONFIG_IP_NF_TARGET_CLASSIFY=y +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_LIMIT=y +CONFIG_IP6_NF_MATCH_MAC=y +CONFIG_IP6_NF_MATCH_RT=y +CONFIG_IP6_NF_MATCH_OPTS=y +CONFIG_IP6_NF_MATCH_FRAG=y +CONFIG_IP6_NF_MATCH_HL=y +CONFIG_IP6_NF_MATCH_MULTIPORT=y +# CONFIG_IP6_NF_MATCH_OWNER is not set +CONFIG_IP6_NF_MATCH_MARK=y +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +CONFIG_IP6_NF_MATCH_AHESP=y +CONFIG_IP6_NF_MATCH_LENGTH=y +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=y +# CONFIG_IP6_NF_TARGET_LOG is not set +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_TARGET_MARK=y +# CONFIG_IP6_NF_RAW is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_ARM_AM79C961A=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=m +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=y + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff --git a/arch/arm/configs/edb7211_defconfig b/arch/arm/configs/edb7211_defconfig new file mode 100644 index 0000000..78b08ed --- /dev/null +++ b/arch/arm/configs/edb7211_defconfig @@ -0,0 +1,575 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 21:48:12 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +CONFIG_ARCH_CLPS711X=y +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CEIVA is not set +# CONFIG_ARCH_CLEP7312 is not set +CONFIG_ARCH_EDB7211=y +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +CONFIG_ARCH_EP7211=y +# CONFIG_EP72XX_ROM_BOOT is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM720T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_LV4T=y +CONFIG_CPU_CACHE_V4=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WT=y +CONFIG_CPU_TLB_V4WT=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CLPS711X=y +CONFIG_SERIAL_CLPS711X_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig new file mode 100644 index 0000000..e8f9fcc --- /dev/null +++ b/arch/arm/configs/enp2611_defconfig @@ -0,0 +1,887 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:08:24 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_IXP2000=y +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP2400/2800 Implementation Options +# + +# +# IXP2400/2800 Platforms +# +CONFIG_ARCH_ENP2611=y +# CONFIG_ARCH_IXDP2400 is not set +# CONFIG_ARCH_IXDP2800 is not set +# CONFIG_ARCH_IXDP2401 is not set +# CONFIG_ARCH_IXDP2801 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=y +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP2000_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_IXP2000 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/ep80219_defconfig b/arch/arm/configs/ep80219_defconfig new file mode 100644 index 0000000..96342af --- /dev/null +++ b/arch/arm/configs/ep80219_defconfig @@ -0,0 +1,952 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:34:12 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# IOP3xx Implementation Options +# + +# +# IOP3xx Platform Types +# +# CONFIG_ARCH_IQ80321 is not set +CONFIG_ARCH_IQ31244=y +# CONFIG_ARCH_IQ80331 is not set +# CONFIG_MACH_IQ80332 is not set +CONFIG_ARCH_EP80219=y +CONFIG_ARCH_IOP321=y +# CONFIG_ARCH_IOP331 is not set + +# +# IOP3xx Chipset Features +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xf0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +# CONFIG_MD_LINEAR is not set +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/epxa10db_defconfig b/arch/arm/configs/epxa10db_defconfig new file mode 100644 index 0000000..9fb8b58 --- /dev/null +++ b/arch/arm/configs/epxa10db_defconfig @@ -0,0 +1,644 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:46:51 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +CONFIG_ARCH_CAMELOT=y +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Epxa10db +# + +# +# PLD hotswap support +# +CONFIG_PLD=y +# CONFIG_PLD_HOTSWAP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM922T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=32M console=ttyUA0,115200 initrd=0x00200000,8M root=/dev/ram0 rw" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_PPP_DEFLATE=y +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_UART00=y +CONFIG_SERIAL_UART00_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +CONFIG_SMB_FS=y +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=y +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig new file mode 100644 index 0000000..9737c48 --- /dev/null +++ b/arch/arm/configs/footbridge_defconfig @@ -0,0 +1,1257 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 23:02:24 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +CONFIG_ARCH_FOOTBRIDGE=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Footbridge Implementations +# +CONFIG_ARCH_CATS=y +CONFIG_ARCH_PERSONAL_SERVER=y +# CONFIG_ARCH_EBSA285_ADDIN is not set +CONFIG_ARCH_EBSA285_HOST=y +CONFIG_ARCH_NETWINDER=y +CONFIG_FOOTBRIDGE=y +CONFIG_FOOTBRIDGE_HOST=y +CONFIG_ARCH_EBSA285=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA110=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WB=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y +CONFIG_ISA_DMA=y +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_ISAPNP=y + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +CONFIG_PARIDE=m +CONFIG_PARIDE_PARPORT=y + +# +# Parallel IDE high-level drivers +# +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PT=m +CONFIG_PARIDE_PG=m + +# +# Parallel IDE protocol modules +# +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +# CONFIG_PARIDE_BPCK6 is not set +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPNP is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +CONFIG_ATM=y +# CONFIG_ATM_CLIP is not set +# CONFIG_ATM_LANE is not set +# CONFIG_ATM_BR2684 is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_NSC_FIR is not set +CONFIG_WINBOND_FIR=m +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_FIR is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_NET_SB1000 is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_EL3 is not set +# CONFIG_3C515 is not set +CONFIG_VORTEX=y +# CONFIG_TYPHOON is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +CONFIG_NE2K_PCI=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# ATM drivers +# +# CONFIG_ATM_TCP is not set +# CONFIG_ATM_LANAI is not set +# CONFIG_ATM_ENI is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_ZATM is not set +# CONFIG_ATM_NICSTAR is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_IA is not set +# CONFIG_ATM_FORE200E_MAYBE is not set +# CONFIG_ATM_HE is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m +# CONFIG_PPPOATM is not set +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_21285=y +CONFIG_SERIAL_21285_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=y +CONFIG_21285_WATCHDOG=m +CONFIG_977_WATCHDOG=m + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_DS1620=y +CONFIG_NWBUTTON=y +CONFIG_NWBUTTON_REBOOT=y +CONFIG_NWFLASH=m +CONFIG_NVRAM=m +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_SAA7134 is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_OVCAMCHIP is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_CADET is not set +# CONFIG_RADIO_RTRACK is not set +# CONFIG_RADIO_RTRACK2 is not set +# CONFIG_RADIO_AZTECH is not set +# CONFIG_RADIO_GEMTEK is not set +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_SF16FMI is not set +# CONFIG_RADIO_SF16FMR2 is not set +# CONFIG_RADIO_TERRATEC is not set +# CONFIG_RADIO_TRUST is not set +# CONFIG_RADIO_TYPHOON is not set +# CONFIG_RADIO_ZOLTRIX is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +CONFIG_FB_CYBER2000=y +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=m +CONFIG_USB_DEBUG=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_AUDIO=m +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +# CONFIG_USB_STORAGE is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=m + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_TEST is not set + +# +# USB ATM/DSL drivers +# +# CONFIG_USB_ATM is not set +# CONFIG_USB_SPEEDTOUCH is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +# CONFIG_ACORN_PARTITION_ICS is not set +CONFIG_ACORN_PARTITION_ADFS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +# CONFIG_ACORN_PARTITION_RISCIX is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff --git a/arch/arm/configs/fortunet_defconfig b/arch/arm/configs/fortunet_defconfig new file mode 100644 index 0000000..b6f688d --- /dev/null +++ b/arch/arm/configs/fortunet_defconfig @@ -0,0 +1,558 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 23:51:10 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +CONFIG_ARCH_CLPS711X=y +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CEIVA is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +CONFIG_ARCH_FORTUNET=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM720T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_LV4T=y +CONFIG_CPU_CACHE_V4=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WT=y +CONFIG_CPU_TLB_V4WT=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +CONFIG_FPE_FASTFPE=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +# CONFIG_INET is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_NETFILTER is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_NETDEVICES is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CLPS711X=y +CONFIG_SERIAL_CLPS711X_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS_FS=y +CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_JFFS_PROC_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig new file mode 100644 index 0000000..b4e297d --- /dev/null +++ b/arch/arm/configs/h3600_defconfig @@ -0,0 +1,913 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:02:26 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +CONFIG_SA1100_H3600=y +# CONFIG_SA1100_H3800 is not set +CONFIG_SA1100_H3XXX=y +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set +# CONFIG_H3600_SLEEVE is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_SA1100=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_APM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +CONFIG_SA1100_FIR=m +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=m +# CONFIG_SERIAL_8250_CS is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_SA1100=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/h7201_defconfig b/arch/arm/configs/h7201_defconfig new file mode 100644 index 0000000..39c13a3 --- /dev/null +++ b/arch/arm/configs/h7201_defconfig @@ -0,0 +1,567 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:11:33 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +CONFIG_ARCH_H720X=y + +# +# h720x Implementations +# +CONFIG_ARCH_H7201=y +# CONFIG_ARCH_H7202 is not set +CONFIG_CPU_H7201=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM720T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_LV4T=y +CONFIG_CPU_CACHE_V4=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WT=y +CONFIG_CPU_TLB_V4WT=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=0 +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_H720X is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +# CONFIG_NET is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/h7202_defconfig b/arch/arm/configs/h7202_defconfig new file mode 100644 index 0000000..fbf5c24 --- /dev/null +++ b/arch/arm/configs/h7202_defconfig @@ -0,0 +1,732 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:15:45 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +CONFIG_ARCH_H720X=y + +# +# h720x Implementations +# +# CONFIG_ARCH_H7201 is not set +CONFIG_ARCH_H7202=y +CONFIG_CPU_H7202=y +# CONFIG_H7202_SERIAL23 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM720T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_LV4T=y +CONFIG_CPU_CACHE_V4=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WT=y +CONFIG_CPU_TLB_V4WT=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,19200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +CONFIG_MTD_H720X=y + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SOFT_CURSOR is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=m +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_SA1100 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_ZERO=m +# CONFIG_USB_ETH is not set +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_FILE_STORAGE_TEST=y +CONFIG_USB_G_SERIAL=m + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +# CONFIG_ROOT_NFS is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig new file mode 100644 index 0000000..6987c8c --- /dev/null +++ b/arch/arm/configs/hackkit_defconfig @@ -0,0 +1,768 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:22:34 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +CONFIG_SA1100_HACKKIT=y +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttySA0,115200 root=/dev/ram0 initrd=0xc0400000,8M init=/rootshell" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=3 +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_ATMEL is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +CONFIG_DEBUG_SLAB=y +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig new file mode 100644 index 0000000..27ee768 --- /dev/null +++ b/arch/arm/configs/integrator_defconfig @@ -0,0 +1,864 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 21:14:51 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +CONFIG_ARCH_INTEGRATOR=y +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Integrator Options +# +CONFIG_ARCH_INTEGRATOR_AP=y +# CONFIG_ARCH_INTEGRATOR_CP is not set +# CONFIG_INTEGRATOR_IMPD1 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM720T=y +CONFIG_CPU_ARM920T=y +# CONFIG_CPU_ARM922T is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1022 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_ABRT_LV4T=y +CONFIG_CPU_CACHE_V4=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WT=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +CONFIG_ICST525=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp mem=32M" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_INTEGRATOR=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_APM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_AFS_PARTS=y + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_AMBA_PL010=y +CONFIG_SERIAL_AMBA_PL010_CONSOLE=y +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_FB_MATROX_G is not set +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/iq31244_defconfig b/arch/arm/configs/iq31244_defconfig new file mode 100644 index 0000000..e71443b --- /dev/null +++ b/arch/arm/configs/iq31244_defconfig @@ -0,0 +1,922 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 02:10:38 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# IOP3xx Implementation Options +# + +# +# IOP3xx Platform Types +# +# CONFIG_ARCH_IQ80321 is not set +CONFIG_ARCH_IQ31244=y +# CONFIG_ARCH_IQ80331 is not set +# CONFIG_MACH_IQ80332 is not set +# CONFIG_ARCH_EP80219 is not set +CONFIG_ARCH_IOP321=y +# CONFIG_ARCH_IOP331 is not set + +# +# IOP3xx Chipset Features +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xf0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +# CONFIG_MD_LINEAR is not set +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig new file mode 100644 index 0000000..ab5ad23 --- /dev/null +++ b/arch/arm/configs/iq80321_defconfig @@ -0,0 +1,843 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 13:24:10 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# IOP3xx Implementation Options +# + +# +# IOP3xx Platform Types +# +CONFIG_ARCH_IQ80321=y +# CONFIG_ARCH_IQ31244 is not set +# CONFIG_ARCH_IQ80331 is not set +# CONFIG_MACH_IQ80332 is not set +# CONFIG_ARCH_EP80219 is not set +CONFIG_ARCH_IOP321=y +# CONFIG_ARCH_IOP331 is not set + +# +# IOP3xx Chipset Features +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xf0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/iq80331_defconfig b/arch/arm/configs/iq80331_defconfig new file mode 100644 index 0000000..bb53613 --- /dev/null +++ b/arch/arm/configs/iq80331_defconfig @@ -0,0 +1,916 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 15:13:37 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# IOP3xx Implementation Options +# + +# +# IOP3xx Platform Types +# +# CONFIG_ARCH_IQ80321 is not set +# CONFIG_ARCH_IQ31244 is not set +CONFIG_ARCH_IQ80331=y +# CONFIG_MACH_IQ80332 is not set +# CONFIG_ARCH_EP80219 is not set +CONFIG_ARCH_IOP331=y + +# +# IOP3xx Chipset Features +# +CONFIG_IOP331_STEPD=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xc0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/iq80332_defconfig b/arch/arm/configs/iq80332_defconfig new file mode 100644 index 0000000..305f01f --- /dev/null +++ b/arch/arm/configs/iq80332_defconfig @@ -0,0 +1,916 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 17:33:39 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# IOP3xx Implementation Options +# + +# +# IOP3xx Platform Types +# +# CONFIG_ARCH_IQ80321 is not set +# CONFIG_ARCH_IQ31244 is not set +# CONFIG_ARCH_IQ80331 is not set +CONFIG_MACH_IQ80332=y +# CONFIG_ARCH_EP80219 is not set +CONFIG_ARCH_IOP331=y + +# +# IOP3xx Chipset Features +# +# CONFIG_IOP331_STEPD is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xc0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig new file mode 100644 index 0000000..4fd663e --- /dev/null +++ b/arch/arm/configs/ixdp2400_defconfig @@ -0,0 +1,888 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 21:13:38 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_IXP2000=y +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP2400/2800 Implementation Options +# + +# +# IXP2400/2800 Platforms +# +# CONFIG_ARCH_ENP2611 is not set +CONFIG_ARCH_IXDP2400=y +# CONFIG_ARCH_IXDP2800 is not set +CONFIG_ARCH_IXDP2X00=y +# CONFIG_ARCH_IXDP2401 is not set +# CONFIG_ARCH_IXDP2801 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=y +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP2000_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_IXP2000 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig new file mode 100644 index 0000000..6f51c98 --- /dev/null +++ b/arch/arm/configs/ixdp2401_defconfig @@ -0,0 +1,889 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 21:53:55 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_IXP2000=y +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP2400/2800 Implementation Options +# + +# +# IXP2400/2800 Platforms +# +# CONFIG_ARCH_ENP2611 is not set +# CONFIG_ARCH_IXDP2400 is not set +# CONFIG_ARCH_IXDP2800 is not set +CONFIG_ARCH_IXDP2401=y +# CONFIG_ARCH_IXDP2801 is not set +CONFIG_ARCH_IXDP2X01=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +CONFIG_CS89x0=y +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=y +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP2000_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_IXP2000 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig new file mode 100644 index 0000000..d36f991 --- /dev/null +++ b/arch/arm/configs/ixdp2800_defconfig @@ -0,0 +1,888 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:15:23 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_IXP2000=y +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP2400/2800 Implementation Options +# + +# +# IXP2400/2800 Platforms +# +# CONFIG_ARCH_ENP2611 is not set +# CONFIG_ARCH_IXDP2400 is not set +CONFIG_ARCH_IXDP2800=y +CONFIG_ARCH_IXDP2X00=y +# CONFIG_ARCH_IXDP2401 is not set +# CONFIG_ARCH_IXDP2801 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=y +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP2000_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_IXP2000 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig new file mode 100644 index 0000000..cd84a20 --- /dev/null +++ b/arch/arm/configs/ixdp2801_defconfig @@ -0,0 +1,889 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:39:19 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_IXP2000=y +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP2400/2800 Implementation Options +# + +# +# IXP2400/2800 Platforms +# +# CONFIG_ARCH_ENP2611 is not set +# CONFIG_ARCH_IXDP2400 is not set +# CONFIG_ARCH_IXDP2800 is not set +# CONFIG_ARCH_IXDP2401 is not set +CONFIG_ARCH_IXDP2801=y +CONFIG_ARCH_IXDP2X01=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware ixdp2x01_clock=50000000" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP2000=y +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +CONFIG_CS89x0=y +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=y +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=y +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP2000_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_IXP2000 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig new file mode 100644 index 0000000..94aafec --- /dev/null +++ b/arch/arm/configs/ixp4xx_defconfig @@ -0,0 +1,1164 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:53:40 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +CONFIG_ARCH_IXP4XX=y +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP4xx Implementation Options +# + +# +# IXP4xx Platforms +# +# CONFIG_ARCH_AVILA is not set +CONFIG_ARCH_ADI_COYOTE=y +CONFIG_ARCH_IXDP425=y +# CONFIG_MACH_IXDPG425 is not set +# CONFIG_MACH_IXDP465 is not set +CONFIG_ARCH_IXCDP1100=y +CONFIG_ARCH_PRPMC1100=y +CONFIG_ARCH_IXDP4XX=y +# CONFIG_MACH_GTWX5715 is not set + +# +# IXP4xx Options +# +# CONFIG_IXP4XX_INDIRECT_PCI is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y +CONFIG_DMABOUNCE=y + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp root=/dev/nfs" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_APM=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP4XX=y +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=m +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TUNNEL=m +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +# CONFIG_IP_VS_PROTO_TCP is not set +# CONFIG_IP_VS_PROTO_UDP is not set +# CONFIG_IP_VS_PROTO_ESP is not set +# CONFIG_IP_VS_PROTO_AH is not set + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +# CONFIG_IP_VS_SED is not set +# CONFIG_IP_VS_NQ is not set + +# +# IPVS application helper +# +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +# CONFIG_IP_NF_MATCH_IPRANGE is not set +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +# CONFIG_IP_NF_MATCH_HELPER is not set +CONFIG_IP_NF_MATCH_STATE=m +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +CONFIG_IP_NF_MATCH_OWNER=m +# CONFIG_IP_NF_MATCH_PHYSDEV is not set +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_REALM is not set +# CONFIG_IP_NF_MATCH_SCTP is not set +# CONFIG_IP_NF_MATCH_COMMENT is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_SAME is not set +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +# CONFIG_IP_NF_TARGET_CLASSIFY is not set +# CONFIG_IP_NF_RAW is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +# CONFIG_IP_NF_ARP_MANGLE is not set + +# +# Bridge: Netfilter Configuration +# +# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +CONFIG_ATM=y +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=y +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +CONFIG_X25=m +CONFIG_LAPB=m +# CONFIG_NET_DIVERT is not set +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_WAN_ROUTER=m + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_ATM is not set +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +# CONFIG_NET_SCH_NETEM is not set +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +# CONFIG_NET_CLS_BASIC is not set +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +# CONFIG_NET_CLS_IND is not set +# CONFIG_CLS_U32_MARK is not set +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +CONFIG_EEPRO100=y +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_HERMES=y +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +CONFIG_PCI_HERMES=y +# CONFIG_ATMEL is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_DSCC4 is not set +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=m +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y +CONFIG_HDLC_X25=y +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=m +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +CONFIG_WAN_ROUTER_DRIVERS=y +# CONFIG_CYCLADES_SYNC is not set +# CONFIG_LAPBETHER is not set +# CONFIG_X25_ASY is not set + +# +# ATM drivers +# +CONFIG_ATM_TCP=m +# CONFIG_ATM_LANAI is not set +# CONFIG_ATM_ENI is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_ZATM is not set +# CONFIG_ATM_NICSTAR is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_IA is not set +# CONFIG_ATM_FORE200E_MAYBE is not set +# CONFIG_ATM_HE is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP4XX_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_IOP3XX is not set +# CONFIG_I2C_ISA is not set +CONFIG_I2C_IXP4XX=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig new file mode 100644 index 0000000..b88aeba --- /dev/null +++ b/arch/arm/configs/jornada720_defconfig @@ -0,0 +1,919 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 23:10:35 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +CONFIG_SA1100_JORNADA720=y +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +CONFIG_SA1111=y +CONFIG_DMABOUNCE=y +CONFIG_FORCE_MAX_ZONEORDER=9 + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +CONFIG_I82365=y +# CONFIG_TCIC is not set +CONFIG_PCMCIA_SA1100=y +# CONFIG_PCMCIA_SA1111 is not set +CONFIG_PCCARD_NONSTATIC=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="keepinitrd mem=32M" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +CONFIG_FPE_FASTFPE=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=m +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_APM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=1 +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +CONFIG_SA1100_FIR=m +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set +CONFIG_MII=m + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +CONFIG_ARLAN=m +CONFIG_WAVELAN=m +CONFIG_PCMCIA_WAVELAN=m +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_HERMES=m +# CONFIG_ATMEL is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +CONFIG_AIRO_CS=m +# CONFIG_PCMCIA_WL3501 is not set +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_SA1111 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SOFT_CURSOR is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +CONFIG_DEVFS_DEBUG=y +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=2 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +CONFIG_DEBUG_SLAB=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig new file mode 100644 index 0000000..7033829 --- /dev/null +++ b/arch/arm/configs/lart_defconfig @@ -0,0 +1,877 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 23:53:24 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +CONFIG_SA1100_LART=y +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_LEDS=y +# CONFIG_LEDS_TIMER is not set +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_SA1100=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_APM=m + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=1 +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +CONFIG_MTD_LART=y +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=m +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +# CONFIG_IRDA_FAST_RR is not set +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +CONFIG_SA1100_FIR=m +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +# CONFIG_PPPOE is not set +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +# CONFIG_SLIP_SMART is not set +# CONFIG_SLIP_MODE_SLIP6 is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=1 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=m +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff --git a/arch/arm/configs/lpd7a400_defconfig b/arch/arm/configs/lpd7a400_defconfig new file mode 100644 index 0000000..d64706d --- /dev/null +++ b/arch/arm/configs/lpd7a400_defconfig @@ -0,0 +1,781 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:06:33 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +CONFIG_ARCH_LH7A40X=y +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# LH7A40X Implementations +# +# CONFIG_MACH_KEV7A400 is not set +CONFIG_MACH_LPD7A400=y +# CONFIG_MACH_LPD7A404 is not set +CONFIG_ARCH_LH7A400=y +# CONFIG_LH7A40X_CONTIGMEM is not set +# CONFIG_LH7A40X_ONE_BANK_PER_NODE is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM922T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +CONFIG_DISCONTIGMEM=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_LH7A40X=y +CONFIG_SERIAL_LH7A40X_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig new file mode 100644 index 0000000..87cbedf --- /dev/null +++ b/arch/arm/configs/lpd7a404_defconfig @@ -0,0 +1,919 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:14:08 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +CONFIG_ARCH_LH7A40X=y +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# LH7A40X Implementations +# +# CONFIG_MACH_KEV7A400 is not set +# CONFIG_MACH_LPD7A400 is not set +CONFIG_MACH_LPD7A404=y +CONFIG_ARCH_LH7A404=y +# CONFIG_LH7A40X_CONTIGMEM is not set +# CONFIG_LH7A40X_ONE_BANK_PER_NODE is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM922T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +CONFIG_DISCONTIGMEM=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +# CONFIG_BLK_DEV_SD is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_LH7A40X=y +CONFIG_SERIAL_LH7A40X_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DEBUG=y +# CONFIG_USB_STORAGE_RW_DETECT is not set +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_TEST is not set + +# +# USB ATM/DSL drivers +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig new file mode 100644 index 0000000..4bc8717 --- /dev/null +++ b/arch/arm/configs/lubbock_defconfig @@ -0,0 +1,803 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:18:13 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Intel PXA2xx Implementations +# +CONFIG_ARCH_LUBBOCK=y +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_PXA_SHARPSL is not set +CONFIG_PXA25x=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y +CONFIG_SA1111=y +CONFIG_DMABOUNCE=y +CONFIG_FORCE_MAX_ZONEORDER=9 + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +# CONFIG_TCIC is not set +CONFIG_PCMCIA_PXA2XX=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_LUBBOCK=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_SHARP_SL is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_SA1111=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_NET2280 is not set +CONFIG_USB_GADGET_PXA2XX=y +CONFIG_USB_PXA2XX=y +CONFIG_USB_PXA2XX_SMALL=y +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_SA1100 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +CONFIG_USB_G_SERIAL=y + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_VFAT_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/lusl7200_defconfig b/arch/arm/configs/lusl7200_defconfig new file mode 100644 index 0000000..3ca64ca --- /dev/null +++ b/arch/arm/configs/lusl7200_defconfig @@ -0,0 +1,455 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:24:38 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y +CONFIG_FIQ=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +CONFIG_ARCH_L7200=y +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM720T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_LV4T=y +CONFIG_CPU_CACHE_V4=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WT=y +CONFIG_CPU_TLB_V4WT=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x00010000 +CONFIG_ZBOOT_ROM_BSS=0xf03e0000 +CONFIG_ZBOOT_ROM=y +CONFIG_CMDLINE="console=tty0 console=ttyLU1,115200 root=/dev/ram initrd=0xf1000000,0x005dac7b mem=32M" + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +# CONFIG_NET is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig new file mode 100644 index 0000000..153d685 --- /dev/null +++ b/arch/arm/configs/mainstone_defconfig @@ -0,0 +1,797 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sat Mar 26 20:00:45 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Intel PXA2xx Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +CONFIG_MACH_MAINSTONE=y +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_PXA_SHARPSL is not set +CONFIG_PXA27x=y +CONFIG_IWMMXT=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_SHARP_SL is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_PXA=y +# CONFIG_FB_PXA_PARAMETERS is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_VFAT_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/mx1ads_defconfig b/arch/arm/configs/mx1ads_defconfig new file mode 100644 index 0000000..6517d16 --- /dev/null +++ b/arch/arm/configs/mx1ads_defconfig @@ -0,0 +1,745 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 02:15:46 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_SYSCTL is not set +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_IMX=y +# CONFIG_ARCH_H720X is not set + +# +# IMX Implementations +# +CONFIG_ARCH_MX1ADS=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttySMX0,57600n8 ip=bootp root=/dev/nfs" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +CONFIG_FPE_FASTFPE=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +CONFIG_MTD_ROM=y +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=m +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=y +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig new file mode 100644 index 0000000..7fb1f7c --- /dev/null +++ b/arch/arm/configs/neponset_defconfig @@ -0,0 +1,1145 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.11 +# Wed Mar 9 14:28:26 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +CONFIG_SA1100_ASSABET=y +CONFIG_ASSABET_NEPONSET=y +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +CONFIG_SA1111=y +CONFIG_DMABOUNCE=y +CONFIG_FORCE_MAX_ZONEORDER=9 + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_SA1100=y +CONFIG_PCMCIA_SA1111=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x80000 +CONFIG_ZBOOT_ROM_BSS=0xc1000000 +CONFIG_ZBOOT_ROM=y +CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M" +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_SA1110=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_APM=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_CONCAT=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRA is not set +CONFIG_SMC91X=y +CONFIG_SMC9194=y +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_TSDEV=y +CONFIG_INPUT_TSDEV_SCREEN_X=240 +CONFIG_INPUT_TSDEV_SCREEN_Y=320 +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_CT82C710 is not set +CONFIG_SERIO_SA1111=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_CS=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=64 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_SA1100_WATCHDOG=m + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_SA1100=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +CONFIG_USB=m +CONFIG_USB_DEBUG=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_RW_DETECT is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +CONFIG_USB_MOUSE=m +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=m + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_TEST is not set + +# +# USB ATM/DSL drivers +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_PRINTK_TIME is not set +# CONFIG_SCHEDSTATS is not set +CONFIG_DEBUG_SLAB=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig new file mode 100644 index 0000000..6e81acf --- /dev/null +++ b/arch/arm/configs/netwinder_defconfig @@ -0,0 +1,1046 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 15:18:42 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +CONFIG_ARCH_FOOTBRIDGE=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +CONFIG_ARCH_NETWINDER=y +CONFIG_FOOTBRIDGE=y +CONFIG_FOOTBRIDGE_HOST=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA110=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WB=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y +CONFIG_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +# CONFIG_LEDS_TIMER is not set +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=0x301" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +CONFIG_PARPORT_PC_SUPERIO=y +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_SL82C105=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=y +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +CONFIG_IP_NF_QUEUE=y +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_LIMIT is not set +# CONFIG_IP_NF_MATCH_IPRANGE is not set +# CONFIG_IP_NF_MATCH_MAC is not set +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +# CONFIG_IP_NF_MATCH_MARK is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_TCPMSS is not set +# CONFIG_IP_NF_MATCH_HELPER is not set +# CONFIG_IP_NF_MATCH_STATE is not set +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_REALM is not set +# CONFIG_IP_NF_MATCH_SCTP is not set +# CONFIG_IP_NF_MATCH_COMMENT is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +# CONFIG_IP_NF_FILTER is not set +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_TARGET_TCPMSS is not set +# CONFIG_IP_NF_NAT is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +# CONFIG_DE2104X is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_TULIP_NAPI is not set +# CONFIG_DE4X5 is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_DM9102 is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +CONFIG_NE2K_PCI=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_21285 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_21285_WATCHDOG is not set +CONFIG_977_WATCHDOG=y + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +CONFIG_DS1620=y +CONFIG_NWBUTTON=y +CONFIG_NWBUTTON_REBOOT=y +CONFIG_NWFLASH=y +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +CONFIG_FB_CYBER2000=y +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_OSS=y +CONFIG_SOUND_TRACEINIT=y +CONFIG_SOUND_DMAP=y +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_AD1889 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_MAUI is not set +CONFIG_SOUND_YM3812=y +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +CONFIG_SOUND_WAVEARTIST=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=y +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig new file mode 100644 index 0000000..4e58d93 --- /dev/null +++ b/arch/arm/configs/omap_h2_1610_defconfig @@ -0,0 +1,971 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 17:52:41 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +CONFIG_ARCH_OMAP=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# TI OMAP Implementations +# + +# +# OMAP Core Type +# +# CONFIG_ARCH_OMAP730 is not set +# CONFIG_ARCH_OMAP1510 is not set +CONFIG_ARCH_OMAP16XX=y +CONFIG_ARCH_OMAP_OTG=y + +# +# OMAP Board Type +# +# CONFIG_MACH_OMAP_INNOVATOR is not set +CONFIG_MACH_OMAP_H2=y +# CONFIG_MACH_OMAP_H3 is not set +# CONFIG_MACH_OMAP_H4 is not set +# CONFIG_MACH_OMAP_OSK is not set +# CONFIG_MACH_OMAP_GENERIC is not set + +# +# OMAP Feature Selections +# +CONFIG_OMAP_MUX=y +# CONFIG_OMAP_MUX_DEBUG is not set +CONFIG_OMAP_MUX_WARNINGS=y +CONFIG_OMAP_MPU_TIMER=y +# CONFIG_OMAP_32K_TIMER is not set +CONFIG_OMAP_LL_DEBUG_UART1=y +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +# CONFIG_OMAP_LL_DEBUG_UART3 is not set +CONFIG_OMAP_ARM_192MHZ=y +# CONFIG_OMAP_ARM_168MHZ is not set +# CONFIG_OMAP_ARM_120MHZ is not set +# CONFIG_OMAP_ARM_60MHZ is not set +# CONFIG_OMAP_ARM_30MHZ is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_PREEMPT=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 root=0801 ro init=/bin/sh" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_APM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +CONFIG_DEBUG_DRIVER=y + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=3 +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_ATA_OVER_ETH=m + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +# CONFIG_BLK_DEV_SD is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +CONFIG_SLIP=y +CONFIG_SLIP_COMPRESSED=y +# CONFIG_SLIP_SMART is not set +# CONFIG_SLIP_MODE_SLIP6 is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=y + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +CONFIG_ISP1301_OMAP=y +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SOFT_CURSOR is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_SA1100 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_OMAP=y +CONFIG_USB_OMAP=y +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_VFAT_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=2 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/omnimeter_defconfig b/arch/arm/configs/omnimeter_defconfig new file mode 100644 index 0000000..78fdb4a --- /dev/null +++ b/arch/arm/configs/omnimeter_defconfig @@ -0,0 +1,803 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 21:31:45 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +CONFIG_I82365=y +# CONFIG_TCIC is not set +CONFIG_PCMCIA_SA1100=y +CONFIG_PCCARD_NONSTATIC=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/ram ramdisk=8192 initrd=0xd0000000,4M" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set +CONFIG_PCMCIA_WAVELAN=y +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_AIRO_CS=y +CONFIG_PCMCIA_WL3501=y +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=y +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_SA1100=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_VFAT_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/pleb_defconfig b/arch/arm/configs/pleb_defconfig new file mode 100644 index 0000000..10fec89 --- /dev/null +++ b/arch/arm/configs/pleb_defconfig @@ -0,0 +1,749 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:03:02 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +# CONFIG_KOBJECT_UEVENT is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_SHMEM is not set +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +CONFIG_SA1100_PLEB=y +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttySA0,9600 mem=16M@0xc0000000 mem=16M@0xc8000000 root=/dev/ram initrd=0xc0400000,4M" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_SA1100=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +CONFIG_SMC91X=y +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +CONFIG_NFS_DIRECTIO=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig new file mode 100644 index 0000000..21c3278 --- /dev/null +++ b/arch/arm/configs/pxa255-idp_defconfig @@ -0,0 +1,799 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:20:17 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Intel PXA2xx Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_MAINSTONE is not set +CONFIG_ARCH_PXA_IDP=y +# CONFIG_PXA_SHARPSL is not set +CONFIG_PXA25x=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs ip=dhcp console=ttyS0,115200 mem=64M" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_CFI_I1 is not set +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_SHARP_SL is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_PXA=y +# CONFIG_FB_PXA_PARAMETERS is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_VFAT_FS is not set +CONFIG_FAT_DEFAULT_CODEPAGE=437 +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig new file mode 100644 index 0000000..19184c1 --- /dev/null +++ b/arch/arm/configs/rpc_defconfig @@ -0,0 +1,939 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.11 +# Wed Mar 9 14:41:48 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y +CONFIG_FIQ=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +CONFIG_ARCH_RPC=y +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +CONFIG_ARCH_ACORN=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM610=y +CONFIG_CPU_ARM710=y +CONFIG_CPU_SA110=y +CONFIG_CPU_32v3=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V3=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V3=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V3=y +CONFIG_CPU_TLB_V4WB=y + +# +# Processor Features +# +CONFIG_TIMER_ACORN=y + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PC-card bridges +# + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_CML1=y +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# Acorn-specific block devices +# + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_IDE_ARM=y +CONFIG_BLK_DEV_IDE_ICSIDE=y +CONFIG_BLK_DEV_IDEDMA_ICS=y +CONFIG_IDEDMA_ICS_AUTO=y +CONFIG_BLK_DEV_IDE_RAPIDE=y +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_SATA is not set +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_ACORNSCSI_3=m +CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE=y +CONFIG_SCSI_ACORNSCSI_SYNC=y +CONFIG_SCSI_ARXESCSI=m +CONFIG_SCSI_CUMANA_2=m +CONFIG_SCSI_EESOXSCSI=m +CONFIG_SCSI_POWERTECSCSI=y + +# +# The following drivers are not fully supported +# +CONFIG_SCSI_CUMANA_1=m +CONFIG_SCSI_OAK1=m + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_NETLINK_DEV=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_ARM_ETHER1=y +CONFIG_ARM_ETHER3=y +CONFIG_ARM_ETHERH=y +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_RPCKBD=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +CONFIG_MOUSE_RISCPC=y +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=16 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_8250_ACORN=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=64 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_ACORN=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +CONFIG_FONT_ACORN_8x8=y +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_AD1889 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +CONFIG_SOUND_VIDC=m +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +# CONFIG_USB is not set +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=y +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +CONFIG_ACORN_PARTITION_ADFS=y +CONFIG_ACORN_PARTITION_POWERTEC=y +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_SOLARIS_X86_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +CONFIG_NLS_KOI8_R=m +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_PRINTK_TIME is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig new file mode 100644 index 0000000..2a63fb2 --- /dev/null +++ b/arch/arm/configs/s3c2410_defconfig @@ -0,0 +1,954 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 17:47:45 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +CONFIG_ARCH_S3C2410=y +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# S3C24XX Implementations +# +CONFIG_ARCH_BAST=y +CONFIG_ARCH_H1940=y +CONFIG_MACH_N30=y +CONFIG_ARCH_SMDK2410=y +CONFIG_ARCH_S3C2440=y +CONFIG_MACH_VR1000=y +CONFIG_MACH_RX3715=y +CONFIG_MACH_OTOM=y +CONFIG_MACH_NEXCODER_2440=y +CONFIG_CPU_S3C2410=y +CONFIG_CPU_S3C2440=y + +# +# S3C2410 Boot +# +# CONFIG_S3C2410_BOOT_WATCHDOG is not set + +# +# S3C2410 Setup +# +CONFIG_S3C2410_DMA=y +# CONFIG_S3C2410_DMA_DEBUG is not set +# CONFIG_S3C2410_PM_DEBUG is not set +# CONFIG_S3C2410_PM_CHECK is not set +CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_APM=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MAP_BANK_WIDTH_16=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_AMDSTD_RETRY=0 +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +CONFIG_MTD_ROM=y +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +CONFIG_MTD_BAST=y +CONFIG_MTD_BAST_MAXSIZE=4 + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=y +CONFIG_MTD_NAND_S3C2410=y +# CONFIG_MTD_NAND_S3C2410_DEBUG is not set +# CONFIG_MTD_NAND_S3C2410_HWECC is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +# CONFIG_PARPORT_PC is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_ATA_OVER_ETH=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDE_BAST=y +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PARKBD is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_S3C2410=y +CONFIG_SERIAL_S3C2410_CONSOLE=y +CONFIG_SERIAL_BAST_SIO=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=y +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_S3C2410_WATCHDOG=y +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_S3C2410_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +CONFIG_I2C_S3C2410=y +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +CONFIG_SENSORS_LM75=m +# CONFIG_SENSORS_LM77 is not set +CONFIG_SENSORS_LM78=m +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +CONFIG_SENSORS_LM85=m +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=m +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SOFT_CURSOR is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS_FS=y +CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_JFFS_PROC_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_SOLARIS_X86_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C2410_PORT=y +CONFIG_DEBUG_S3C2410_UART=0 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/shannon_defconfig b/arch/arm/configs/shannon_defconfig new file mode 100644 index 0000000..e3facc4 --- /dev/null +++ b/arch/arm/configs/shannon_defconfig @@ -0,0 +1,872 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 23:26:46 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +CONFIG_SA1100_SHANNON=y +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_SA1100=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_DISCONTIGMEM=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttySA0,9600 console=tty1 root=/dev/mtdblock2 init=/linuxrc" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_AMDSTD_RETRY=0 +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +# CONFIG_BLK_DEV_IDEDISK is not set +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=m +# CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +CONFIG_PCMCIA_SMC91C92=y +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_SA1100_WATCHDOG=y + +# +# ISA-based Watchdog Cards +# +# CONFIG_PCWATCHDOG is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_SA1100=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig new file mode 100644 index 0000000..1d9bcbb --- /dev/null +++ b/arch/arm/configs/shark_defconfig @@ -0,0 +1,974 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 23:59:14 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +CONFIG_ARCH_SHARK=y +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA110=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WB=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y +CONFIG_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_HOST_VIA82C505=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_NAMES is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +CONFIG_FPE_FASTFPE=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPCI is not set +CONFIG_IDE_ARM=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=m +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +CONFIG_CS89x0=y +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +CONFIG_FB_CYBER2000=y +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +CONFIG_SOUND_PRIME=m +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_AD1889 is not set +# CONFIG_SOUND_SGALAXY is not set +CONFIG_SOUND_ADLIB=m +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_SOUND_PSS is not set +CONFIG_SOUND_SB=m +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_KAHLUA is not set +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_AD1980 is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig new file mode 100644 index 0000000..5373eeb --- /dev/null +++ b/arch/arm/configs/simpad_defconfig @@ -0,0 +1,964 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:10:36 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y + +# +# General setup +# +CONFIG_LOCALVERSION="oe1" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_COLLIE is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_SHANNON is not set +CONFIG_SA1100_SIMPAD=y +# CONFIG_SA1100_SSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# + +# +# Bus support +# +CONFIG_ISA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y + +# +# PC-card bridges +# +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +CONFIG_PCMCIA_SA1100=y + +# +# Kernel Features +# +CONFIG_PREEMPT=y +CONFIG_DISCONTIGMEM=y +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +# CONFIG_LEDS_CPU is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mtdparts=sa1100:512k(boot),1m(kernel),-(root) console=ttySA0 root=1f02 noinitrd mem=64M jffs2_orphaned_inodes=delete rootfstype=jffs2" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=m +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_APM=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_SA1100=y +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +CONFIG_IRPORT_SIR=m + +# +# Old Serial dongle support +# +# CONFIG_DONGLE_OLD is not set + +# +# FIR device drivers +# +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +CONFIG_SA1100_FIR=m +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +# CONFIG_BT_HIDP is not set + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIDTL1 is not set +# CONFIG_BT_HCIBT3C is not set +# CONFIG_BT_HCIBLUECARD is not set +# CONFIG_BT_HCIBTUART is not set +# CONFIG_BT_HCIVHCI is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_SMC91X is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set +CONFIG_PCMCIA_WAVELAN=m +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=m +# CONFIG_PCMCIA_NMCLAN is not set +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +# CONFIG_PCMCIA_AXNET is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=800 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=600 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_TSDEV=y +CONFIG_INPUT_TSDEV_SCREEN_X=800 +CONFIG_INPUT_TSDEV_SCREEN_Y=600 +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_EVBUG=y + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=m +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_SOFT_CURSOR is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=m +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS_FS=m +CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_JFFS_PROC_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +# CONFIG_ROOT_NFS is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/smdk2410_defconfig b/arch/arm/configs/smdk2410_defconfig new file mode 100644 index 0000000..2c60865 --- /dev/null +++ b/arch/arm/configs/smdk2410_defconfig @@ -0,0 +1,736 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:42:40 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +CONFIG_ARCH_S3C2410=y +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# S3C24XX Implementations +# +# CONFIG_ARCH_BAST is not set +# CONFIG_ARCH_H1940 is not set +# CONFIG_MACH_N30 is not set +CONFIG_ARCH_SMDK2410=y +# CONFIG_ARCH_S3C2440 is not set +# CONFIG_MACH_VR1000 is not set +# CONFIG_MACH_RX3715 is not set +# CONFIG_MACH_OTOM is not set +# CONFIG_MACH_NEXCODER_2440 is not set +CONFIG_CPU_S3C2410=y + +# +# S3C2410 Boot +# + +# +# S3C2410 Setup +# +# CONFIG_S3C2410_DMA is not set +CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=1f04 mem=32M" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_SMC91X is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_S3C2410=y +CONFIG_SERIAL_S3C2410_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_S3C2410_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_VIRTUAL=y + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C2410_PORT=y +CONFIG_DEBUG_S3C2410_UART=0 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig new file mode 100644 index 0000000..d72f2c7 --- /dev/null +++ b/arch/arm/configs/versatile_defconfig @@ -0,0 +1,902 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Mon Mar 28 00:20:50 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +CONFIG_ARCH_VERSATILE=y +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# Versatile platform type +# +CONFIG_ARCH_VERSATILE_PB=y +# CONFIG_MACH_VERSATILE_AB is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_ICST307=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=1f03 mem=32M" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_APM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_ARM_INTEGRATOR=y +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_MULTIPORT=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=m +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_EEPROM=m +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +CONFIG_FONT_ACORN_8x8=y +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_ARMMMCI=m + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=y +CONFIG_ROMFS_FS=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile new file mode 100644 index 0000000..07a56ff --- /dev/null +++ b/arch/arm/kernel/Makefile @@ -0,0 +1,38 @@ +# +# Makefile for the linux kernel. +# + +AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) + +# Object file lists. + +obj-y := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o \ + process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \ + time.o traps.o + +obj-$(CONFIG_APM) += apm.o +obj-$(CONFIG_ARCH_ACORN) += ecard.o +obj-$(CONFIG_FOOTBRIDGE) += isa.o +obj-$(CONFIG_FIQ) += fiq.o +obj-$(CONFIG_MODULES) += armksyms.o module.o +obj-$(CONFIG_ARTHUR) += arthur.o +obj-$(CONFIG_ISA_DMA) += dma-isa.o +obj-$(CONFIG_PCI) += bios32.o +obj-$(CONFIG_SMP) += smp.o + +obj-$(CONFIG_IWMMXT) += iwmmxt.o +AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt + +ifneq ($(CONFIG_ARCH_EBSA110),y) + obj-y += io.o +endif + +head-y := head.o +obj-$(CONFIG_DEBUG_LL) += debug.o + +extra-y := $(head-y) init_task.o vmlinux.lds + +# Spell out some dependencies that aren't automatically figured out +$(obj)/entry-armv.o: $(obj)/entry-header.S include/asm-arm/constants.h +$(obj)/entry-common.o: $(obj)/entry-header.S include/asm-arm/constants.h \ + $(obj)/calls.S diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c new file mode 100644 index 0000000..b0bbd1e --- /dev/null +++ b/arch/arm/kernel/apm.c @@ -0,0 +1,610 @@ +/* + * bios-less APM driver for ARM Linux + * Jamey Hicks <jamey@crl.dec.com> + * adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com) + * + * APM 1.2 Reference: + * Intel Corporation, Microsoft Corporation. Advanced Power Management + * (APM) BIOS Interface Specification, Revision 1.2, February 1996. + * + * [This document is available from Microsoft at: + * http://www.microsoft.com/hwdev/busbios/amp_12.htm] + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/poll.h> +#include <linux/timer.h> +#include <linux/slab.h> +#include <linux/proc_fs.h> +#include <linux/miscdevice.h> +#include <linux/apm_bios.h> +#include <linux/sched.h> +#include <linux/pm.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/init.h> +#include <linux/completion.h> + +#include <asm/apm.h> /* apm_power_info */ +#include <asm/system.h> + +/* + * The apm_bios device is one of the misc char devices. + * This is its minor number. + */ +#define APM_MINOR_DEV 134 + +/* + * See Documentation/Config.help for the configuration options. + * + * Various options can be changed at boot time as follows: + * (We allow underscores for compatibility with the modules code) + * apm=on/off enable/disable APM + */ + +/* + * Maximum number of events stored + */ +#define APM_MAX_EVENTS 16 + +struct apm_queue { + unsigned int event_head; + unsigned int event_tail; + apm_event_t events[APM_MAX_EVENTS]; +}; + +/* + * The per-file APM data + */ +struct apm_user { + struct list_head list; + + unsigned int suser: 1; + unsigned int writer: 1; + unsigned int reader: 1; + + int suspend_result; + unsigned int suspend_state; +#define SUSPEND_NONE 0 /* no suspend pending */ +#define SUSPEND_PENDING 1 /* suspend pending read */ +#define SUSPEND_READ 2 /* suspend read, pending ack */ +#define SUSPEND_ACKED 3 /* suspend acked */ +#define SUSPEND_DONE 4 /* suspend completed */ + + struct apm_queue queue; +}; + +/* + * Local variables + */ +static int suspends_pending; +static int apm_disabled; + +static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); +static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); + +/* + * This is a list of everyone who has opened /dev/apm_bios + */ +static DECLARE_RWSEM(user_list_lock); +static LIST_HEAD(apm_user_list); + +/* + * kapmd info. kapmd provides us a process context to handle + * "APM" events within - specifically necessary if we're going + * to be suspending the system. + */ +static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); +static DECLARE_COMPLETION(kapmd_exit); +static DEFINE_SPINLOCK(kapmd_queue_lock); +static struct apm_queue kapmd_queue; + + +static const char driver_version[] = "1.13"; /* no spaces */ + + + +/* + * Compatibility cruft until the IPAQ people move over to the new + * interface. + */ +static void __apm_get_power_status(struct apm_power_info *info) +{ +} + +/* + * This allows machines to provide their own "apm get power status" function. + */ +void (*apm_get_power_status)(struct apm_power_info *) = __apm_get_power_status; +EXPORT_SYMBOL(apm_get_power_status); + + +/* + * APM event queue management. + */ +static inline int queue_empty(struct apm_queue *q) +{ + return q->event_head == q->event_tail; +} + +static inline apm_event_t queue_get_event(struct apm_queue *q) +{ + q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS; + return q->events[q->event_tail]; +} + +static void queue_add_event(struct apm_queue *q, apm_event_t event) +{ + q->event_head = (q->event_head + 1) % APM_MAX_EVENTS; + if (q->event_head == q->event_tail) { + static int notified; + + if (notified++ == 0) + printk(KERN_ERR "apm: an event queue overflowed\n"); + q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS; + } + q->events[q->event_head] = event; +} + +static void queue_event_one_user(struct apm_user *as, apm_event_t event) +{ + if (as->suser && as->writer) { + switch (event) { + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + /* + * If this user already has a suspend pending, + * don't queue another one. + */ + if (as->suspend_state != SUSPEND_NONE) + return; + + as->suspend_state = SUSPEND_PENDING; + suspends_pending++; + break; + } + } + queue_add_event(&as->queue, event); +} + +static void queue_event(apm_event_t event, struct apm_user *sender) +{ + struct apm_user *as; + + down_read(&user_list_lock); + list_for_each_entry(as, &apm_user_list, list) { + if (as != sender && as->reader) + queue_event_one_user(as, event); + } + up_read(&user_list_lock); + wake_up_interruptible(&apm_waitqueue); +} + +static void apm_suspend(void) +{ + struct apm_user *as; + int err = pm_suspend(PM_SUSPEND_MEM); + + /* + * Anyone on the APM queues will think we're still suspended. + * Send a message so everyone knows we're now awake again. + */ + queue_event(APM_NORMAL_RESUME, NULL); + + /* + * Finally, wake up anyone who is sleeping on the suspend. + */ + down_read(&user_list_lock); + list_for_each_entry(as, &apm_user_list, list) { + as->suspend_result = err; + as->suspend_state = SUSPEND_DONE; + } + up_read(&user_list_lock); + + wake_up(&apm_suspend_waitqueue); +} + +static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) +{ + struct apm_user *as = fp->private_data; + apm_event_t event; + int i = count, ret = 0; + + if (count < sizeof(apm_event_t)) + return -EINVAL; + + if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK) + return -EAGAIN; + + wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue)); + + while ((i >= sizeof(event)) && !queue_empty(&as->queue)) { + event = queue_get_event(&as->queue); + + ret = -EFAULT; + if (copy_to_user(buf, &event, sizeof(event))) + break; + + if (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND) + as->suspend_state = SUSPEND_READ; + + buf += sizeof(event); + i -= sizeof(event); + } + + if (i < count) + ret = count - i; + + return ret; +} + +static unsigned int apm_poll(struct file *fp, poll_table * wait) +{ + struct apm_user *as = fp->private_data; + + poll_wait(fp, &apm_waitqueue, wait); + return queue_empty(&as->queue) ? 0 : POLLIN | POLLRDNORM; +} + +/* + * apm_ioctl - handle APM ioctl + * + * APM_IOC_SUSPEND + * This IOCTL is overloaded, and performs two functions. It is used to: + * - initiate a suspend + * - acknowledge a suspend read from /dev/apm_bios. + * Only when everyone who has opened /dev/apm_bios with write permission + * has acknowledge does the actual suspend happen. + */ +static int +apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) +{ + struct apm_user *as = filp->private_data; + unsigned long flags; + int err = -EINVAL; + + if (!as->suser || !as->writer) + return -EPERM; + + switch (cmd) { + case APM_IOC_SUSPEND: + as->suspend_result = -EINTR; + + if (as->suspend_state == SUSPEND_READ) { + /* + * If we read a suspend command from /dev/apm_bios, + * then the corresponding APM_IOC_SUSPEND ioctl is + * interpreted as an acknowledge. + */ + as->suspend_state = SUSPEND_ACKED; + suspends_pending--; + } else { + /* + * Otherwise it is a request to suspend the system. + * Queue an event for all readers, and expect an + * acknowledge from all writers who haven't already + * acknowledged. + */ + queue_event(APM_USER_SUSPEND, as); + } + + /* + * If there are no further acknowledges required, suspend + * the system. + */ + if (suspends_pending == 0) + apm_suspend(); + + /* + * Wait for the suspend/resume to complete. If there are + * pending acknowledges, we wait here for them. + * + * Note that we need to ensure that the PM subsystem does + * not kick us out of the wait when it suspends the threads. + */ + flags = current->flags; + current->flags |= PF_NOFREEZE; + + /* + * Note: do not allow a thread which is acking the suspend + * to escape until the resume is complete. + */ + if (as->suspend_state == SUSPEND_ACKED) + wait_event(apm_suspend_waitqueue, + as->suspend_state == SUSPEND_DONE); + else + wait_event_interruptible(apm_suspend_waitqueue, + as->suspend_state == SUSPEND_DONE); + + current->flags = flags; + err = as->suspend_result; + as->suspend_state = SUSPEND_NONE; + break; + } + + return err; +} + +static int apm_release(struct inode * inode, struct file * filp) +{ + struct apm_user *as = filp->private_data; + filp->private_data = NULL; + + down_write(&user_list_lock); + list_del(&as->list); + up_write(&user_list_lock); + + /* + * We are now unhooked from the chain. As far as new + * events are concerned, we no longer exist. However, we + * need to balance suspends_pending, which means the + * possibility of sleeping. + */ + if (as->suspend_state != SUSPEND_NONE) { + suspends_pending -= 1; + if (suspends_pending == 0) + apm_suspend(); + } + + kfree(as); + return 0; +} + +static int apm_open(struct inode * inode, struct file * filp) +{ + struct apm_user *as; + + as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL); + if (as) { + memset(as, 0, sizeof(*as)); + + /* + * XXX - this is a tiny bit broken, when we consider BSD + * process accounting. If the device is opened by root, we + * instantly flag that we used superuser privs. Who knows, + * we might close the device immediately without doing a + * privileged operation -- cevans + */ + as->suser = capable(CAP_SYS_ADMIN); + as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE; + as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ; + + down_write(&user_list_lock); + list_add(&as->list, &apm_user_list); + up_write(&user_list_lock); + + filp->private_data = as; + } + + return as ? 0 : -ENOMEM; +} + +static struct file_operations apm_bios_fops = { + .owner = THIS_MODULE, + .read = apm_read, + .poll = apm_poll, + .ioctl = apm_ioctl, + .open = apm_open, + .release = apm_release, +}; + +static struct miscdevice apm_device = { + .minor = APM_MINOR_DEV, + .name = "apm_bios", + .fops = &apm_bios_fops +}; + + +#ifdef CONFIG_PROC_FS +/* + * Arguments, with symbols from linux/apm_bios.h. + * + * 0) Linux driver version (this will change if format changes) + * 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2. + * 2) APM flags from APM Installation Check (0x00): + * bit 0: APM_16_BIT_SUPPORT + * bit 1: APM_32_BIT_SUPPORT + * bit 2: APM_IDLE_SLOWS_CLOCK + * bit 3: APM_BIOS_DISABLED + * bit 4: APM_BIOS_DISENGAGED + * 3) AC line status + * 0x00: Off-line + * 0x01: On-line + * 0x02: On backup power (BIOS >= 1.1 only) + * 0xff: Unknown + * 4) Battery status + * 0x00: High + * 0x01: Low + * 0x02: Critical + * 0x03: Charging + * 0x04: Selected battery not present (BIOS >= 1.2 only) + * 0xff: Unknown + * 5) Battery flag + * bit 0: High + * bit 1: Low + * bit 2: Critical + * bit 3: Charging + * bit 7: No system battery + * 0xff: Unknown + * 6) Remaining battery life (percentage of charge): + * 0-100: valid + * -1: Unknown + * 7) Remaining battery life (time units): + * Number of remaining minutes or seconds + * -1: Unknown + * 8) min = minutes; sec = seconds + */ +static int apm_get_info(char *buf, char **start, off_t fpos, int length) +{ + struct apm_power_info info; + char *units; + int ret; + + info.ac_line_status = 0xff; + info.battery_status = 0xff; + info.battery_flag = 0xff; + info.battery_life = -1; + info.time = -1; + info.units = -1; + + if (apm_get_power_status) + apm_get_power_status(&info); + + switch (info.units) { + default: units = "?"; break; + case 0: units = "min"; break; + case 1: units = "sec"; break; + } + + ret = sprintf(buf, "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", + driver_version, APM_32_BIT_SUPPORT, + info.ac_line_status, info.battery_status, + info.battery_flag, info.battery_life, + info.time, units); + + return ret; +} +#endif + +static int kapmd(void *arg) +{ + daemonize("kapmd"); + current->flags |= PF_NOFREEZE; + + do { + apm_event_t event; + + wait_event_interruptible(kapmd_wait, + !queue_empty(&kapmd_queue) || !pm_active); + + if (!pm_active) + break; + + spin_lock_irq(&kapmd_queue_lock); + event = 0; + if (!queue_empty(&kapmd_queue)) + event = queue_get_event(&kapmd_queue); + spin_unlock_irq(&kapmd_queue_lock); + + switch (event) { + case 0: + break; + + case APM_LOW_BATTERY: + case APM_POWER_STATUS_CHANGE: + queue_event(event, NULL); + break; + + case APM_USER_SUSPEND: + case APM_SYS_SUSPEND: + queue_event(event, NULL); + if (suspends_pending == 0) + apm_suspend(); + break; + + case APM_CRITICAL_SUSPEND: + apm_suspend(); + break; + } + } while (1); + + complete_and_exit(&kapmd_exit, 0); +} + +static int __init apm_init(void) +{ + int ret; + + if (apm_disabled) { + printk(KERN_NOTICE "apm: disabled on user request.\n"); + return -ENODEV; + } + + if (PM_IS_ACTIVE()) { + printk(KERN_NOTICE "apm: overridden by ACPI.\n"); + return -EINVAL; + } + + pm_active = 1; + + ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); + if (ret < 0) { + pm_active = 0; + return ret; + } + +#ifdef CONFIG_PROC_FS + create_proc_info_entry("apm", 0, NULL, apm_get_info); +#endif + + ret = misc_register(&apm_device); + if (ret != 0) { + remove_proc_entry("apm", NULL); + + pm_active = 0; + wake_up(&kapmd_wait); + wait_for_completion(&kapmd_exit); + } + + return ret; +} + +static void __exit apm_exit(void) +{ + misc_deregister(&apm_device); + remove_proc_entry("apm", NULL); + + pm_active = 0; + wake_up(&kapmd_wait); + wait_for_completion(&kapmd_exit); +} + +module_init(apm_init); +module_exit(apm_exit); + +MODULE_AUTHOR("Stephen Rothwell"); +MODULE_DESCRIPTION("Advanced Power Management"); +MODULE_LICENSE("GPL"); + +#ifndef MODULE +static int __init apm_setup(char *str) +{ + while ((str != NULL) && (*str != '\0')) { + if (strncmp(str, "off", 3) == 0) + apm_disabled = 1; + if (strncmp(str, "on", 2) == 0) + apm_disabled = 0; + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); + } + return 1; +} + +__setup("apm=", apm_setup); +#endif + +/** + * apm_queue_event - queue an APM event for kapmd + * @event: APM event + * + * Queue an APM event for kapmd to process and ultimately take the + * appropriate action. Only a subset of events are handled: + * %APM_LOW_BATTERY + * %APM_POWER_STATUS_CHANGE + * %APM_USER_SUSPEND + * %APM_SYS_SUSPEND + * %APM_CRITICAL_SUSPEND + */ +void apm_queue_event(apm_event_t event) +{ + unsigned long flags; + + spin_lock_irqsave(&kapmd_queue_lock, flags); + queue_add_event(&kapmd_queue, event); + spin_unlock_irqrestore(&kapmd_queue_lock, flags); + + wake_up_interruptible(&kapmd_wait); +} +EXPORT_SYMBOL(apm_queue_event); diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c new file mode 100644 index 0000000..4e02fbe --- /dev/null +++ b/arch/arm/kernel/arch.c @@ -0,0 +1,46 @@ +/* + * linux/arch/arm/kernel/arch.c + * + * Architecture specific fixups. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/types.h> + +#include <asm/elf.h> +#include <asm/page.h> +#include <asm/setup.h> +#include <asm/mach/arch.h> + +unsigned int vram_size; + +#ifdef CONFIG_ARCH_ACORN + +unsigned int memc_ctrl_reg; +unsigned int number_mfm_drives; + +static int __init parse_tag_acorn(const struct tag *tag) +{ + memc_ctrl_reg = tag->u.acorn.memc_control_reg; + number_mfm_drives = tag->u.acorn.adfsdrives; + + switch (tag->u.acorn.vram_pages) { + case 512: + vram_size += PAGE_SIZE * 256; + case 256: + vram_size += PAGE_SIZE * 256; + default: + break; + } +#if 0 + if (vram_size) { + desc->video_start = 0x02000000; + desc->video_end = 0x02000000 + vram_size; + } +#endif + return 0; +} + +__tagtable(ATAG_ACORN, parse_tag_acorn); + +#endif diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c new file mode 100644 index 0000000..4c38bd8 --- /dev/null +++ b/arch/arm/kernel/armksyms.c @@ -0,0 +1,175 @@ +/* + * linux/arch/arm/kernel/armksyms.c + * + * Copyright (C) 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/module.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/in6.h> +#include <linux/syscalls.h> + +#include <asm/checksum.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/uaccess.h> + +/* + * libgcc functions - functions that are used internally by the + * compiler... (prototypes are not correct though, but that + * doesn't really matter since they're not versioned). + */ +extern void __ashldi3(void); +extern void __ashrdi3(void); +extern void __divsi3(void); +extern void __lshrdi3(void); +extern void __modsi3(void); +extern void __muldi3(void); +extern void __ucmpdi2(void); +extern void __udivdi3(void); +extern void __umoddi3(void); +extern void __udivmoddi4(void); +extern void __udivsi3(void); +extern void __umodsi3(void); +extern void __do_div64(void); + +extern void fpundefinstr(void); +extern void fp_enter(void); + +/* + * This has a special calling convention; it doesn't + * modify any of the usual registers, except for LR. + */ +#define EXPORT_SYMBOL_ALIAS(sym,orig) \ + const struct kernel_symbol __ksymtab_##sym \ + __attribute__((section("__ksymtab"))) = \ + { (unsigned long)&orig, #sym }; + +/* + * floating point math emulator support. + * These symbols will never change their calling convention... + */ +EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter); +EXPORT_SYMBOL_ALIAS(fp_printk,printk); +EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig); + +EXPORT_SYMBOL(__backtrace); + + /* platform dependent support */ +EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(__const_udelay); + + /* networking */ +EXPORT_SYMBOL(csum_partial); +EXPORT_SYMBOL(csum_partial_copy_nocheck); +EXPORT_SYMBOL(__csum_ipv6_magic); + + /* io */ +#ifndef __raw_readsb +EXPORT_SYMBOL(__raw_readsb); +#endif +#ifndef __raw_readsw +EXPORT_SYMBOL(__raw_readsw); +#endif +#ifndef __raw_readsl +EXPORT_SYMBOL(__raw_readsl); +#endif +#ifndef __raw_writesb +EXPORT_SYMBOL(__raw_writesb); +#endif +#ifndef __raw_writesw +EXPORT_SYMBOL(__raw_writesw); +#endif +#ifndef __raw_writesl +EXPORT_SYMBOL(__raw_writesl); +#endif + + /* string / mem functions */ +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strpbrk); +EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memscan); +EXPORT_SYMBOL(memchr); +EXPORT_SYMBOL(__memzero); + + /* user mem (segment) */ +EXPORT_SYMBOL(__arch_copy_from_user); +EXPORT_SYMBOL(__arch_copy_to_user); +EXPORT_SYMBOL(__arch_clear_user); +EXPORT_SYMBOL(__arch_strnlen_user); +EXPORT_SYMBOL(__arch_strncpy_from_user); + +EXPORT_SYMBOL(__get_user_1); +EXPORT_SYMBOL(__get_user_2); +EXPORT_SYMBOL(__get_user_4); +EXPORT_SYMBOL(__get_user_8); + +EXPORT_SYMBOL(__put_user_1); +EXPORT_SYMBOL(__put_user_2); +EXPORT_SYMBOL(__put_user_4); +EXPORT_SYMBOL(__put_user_8); + + /* gcc lib functions */ +EXPORT_SYMBOL(__ashldi3); +EXPORT_SYMBOL(__ashrdi3); +EXPORT_SYMBOL(__divsi3); +EXPORT_SYMBOL(__lshrdi3); +EXPORT_SYMBOL(__modsi3); +EXPORT_SYMBOL(__muldi3); +EXPORT_SYMBOL(__ucmpdi2); +EXPORT_SYMBOL(__udivdi3); +EXPORT_SYMBOL(__umoddi3); +EXPORT_SYMBOL(__udivmoddi4); +EXPORT_SYMBOL(__udivsi3); +EXPORT_SYMBOL(__umodsi3); +EXPORT_SYMBOL(__do_div64); + + /* bitops */ +EXPORT_SYMBOL(_set_bit_le); +EXPORT_SYMBOL(_test_and_set_bit_le); +EXPORT_SYMBOL(_clear_bit_le); +EXPORT_SYMBOL(_test_and_clear_bit_le); +EXPORT_SYMBOL(_change_bit_le); +EXPORT_SYMBOL(_test_and_change_bit_le); +EXPORT_SYMBOL(_find_first_zero_bit_le); +EXPORT_SYMBOL(_find_next_zero_bit_le); +EXPORT_SYMBOL(_find_first_bit_le); +EXPORT_SYMBOL(_find_next_bit_le); + +#ifdef __ARMEB__ +EXPORT_SYMBOL(_set_bit_be); +EXPORT_SYMBOL(_test_and_set_bit_be); +EXPORT_SYMBOL(_clear_bit_be); +EXPORT_SYMBOL(_test_and_clear_bit_be); +EXPORT_SYMBOL(_change_bit_be); +EXPORT_SYMBOL(_test_and_change_bit_be); +EXPORT_SYMBOL(_find_first_zero_bit_be); +EXPORT_SYMBOL(_find_next_zero_bit_be); +EXPORT_SYMBOL(_find_first_bit_be); +EXPORT_SYMBOL(_find_next_bit_be); +#endif + + /* syscalls */ +EXPORT_SYMBOL(sys_write); +EXPORT_SYMBOL(sys_read); +EXPORT_SYMBOL(sys_lseek); +EXPORT_SYMBOL(sys_open); +EXPORT_SYMBOL(sys_exit); +EXPORT_SYMBOL(sys_wait4); diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c new file mode 100644 index 0000000..a418dad --- /dev/null +++ b/arch/arm/kernel/arthur.c @@ -0,0 +1,91 @@ +/* + * linux/arch/arm/kernel/arthur.c + * + * Copyright (C) 1998, 1999, 2000, 2001 Philip Blundell + * + * Arthur personality + */ + +/* + * 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. + */ + +#include <linux/module.h> +#include <linux/personality.h> +#include <linux/stddef.h> +#include <linux/signal.h> +#include <linux/init.h> + +#include <asm/ptrace.h> + +/* Arthur doesn't have many signals, and a lot of those that it does + have don't map easily to any Linux equivalent. Never mind. */ + +#define ARTHUR_SIGABRT 1 +#define ARTHUR_SIGFPE 2 +#define ARTHUR_SIGILL 3 +#define ARTHUR_SIGINT 4 +#define ARTHUR_SIGSEGV 5 +#define ARTHUR_SIGTERM 6 +#define ARTHUR_SIGSTAK 7 +#define ARTHUR_SIGUSR1 8 +#define ARTHUR_SIGUSR2 9 +#define ARTHUR_SIGOSERROR 10 + +static unsigned long arthur_to_linux_signals[32] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31 +}; + +static unsigned long linux_to_arthur_signals[32] = { + 0, -1, ARTHUR_SIGINT, -1, + ARTHUR_SIGILL, 5, ARTHUR_SIGABRT, 7, + ARTHUR_SIGFPE, 9, ARTHUR_SIGUSR1, ARTHUR_SIGSEGV, + ARTHUR_SIGUSR2, 13, 14, ARTHUR_SIGTERM, + 16, 17, 18, 19, + 20, 21, 22, 23, + 24, 25, 26, 27, + 28, 29, 30, 31 +}; + +static void arthur_lcall7(int nr, struct pt_regs *regs) +{ + struct siginfo info; + info.si_signo = SIGSWI; + info.si_errno = nr; + /* Bounce it to the emulator */ + send_sig_info(SIGSWI, &info, current); +} + +static struct exec_domain arthur_exec_domain = { + .name = "Arthur", + .handler = arthur_lcall7, + .pers_low = PER_RISCOS, + .pers_high = PER_RISCOS, + .signal_map = arthur_to_linux_signals, + .signal_invmap = linux_to_arthur_signals, + .module = THIS_MODULE, +}; + +/* + * We could do with some locking to stop Arthur being removed while + * processes are using it. + */ + +static int __init arthur_init(void) +{ + return register_exec_domain(&arthur_exec_domain); +} + +static void __exit arthur_exit(void) +{ + unregister_exec_domain(&arthur_exec_domain); +} + +module_init(arthur_init); +module_exit(arthur_exit); diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c new file mode 100644 index 0000000..99d4325 --- /dev/null +++ b/arch/arm/kernel/asm-offsets.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1995-2003 Russell King + * 2001-2002 Keith Owens + * + * Generate definitions needed by assembly language modules. + * This code generates raw asm output which is post-processed to extract + * and format the required data. + * + * 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/sched.h> +#include <linux/mm.h> +#include <asm/mach/arch.h> +#include <asm/thread_info.h> +#include <asm/memory.h> + +/* + * Make sure that the compiler and target are compatible. + */ +#if defined(__APCS_26__) +#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32 +#endif +/* + * GCC 2.95.1, 2.95.2: ignores register clobber list in asm(). + * GCC 3.0, 3.1: general bad code generation. + * GCC 3.2.0: incorrect function argument offset calculation. + * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c + * (http://gcc.gnu.org/PR8896) and incorrect structure + * initialisation in fs/jffs2/erase.c + */ +#if __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \ + (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \ + __GNUC_PATCHLEVEL__ < 3) || \ + (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +#error Your compiler is too buggy; it is known to miscompile kernels. +#error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3 +#endif + +/* Use marker if you need to separate the values later */ + +#define DEFINE(sym, val) \ + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define BLANK() asm volatile("\n->" : : ) + +int main(void) +{ + DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); + BLANK(); + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); + DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); + DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); + DEFINE(TI_TASK, offsetof(struct thread_info, task)); + DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); + DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); + DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain)); + DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context)); + DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp)); + DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); + DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate)); + DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); + DEFINE(TI_IWMMXT_STATE, (offsetof(struct thread_info, fpstate)+4)&~7); + BLANK(); +#if __LINUX_ARM_ARCH__ >= 6 + DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); + BLANK(); +#endif + DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); + DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags)); + BLANK(); + DEFINE(VM_EXEC, VM_EXEC); + BLANK(); + DEFINE(PAGE_SZ, PAGE_SIZE); + DEFINE(VIRT_OFFSET, PAGE_OFFSET); + BLANK(); + DEFINE(SYS_ERROR0, 0x9f0000); + BLANK(); + DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); + return 0; +} diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c new file mode 100644 index 0000000..ad26e98 --- /dev/null +++ b/arch/arm/kernel/bios32.c @@ -0,0 +1,699 @@ +/* + * linux/arch/arm/kernel/bios32.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/slab.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/mach/pci.h> + +static int debug_pci; +static int use_firmware; + +/* + * We can't use pci_find_device() here since we are + * called from interrupt context. + */ +static void pcibios_bus_report_status(struct pci_bus *bus, u_int status_mask, int warn) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + u16 status; + + /* + * ignore host bridge - we handle + * that separately + */ + if (dev->bus->number == 0 && dev->devfn == 0) + continue; + + pci_read_config_word(dev, PCI_STATUS, &status); + if (status == 0xffff) + continue; + + if ((status & status_mask) == 0) + continue; + + /* clear the status errors */ + pci_write_config_word(dev, PCI_STATUS, status & status_mask); + + if (warn) + printk("(%s: %04X) ", pci_name(dev), status); + } + + list_for_each_entry(dev, &bus->devices, bus_list) + if (dev->subordinate) + pcibios_bus_report_status(dev->subordinate, status_mask, warn); +} + +void pcibios_report_status(u_int status_mask, int warn) +{ + struct list_head *l; + + list_for_each(l, &pci_root_buses) { + struct pci_bus *bus = pci_bus_b(l); + + pcibios_bus_report_status(bus, status_mask, warn); + } +} + +/* + * We don't use this to fix the device, but initialisation of it. + * It's not the correct use for this, but it works. + * Note that the arbiter/ISA bridge appears to be buggy, specifically in + * the following area: + * 1. park on CPU + * 2. ISA bridge ping-pong + * 3. ISA bridge master handling of target RETRY + * + * Bug 3 is responsible for the sound DMA grinding to a halt. We now + * live with bug 2. + */ +static void __devinit pci_fixup_83c553(struct pci_dev *dev) +{ + /* + * Set memory region to start at address 0, and enable IO + */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO); + + dev->resource[0].end -= dev->resource[0].start; + dev->resource[0].start = 0; + + /* + * All memory requests from ISA to be channelled to PCI + */ + pci_write_config_byte(dev, 0x48, 0xff); + + /* + * Enable ping-pong on bus master to ISA bridge transactions. + * This improves the sound DMA substantially. The fixed + * priority arbiter also helps (see below). + */ + pci_write_config_byte(dev, 0x42, 0x01); + + /* + * Enable PCI retry + */ + pci_write_config_byte(dev, 0x40, 0x22); + + /* + * We used to set the arbiter to "park on last master" (bit + * 1 set), but unfortunately the CyberPro does not park the + * bus. We must therefore park on CPU. Unfortunately, this + * may trigger yet another bug in the 553. + */ + pci_write_config_byte(dev, 0x83, 0x02); + + /* + * Make the ISA DMA request lowest priority, and disable + * rotating priorities completely. + */ + pci_write_config_byte(dev, 0x80, 0x11); + pci_write_config_byte(dev, 0x81, 0x00); + + /* + * Route INTA input to IRQ 11, and set IRQ11 to be level + * sensitive. + */ + pci_write_config_word(dev, 0x44, 0xb000); + outb(0x08, 0x4d1); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, pci_fixup_83c553); + +static void __devinit pci_fixup_unassign(struct pci_dev *dev) +{ + dev->resource[0].end -= dev->resource[0].start; + dev->resource[0].start = 0; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F, pci_fixup_unassign); + +/* + * Prevent the PCI layer from seeing the resources allocated to this device + * if it is the host bridge by marking it as such. These resources are of + * no consequence to the PCI layer (they are handled elsewhere). + */ +static void __devinit pci_fixup_dec21285(struct pci_dev *dev) +{ + int i; + + if (dev->devfn == 0) { + dev->class &= 0xff; + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, pci_fixup_dec21285); + +/* + * Same as above. The PrPMC800 carrier board for the PrPMC1100 + * card maps the host-bridge @ 00:01:00 for some reason and it + * ends up getting scanned. Note that we only want to do this + * fixup when we find the IXP4xx on a PrPMC system, which is why + * we check the machine type. We could be running on a board + * with an IXP4xx target device and we don't want to kill the + * resources in that case. + */ +static void __devinit pci_fixup_prpmc1100(struct pci_dev *dev) +{ + int i; + + if (machine_is_prpmc1100()) { + dev->class &= 0xff; + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP4XX, pci_fixup_prpmc1100); + +/* + * PCI IDE controllers use non-standard I/O port decoding, respect it. + */ +static void __devinit pci_fixup_ide_bases(struct pci_dev *dev) +{ + struct resource *r; + int i; + + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + r = dev->resource + i; + if ((r->start & ~0x80) == 0x374) { + r->start |= 2; + r->end = r->start; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); + +/* + * Put the DEC21142 to sleep + */ +static void __devinit pci_fixup_dec21142(struct pci_dev *dev) +{ + pci_write_config_dword(dev, 0x40, 0x80000000); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, pci_fixup_dec21142); + +/* + * The CY82C693 needs some rather major fixups to ensure that it does + * the right thing. Idea from the Alpha people, with a few additions. + * + * We ensure that the IDE base registers are set to 1f0/3f4 for the + * primary bus, and 170/374 for the secondary bus. Also, hide them + * from the PCI subsystem view as well so we won't try to perform + * our own auto-configuration on them. + * + * In addition, we ensure that the PCI IDE interrupts are routed to + * IRQ 14 and IRQ 15 respectively. + * + * The above gets us to a point where the IDE on this device is + * functional. However, The CY82C693U _does not work_ in bus + * master mode without locking the PCI bus solid. + */ +static void __devinit pci_fixup_cy82c693(struct pci_dev *dev) +{ + if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { + u32 base0, base1; + + if (dev->class & 0x80) { /* primary */ + base0 = 0x1f0; + base1 = 0x3f4; + } else { /* secondary */ + base0 = 0x170; + base1 = 0x374; + } + + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + base0 | PCI_BASE_ADDRESS_SPACE_IO); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, + base1 | PCI_BASE_ADDRESS_SPACE_IO); + + dev->resource[0].start = 0; + dev->resource[0].end = 0; + dev->resource[0].flags = 0; + + dev->resource[1].start = 0; + dev->resource[1].end = 0; + dev->resource[1].flags = 0; + } else if (PCI_FUNC(dev->devfn) == 0) { + /* + * Setup IDE IRQ routing. + */ + pci_write_config_byte(dev, 0x4b, 14); + pci_write_config_byte(dev, 0x4c, 15); + + /* + * Disable FREQACK handshake, enable USB. + */ + pci_write_config_byte(dev, 0x4d, 0x41); + + /* + * Enable PCI retry, and PCI post-write buffer. + */ + pci_write_config_byte(dev, 0x44, 0x17); + + /* + * Enable ISA master and DMA post write buffering. + */ + pci_write_config_byte(dev, 0x45, 0x03); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693); + +void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) +{ + if (debug_pci) + printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev)); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + +/* + * If the bus contains any of these devices, then we must not turn on + * parity checking of any kind. Currently this is CyberPro 20x0 only. + */ +static inline int pdev_bad_for_parity(struct pci_dev *dev) +{ + return (dev->vendor == PCI_VENDOR_ID_INTERG && + (dev->device == PCI_DEVICE_ID_INTERG_2000 || + dev->device == PCI_DEVICE_ID_INTERG_2010)); +} + +/* + * Adjust the device resources from bus-centric to Linux-centric. + */ +static void __devinit +pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) +{ + unsigned long offset; + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + if (dev->resource[i].start == 0) + continue; + if (dev->resource[i].flags & IORESOURCE_MEM) + offset = root->mem_offset; + else + offset = root->io_offset; + + dev->resource[i].start += offset; + dev->resource[i].end += offset; + } +} + +static void __devinit +pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root) +{ + struct pci_dev *dev = bus->self; + int i; + + if (!dev) { + /* + * Assign root bus resources. + */ + for (i = 0; i < 3; i++) + bus->resource[i] = root->resource[i]; + } +} + +/* + * pcibios_fixup_bus - Called after each bus is probed, + * but before its children are examined. + */ +void __devinit pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_sys_data *root = bus->sysdata; + struct pci_dev *dev; + u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK; + + pbus_assign_bus_resources(bus, root); + + /* + * Walk the devices on this bus, working out what we can + * and can't support. + */ + list_for_each_entry(dev, &bus->devices, bus_list) { + u16 status; + + pdev_fixup_device_resources(root, dev); + + pci_read_config_word(dev, PCI_STATUS, &status); + + /* + * If any device on this bus does not support fast back + * to back transfers, then the bus as a whole is not able + * to support them. Having fast back to back transfers + * on saves us one PCI cycle per transaction. + */ + if (!(status & PCI_STATUS_FAST_BACK)) + features &= ~PCI_COMMAND_FAST_BACK; + + if (pdev_bad_for_parity(dev)) + features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); + + switch (dev->class >> 8) { +#if defined(CONFIG_ISA) || defined(CONFIG_EISA) + case PCI_CLASS_BRIDGE_ISA: + case PCI_CLASS_BRIDGE_EISA: + /* + * If this device is an ISA bridge, set isa_bridge + * to point at this device. We will then go looking + * for things like keyboard, etc. + */ + isa_bridge = dev; + break; +#endif + case PCI_CLASS_BRIDGE_PCI: + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status); + status |= PCI_BRIDGE_CTL_PARITY|PCI_BRIDGE_CTL_MASTER_ABORT; + status &= ~(PCI_BRIDGE_CTL_BUS_RESET|PCI_BRIDGE_CTL_FAST_BACK); + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, status); + break; + + case PCI_CLASS_BRIDGE_CARDBUS: + pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL, &status); + status |= PCI_CB_BRIDGE_CTL_PARITY|PCI_CB_BRIDGE_CTL_MASTER_ABORT; + pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL, status); + break; + } + } + + /* + * Now walk the devices again, this time setting them up. + */ + list_for_each_entry(dev, &bus->devices, bus_list) { + u16 cmd; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= features; + pci_write_config_word(dev, PCI_COMMAND, cmd); + + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, + L1_CACHE_BYTES >> 2); + } + + /* + * Propagate the flags to the PCI bridge. + */ + if (bus->self && bus->self->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + if (features & PCI_COMMAND_FAST_BACK) + bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK; + if (features & PCI_COMMAND_PARITY) + bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY; + } + + /* + * Report what we did for this bus + */ + printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", + bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); +} + +/* + * Convert from Linux-centric to bus-centric addresses for bridge devices. + */ +void __devinit +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res) +{ + struct pci_sys_data *root = dev->sysdata; + unsigned long offset = 0; + + if (res->flags & IORESOURCE_IO) + offset = root->io_offset; + if (res->flags & IORESOURCE_MEM) + offset = root->mem_offset; + + region->start = res->start - offset; + region->end = res->end - offset; +} + +#ifdef CONFIG_HOTPLUG +EXPORT_SYMBOL(pcibios_fixup_bus); +EXPORT_SYMBOL(pcibios_resource_to_bus); +#endif + +/* + * This is the standard PCI-PCI bridge swizzling algorithm: + * + * Dev: 0 1 2 3 + * A A B C D + * B B C D A + * C C D A B + * D D A B C + * ^^^^^^^^^^ irq pin on bridge + */ +u8 __devinit pci_std_swizzle(struct pci_dev *dev, u8 *pinp) +{ + int pin = *pinp - 1; + + while (dev->bus->self) { + pin = (pin + PCI_SLOT(dev->devfn)) & 3; + /* + * move up the chain of bridges, + * swizzling as we go. + */ + dev = dev->bus->self; + } + *pinp = pin + 1; + + return PCI_SLOT(dev->devfn); +} + +/* + * Swizzle the device pin each time we cross a bridge. + * This might update pin and returns the slot number. + */ +static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin) +{ + struct pci_sys_data *sys = dev->sysdata; + int slot = 0, oldpin = *pin; + + if (sys->swizzle) + slot = sys->swizzle(dev, pin); + + if (debug_pci) + printk("PCI: %s swizzling pin %d => pin %d slot %d\n", + pci_name(dev), oldpin, *pin, slot); + + return slot; +} + +/* + * Map a slot/pin to an IRQ. + */ +static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + struct pci_sys_data *sys = dev->sysdata; + int irq = -1; + + if (sys->map_irq) + irq = sys->map_irq(dev, slot, pin); + + if (debug_pci) + printk("PCI: %s mapping slot %d pin %d => irq %d\n", + pci_name(dev), slot, pin, irq); + + return irq; +} + +static void __init pcibios_init_hw(struct hw_pci *hw) +{ + struct pci_sys_data *sys = NULL; + int ret; + int nr, busnr; + + for (nr = busnr = 0; nr < hw->nr_controllers; nr++) { + sys = kmalloc(sizeof(struct pci_sys_data), GFP_KERNEL); + if (!sys) + panic("PCI: unable to allocate sys data!"); + + memset(sys, 0, sizeof(struct pci_sys_data)); + + sys->hw = hw; + sys->busnr = busnr; + sys->swizzle = hw->swizzle; + sys->map_irq = hw->map_irq; + sys->resource[0] = &ioport_resource; + sys->resource[1] = &iomem_resource; + + ret = hw->setup(nr, sys); + + if (ret > 0) { + sys->bus = hw->scan(nr, sys); + + if (!sys->bus) + panic("PCI: unable to scan bus!"); + + busnr = sys->bus->subordinate + 1; + + list_add(&sys->node, &hw->buses); + } else { + kfree(sys); + if (ret < 0) + break; + } + } +} + +void __init pci_common_init(struct hw_pci *hw) +{ + struct pci_sys_data *sys; + + INIT_LIST_HEAD(&hw->buses); + + if (hw->preinit) + hw->preinit(); + pcibios_init_hw(hw); + if (hw->postinit) + hw->postinit(); + + pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq); + + list_for_each_entry(sys, &hw->buses, node) { + struct pci_bus *bus = sys->bus; + + if (!use_firmware) { + /* + * Size the bridge windows. + */ + pci_bus_size_bridges(bus); + + /* + * Assign resources. + */ + pci_bus_assign_resources(bus); + } + + /* + * Tell drivers about devices found. + */ + pci_bus_add_devices(bus); + } +} + +char * __init pcibios_setup(char *str) +{ + if (!strcmp(str, "debug")) { + debug_pci = 1; + return NULL; + } else if (!strcmp(str, "firmware")) { + use_firmware = 1; + return NULL; + } + return str; +} + +/* + * From arch/i386/kernel/pci-i386.c: + * + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might be mirrored at 0x0100-0x03ff.. + */ +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + unsigned long start = res->start; + + if (res->flags & IORESOURCE_IO && start & 0x300) + start = (start + 0x3ff) & ~0x3ff; + + res->start = (start + align - 1) & ~(align - 1); +} + +/** + * pcibios_enable_device - Enable I/O and memory. + * @dev: PCI device to be enabled + */ +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1 << idx))) + continue; + + r = dev->resource + idx; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because" + " of resource collisions\n", pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + + /* + * Bridges (eg, cardbus bridges) need to be fully enabled + */ + if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) + cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + + if (cmd != old_cmd) { + printk("PCI: enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine) +{ + struct pci_sys_data *root = dev->sysdata; + unsigned long phys; + + if (mmap_state == pci_mmap_io) { + return -EINVAL; + } else { + phys = vma->vm_pgoff + (root->mem_offset >> PAGE_SHIFT); + } + + /* + * Mark this as IO + */ + vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, phys, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) + return -EAGAIN; + + return 0; +} diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S new file mode 100644 index 0000000..e5d370c --- /dev/null +++ b/arch/arm/kernel/calls.S @@ -0,0 +1,335 @@ +/* + * linux/arch/arm/kernel/calls.S + * + * Copyright (C) 1995-2005 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. + * + * This file is included twice in entry-common.S + */ +#ifndef NR_syscalls +#define NR_syscalls 320 +#else + +__syscall_start: +/* 0 */ .long sys_restart_syscall + .long sys_exit + .long sys_fork_wrapper + .long sys_read + .long sys_write +/* 5 */ .long sys_open + .long sys_close + .long sys_ni_syscall /* was sys_waitpid */ + .long sys_creat + .long sys_link +/* 10 */ .long sys_unlink + .long sys_execve_wrapper + .long sys_chdir + .long sys_time /* used by libc4 */ + .long sys_mknod +/* 15 */ .long sys_chmod + .long sys_lchown16 + .long sys_ni_syscall /* was sys_break */ + .long sys_ni_syscall /* was sys_stat */ + .long sys_lseek +/* 20 */ .long sys_getpid + .long sys_mount + .long sys_oldumount /* used by libc4 */ + .long sys_setuid16 + .long sys_getuid16 +/* 25 */ .long sys_stime + .long sys_ptrace + .long sys_alarm /* used by libc4 */ + .long sys_ni_syscall /* was sys_fstat */ + .long sys_pause +/* 30 */ .long sys_utime /* used by libc4 */ + .long sys_ni_syscall /* was sys_stty */ + .long sys_ni_syscall /* was sys_getty */ + .long sys_access + .long sys_nice +/* 35 */ .long sys_ni_syscall /* was sys_ftime */ + .long sys_sync + .long sys_kill + .long sys_rename + .long sys_mkdir +/* 40 */ .long sys_rmdir + .long sys_dup + .long sys_pipe + .long sys_times + .long sys_ni_syscall /* was sys_prof */ +/* 45 */ .long sys_brk + .long sys_setgid16 + .long sys_getgid16 + .long sys_ni_syscall /* was sys_signal */ + .long sys_geteuid16 +/* 50 */ .long sys_getegid16 + .long sys_acct + .long sys_umount + .long sys_ni_syscall /* was sys_lock */ + .long sys_ioctl +/* 55 */ .long sys_fcntl + .long sys_ni_syscall /* was sys_mpx */ + .long sys_setpgid + .long sys_ni_syscall /* was sys_ulimit */ + .long sys_ni_syscall /* was sys_olduname */ +/* 60 */ .long sys_umask + .long sys_chroot + .long sys_ustat + .long sys_dup2 + .long sys_getppid +/* 65 */ .long sys_getpgrp + .long sys_setsid + .long sys_sigaction + .long sys_ni_syscall /* was sys_sgetmask */ + .long sys_ni_syscall /* was sys_ssetmask */ +/* 70 */ .long sys_setreuid16 + .long sys_setregid16 + .long sys_sigsuspend_wrapper + .long sys_sigpending + .long sys_sethostname +/* 75 */ .long sys_setrlimit + .long sys_old_getrlimit /* used by libc4 */ + .long sys_getrusage + .long sys_gettimeofday + .long sys_settimeofday +/* 80 */ .long sys_getgroups16 + .long sys_setgroups16 + .long old_select /* used by libc4 */ + .long sys_symlink + .long sys_ni_syscall /* was sys_lstat */ +/* 85 */ .long sys_readlink + .long sys_uselib + .long sys_swapon + .long sys_reboot + .long old_readdir /* used by libc4 */ +/* 90 */ .long old_mmap /* used by libc4 */ + .long sys_munmap + .long sys_truncate + .long sys_ftruncate + .long sys_fchmod +/* 95 */ .long sys_fchown16 + .long sys_getpriority + .long sys_setpriority + .long sys_ni_syscall /* was sys_profil */ + .long sys_statfs +/* 100 */ .long sys_fstatfs + .long sys_ni_syscall + .long sys_socketcall + .long sys_syslog + .long sys_setitimer +/* 105 */ .long sys_getitimer + .long sys_newstat + .long sys_newlstat + .long sys_newfstat + .long sys_ni_syscall /* was sys_uname */ +/* 110 */ .long sys_ni_syscall /* was sys_iopl */ + .long sys_vhangup + .long sys_ni_syscall + .long sys_syscall /* call a syscall */ + .long sys_wait4 +/* 115 */ .long sys_swapoff + .long sys_sysinfo + .long sys_ipc + .long sys_fsync + .long sys_sigreturn_wrapper +/* 120 */ .long sys_clone_wrapper + .long sys_setdomainname + .long sys_newuname + .long sys_ni_syscall + .long sys_adjtimex +/* 125 */ .long sys_mprotect + .long sys_sigprocmask + .long sys_ni_syscall /* was sys_create_module */ + .long sys_init_module + .long sys_delete_module +/* 130 */ .long sys_ni_syscall /* was sys_get_kernel_syms */ + .long sys_quotactl + .long sys_getpgid + .long sys_fchdir + .long sys_bdflush +/* 135 */ .long sys_sysfs + .long sys_personality + .long sys_ni_syscall /* .long _sys_afs_syscall */ + .long sys_setfsuid16 + .long sys_setfsgid16 +/* 140 */ .long sys_llseek + .long sys_getdents + .long sys_select + .long sys_flock + .long sys_msync +/* 145 */ .long sys_readv + .long sys_writev + .long sys_getsid + .long sys_fdatasync + .long sys_sysctl +/* 150 */ .long sys_mlock + .long sys_munlock + .long sys_mlockall + .long sys_munlockall + .long sys_sched_setparam +/* 155 */ .long sys_sched_getparam + .long sys_sched_setscheduler + .long sys_sched_getscheduler + .long sys_sched_yield + .long sys_sched_get_priority_max +/* 160 */ .long sys_sched_get_priority_min + .long sys_sched_rr_get_interval + .long sys_nanosleep + .long sys_arm_mremap + .long sys_setresuid16 +/* 165 */ .long sys_getresuid16 + .long sys_ni_syscall + .long sys_ni_syscall /* was sys_query_module */ + .long sys_poll + .long sys_nfsservctl +/* 170 */ .long sys_setresgid16 + .long sys_getresgid16 + .long sys_prctl + .long sys_rt_sigreturn_wrapper + .long sys_rt_sigaction +/* 175 */ .long sys_rt_sigprocmask + .long sys_rt_sigpending + .long sys_rt_sigtimedwait + .long sys_rt_sigqueueinfo + .long sys_rt_sigsuspend_wrapper +/* 180 */ .long sys_pread64 + .long sys_pwrite64 + .long sys_chown16 + .long sys_getcwd + .long sys_capget +/* 185 */ .long sys_capset + .long sys_sigaltstack_wrapper + .long sys_sendfile + .long sys_ni_syscall + .long sys_ni_syscall +/* 190 */ .long sys_vfork_wrapper + .long sys_getrlimit + .long sys_mmap2 + .long sys_truncate64 + .long sys_ftruncate64 +/* 195 */ .long sys_stat64 + .long sys_lstat64 + .long sys_fstat64 + .long sys_lchown + .long sys_getuid +/* 200 */ .long sys_getgid + .long sys_geteuid + .long sys_getegid + .long sys_setreuid + .long sys_setregid +/* 205 */ .long sys_getgroups + .long sys_setgroups + .long sys_fchown + .long sys_setresuid + .long sys_getresuid +/* 210 */ .long sys_setresgid + .long sys_getresgid + .long sys_chown + .long sys_setuid + .long sys_setgid +/* 215 */ .long sys_setfsuid + .long sys_setfsgid + .long sys_getdents64 + .long sys_pivot_root + .long sys_mincore +/* 220 */ .long sys_madvise + .long sys_fcntl64 + .long sys_ni_syscall /* TUX */ + .long sys_ni_syscall + .long sys_gettid +/* 225 */ .long sys_readahead + .long sys_setxattr + .long sys_lsetxattr + .long sys_fsetxattr + .long sys_getxattr +/* 230 */ .long sys_lgetxattr + .long sys_fgetxattr + .long sys_listxattr + .long sys_llistxattr + .long sys_flistxattr +/* 235 */ .long sys_removexattr + .long sys_lremovexattr + .long sys_fremovexattr + .long sys_tkill + .long sys_sendfile64 +/* 240 */ .long sys_futex_wrapper + .long sys_sched_setaffinity + .long sys_sched_getaffinity + .long sys_io_setup + .long sys_io_destroy +/* 245 */ .long sys_io_getevents + .long sys_io_submit + .long sys_io_cancel + .long sys_exit_group + .long sys_lookup_dcookie +/* 250 */ .long sys_epoll_create + .long sys_epoll_ctl + .long sys_epoll_wait + .long sys_remap_file_pages + .long sys_ni_syscall /* sys_set_thread_area */ +/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ + .long sys_set_tid_address + .long sys_timer_create + .long sys_timer_settime + .long sys_timer_gettime +/* 260 */ .long sys_timer_getoverrun + .long sys_timer_delete + .long sys_clock_settime + .long sys_clock_gettime + .long sys_clock_getres +/* 265 */ .long sys_clock_nanosleep + .long sys_statfs64 + .long sys_fstatfs64 + .long sys_tgkill + .long sys_utimes +/* 270 */ .long sys_fadvise64_64 + .long sys_pciconfig_iobase + .long sys_pciconfig_read + .long sys_pciconfig_write + .long sys_mq_open +/* 275 */ .long sys_mq_unlink + .long sys_mq_timedsend + .long sys_mq_timedreceive + .long sys_mq_notify + .long sys_mq_getsetattr +/* 280 */ .long sys_waitid + .long sys_socket + .long sys_bind + .long sys_connect + .long sys_listen +/* 285 */ .long sys_accept + .long sys_getsockname + .long sys_getpeername + .long sys_socketpair + .long sys_send +/* 290 */ .long sys_sendto + .long sys_recv + .long sys_recvfrom + .long sys_shutdown + .long sys_setsockopt +/* 295 */ .long sys_getsockopt + .long sys_sendmsg + .long sys_recvmsg + .long sys_semop + .long sys_semget +/* 300 */ .long sys_semctl + .long sys_msgsnd + .long sys_msgrcv + .long sys_msgget + .long sys_msgctl +/* 305 */ .long sys_shmat + .long sys_shmdt + .long sys_shmget + .long sys_shmctl + .long sys_add_key +/* 310 */ .long sys_request_key + .long sys_keyctl + .long sys_semtimedop +__syscall_end: + + .rept NR_syscalls - (__syscall_end - __syscall_start) / 4 + .long sys_ni_syscall + .endr +#endif diff --git a/arch/arm/kernel/compat.c b/arch/arm/kernel/compat.c new file mode 100644 index 0000000..7195add --- /dev/null +++ b/arch/arm/kernel/compat.c @@ -0,0 +1,225 @@ +/* + * linux/arch/arm/kernel/compat.c + * + * Copyright (C) 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. + * + * We keep the old params compatibility cruft in one place (here) + * so we don't end up with lots of mess around other places. + * + * NOTE: + * The old struct param_struct is deprecated, but it will be kept in + * the kernel for 5 years from now (2001). This will allow boot loaders + * to convert to the new struct tag way. + */ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/init.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/page.h> + +#include <asm/mach/arch.h> + +/* + * Usage: + * - do not go blindly adding fields, add them at the end + * - when adding fields, don't rely on the address until + * a patch from me has been released + * - unused fields should be zero (for future expansion) + * - this structure is relatively short-lived - only + * guaranteed to contain useful data in setup_arch() + * + * This is the old deprecated way to pass parameters to the kernel + */ +struct param_struct { + union { + struct { + unsigned long page_size; /* 0 */ + unsigned long nr_pages; /* 4 */ + unsigned long ramdisk_size; /* 8 */ + unsigned long flags; /* 12 */ +#define FLAG_READONLY 1 +#define FLAG_RDLOAD 4 +#define FLAG_RDPROMPT 8 + unsigned long rootdev; /* 16 */ + unsigned long video_num_cols; /* 20 */ + unsigned long video_num_rows; /* 24 */ + unsigned long video_x; /* 28 */ + unsigned long video_y; /* 32 */ + unsigned long memc_control_reg; /* 36 */ + unsigned char sounddefault; /* 40 */ + unsigned char adfsdrives; /* 41 */ + unsigned char bytes_per_char_h; /* 42 */ + unsigned char bytes_per_char_v; /* 43 */ + unsigned long pages_in_bank[4]; /* 44 */ + unsigned long pages_in_vram; /* 60 */ + unsigned long initrd_start; /* 64 */ + unsigned long initrd_size; /* 68 */ + unsigned long rd_start; /* 72 */ + unsigned long system_rev; /* 76 */ + unsigned long system_serial_low; /* 80 */ + unsigned long system_serial_high; /* 84 */ + unsigned long mem_fclk_21285; /* 88 */ + } s; + char unused[256]; + } u1; + union { + char paths[8][128]; + struct { + unsigned long magic; + char n[1024 - sizeof(unsigned long)]; + } s; + } u2; + char commandline[COMMAND_LINE_SIZE]; +}; + +static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size) +{ + tag = tag_next(tag); + tag->hdr.tag = ATAG_MEM; + tag->hdr.size = tag_size(tag_mem32); + tag->u.mem.size = size; + tag->u.mem.start = start; + + return tag; +} + +static void __init build_tag_list(struct param_struct *params, void *taglist) +{ + struct tag *tag = taglist; + + if (params->u1.s.page_size != PAGE_SIZE) { + printk(KERN_WARNING "Warning: bad configuration page, " + "trying to continue\n"); + return; + } + + printk(KERN_DEBUG "Converting old-style param struct to taglist\n"); + +#ifdef CONFIG_ARCH_NETWINDER + 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"); + + params->u1.s.nr_pages = 0x1000; /* 16MB */ + params->u1.s.ramdisk_size = 0; + params->u1.s.flags = FLAG_READONLY; + params->u1.s.initrd_start = 0; + params->u1.s.initrd_size = 0; + params->u1.s.rd_start = 0; + } +#endif + + tag->hdr.tag = ATAG_CORE; + tag->hdr.size = tag_size(tag_core); + tag->u.core.flags = params->u1.s.flags & FLAG_READONLY; + tag->u.core.pagesize = params->u1.s.page_size; + tag->u.core.rootdev = params->u1.s.rootdev; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_RAMDISK; + tag->hdr.size = tag_size(tag_ramdisk); + tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) | + (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0); + tag->u.ramdisk.size = params->u1.s.ramdisk_size; + tag->u.ramdisk.start = params->u1.s.rd_start; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_INITRD; + tag->hdr.size = tag_size(tag_initrd); + tag->u.initrd.start = params->u1.s.initrd_start; + tag->u.initrd.size = params->u1.s.initrd_size; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_SERIAL; + tag->hdr.size = tag_size(tag_serialnr); + tag->u.serialnr.low = params->u1.s.system_serial_low; + tag->u.serialnr.high = params->u1.s.system_serial_high; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_REVISION; + tag->hdr.size = tag_size(tag_revision); + tag->u.revision.rev = params->u1.s.system_rev; + +#ifdef CONFIG_ARCH_ACORN + if (machine_is_riscpc()) { + int i; + for (i = 0; i < 4; i++) + tag = memtag(tag, PHYS_OFFSET + (i << 26), + params->u1.s.pages_in_bank[i] * PAGE_SIZE); + } else +#endif + tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE); + +#ifdef CONFIG_FOOTBRIDGE + if (params->u1.s.mem_fclk_21285) { + tag = tag_next(tag); + tag->hdr.tag = ATAG_MEMCLK; + tag->hdr.size = tag_size(tag_memclk); + tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285; + } +#endif + +#ifdef CONFIG_ARCH_EBSA285 + if (machine_is_ebsa285()) { + tag = tag_next(tag); + tag->hdr.tag = ATAG_VIDEOTEXT; + tag->hdr.size = tag_size(tag_videotext); + tag->u.videotext.x = params->u1.s.video_x; + tag->u.videotext.y = params->u1.s.video_y; + tag->u.videotext.video_page = 0; + tag->u.videotext.video_mode = 0; + tag->u.videotext.video_cols = params->u1.s.video_num_cols; + tag->u.videotext.video_ega_bx = 0; + tag->u.videotext.video_lines = params->u1.s.video_num_rows; + tag->u.videotext.video_isvga = 1; + tag->u.videotext.video_points = 8; + } +#endif + +#ifdef CONFIG_ARCH_ACORN + tag = tag_next(tag); + tag->hdr.tag = ATAG_ACORN; + tag->hdr.size = tag_size(tag_acorn); + tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg; + tag->u.acorn.vram_pages = params->u1.s.pages_in_vram; + tag->u.acorn.sounddefault = params->u1.s.sounddefault; + tag->u.acorn.adfsdrives = params->u1.s.adfsdrives; +#endif + + tag = tag_next(tag); + tag->hdr.tag = ATAG_CMDLINE; + tag->hdr.size = (strlen(params->commandline) + 3 + + sizeof(struct tag_header)) >> 2; + strcpy(tag->u.cmdline.cmdline, params->commandline); + + tag = tag_next(tag); + tag->hdr.tag = ATAG_NONE; + tag->hdr.size = 0; + + memmove(params, taglist, ((int)tag) - ((int)taglist) + + sizeof(struct tag_header)); +} + +void __init convert_to_tag_list(struct tag *tags) +{ + struct param_struct *params = (struct param_struct *)tags; + build_tag_list(params, ¶ms->u2); +} + +void __init squash_mem_tags(struct tag *tag) +{ + for (; tag->hdr.size; tag = tag_next(tag)) + if (tag->hdr.tag == ATAG_MEM) + tag->hdr.tag = ATAG_NONE; +} diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S new file mode 100644 index 0000000..caaa919 --- /dev/null +++ b/arch/arm/kernel/debug.S @@ -0,0 +1,106 @@ +/* + * linux/arch/arm/kernel/debug.S + * + * Copyright (C) 1994-1999 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. + * + * 32-bit debugging code + */ +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/hardware.h> + + .text + +/* + * Some debugging routines (useful if you've got MM problems and + * printk isn't working). For DEBUGGING ONLY!!! Do not leave + * references to these in a production kernel! + */ + +#if defined(CONFIG_DEBUG_ICEDCC) + @@ debug using ARM EmbeddedICE DCC channel + .macro addruart, rx + .endm + + .macro senduart, rd, rx + mcr p14, 0, \rd, c1, c0, 0 + .endm + + .macro busyuart, rd, rx +1001: + mrc p14, 0, \rx, c0, c0, 0 + tst \rx, #2 + beq 1001b + + .endm + + .macro waituart, rd, rx + mov \rd, #0x2000000 +1001: + subs \rd, \rd, #1 + bmi 1002f + mrc p14, 0, \rx, c0, c0, 0 + tst \rx, #2 + bne 1001b +1002: + .endm +#else +#include <asm/arch/debug-macro.S> +#endif + +/* + * Useful debugging routines + */ +ENTRY(printhex8) + mov r1, #8 + b printhex + +ENTRY(printhex4) + mov r1, #4 + b printhex + +ENTRY(printhex2) + mov r1, #2 +printhex: adr r2, hexbuf + add r3, r2, r1 + mov r1, #0 + strb r1, [r3] +1: and r1, r0, #15 + mov r0, r0, lsr #4 + cmp r1, #10 + addlt r1, r1, #'0' + addge r1, r1, #'a' - 10 + strb r1, [r3, #-1]! + teq r3, r2 + bne 1b + mov r0, r2 + b printascii + + .ltorg + +ENTRY(printascii) + addruart r3 + b 2f +1: waituart r2, r3 + senduart r1, r3 + busyuart r2, r3 + teq r1, #'\n' + moveq r1, #'\r' + beq 1b +2: teq r0, #0 + ldrneb r1, [r0], #1 + teqne r1, #0 + bne 1b + mov pc, lr + +ENTRY(printch) + addruart r3 + mov r1, r0 + mov r0, #0 + b 1b + +hexbuf: .space 16 diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c new file mode 100644 index 0000000..e9a3630 --- /dev/null +++ b/arch/arm/kernel/dma-isa.c @@ -0,0 +1,207 @@ +/* + * linux/arch/arm/kernel/dma-isa.c + * + * Copyright (C) 1999-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. + * + * ISA DMA primitives + * 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. + * arch/arm/kernel/dma-ebsa285.c + * Copyright (C) 1998 Phil Blundell + */ +#include <linux/ioport.h> +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/dma.h> +#include <asm/io.h> + +#include <asm/mach/dma.h> + +#define ISA_DMA_MODE_READ 0x44 +#define ISA_DMA_MODE_WRITE 0x48 +#define ISA_DMA_MODE_CASCADE 0xc0 +#define ISA_DMA_AUTOINIT 0x10 + +#define ISA_DMA_MASK 0 +#define ISA_DMA_MODE 1 +#define ISA_DMA_CLRFF 2 +#define ISA_DMA_PGHI 3 +#define ISA_DMA_PGLO 4 +#define ISA_DMA_ADDR 5 +#define ISA_DMA_COUNT 6 + +static unsigned int isa_dma_port[8][7] = { + /* MASK MODE CLRFF PAGE_HI PAGE_LO ADDR COUNT */ + { 0x0a, 0x0b, 0x0c, 0x487, 0x087, 0x00, 0x01 }, + { 0x0a, 0x0b, 0x0c, 0x483, 0x083, 0x02, 0x03 }, + { 0x0a, 0x0b, 0x0c, 0x481, 0x081, 0x04, 0x05 }, + { 0x0a, 0x0b, 0x0c, 0x482, 0x082, 0x06, 0x07 }, + { 0xd4, 0xd6, 0xd8, 0x000, 0x000, 0xc0, 0xc2 }, + { 0xd4, 0xd6, 0xd8, 0x48b, 0x08b, 0xc4, 0xc6 }, + { 0xd4, 0xd6, 0xd8, 0x489, 0x089, 0xc8, 0xca }, + { 0xd4, 0xd6, 0xd8, 0x48a, 0x08a, 0xcc, 0xce } +}; + +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; + + count = 1 + inb(io_port); + count |= inb(io_port) << 8; + + return channel < 4 ? count : (count << 1); +} + +static void isa_enable_dma(dmach_t channel, dma_t *dma) +{ + if (dma->invalid) { + unsigned long address, length; + unsigned int mode, direction; + + mode = channel & 3; + switch (dma->dma_mode & DMA_MODE_MASK) { + case DMA_MODE_READ: + mode |= ISA_DMA_MODE_READ; + direction = PCI_DMA_FROMDEVICE; + break; + + case DMA_MODE_WRITE: + mode |= ISA_DMA_MODE_WRITE; + direction = PCI_DMA_TODEVICE; + break; + + case DMA_MODE_CASCADE: + mode |= ISA_DMA_MODE_CASCADE; + direction = PCI_DMA_BIDIRECTIONAL; + break; + + default: + direction = PCI_DMA_NONE; + break; + } + + if (!dma->using_sg) { + /* + * Cope with ISA-style drivers which expect cache + * coherence. + */ + dma->buf.dma_address = pci_map_single(NULL, + dma->buf.__address, dma->buf.length, + direction); + } + + address = dma->buf.dma_address; + length = dma->buf.length - 1; + + outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]); + outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]); + + if (channel >= 4) { + address >>= 1; + length >>= 1; + } + + outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]); + + outb(address, isa_dma_port[channel][ISA_DMA_ADDR]); + outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]); + + outb(length, isa_dma_port[channel][ISA_DMA_COUNT]); + outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]); + + if (dma->dma_mode & DMA_AUTOINIT) + mode |= ISA_DMA_AUTOINIT; + + outb(mode, isa_dma_port[channel][ISA_DMA_MODE]); + dma->invalid = 0; + } + outb(channel & 3, isa_dma_port[channel][ISA_DMA_MASK]); +} + +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 }, + { "dma2", 0x00c0, 0x00df }, + { "dma high page", 0x0480, 0x048f } +}; + +void __init isa_init_dma(dma_t *dma) +{ + /* + * Try to autodetect presence of an ISA DMA controller. + * We do some minimal initialisation, and check that + * channel 0's DMA address registers are writeable. + */ + outb(0xff, 0x0d); + outb(0xff, 0xda); + + /* + * Write high and low address, and then read them back + * in the same order. + */ + outb(0x55, 0x00); + outb(0xaa, 0x00); + + if (inb(0) == 0x55 && inb(0) == 0xaa) { + int channel, i; + + for (channel = 0; channel < 8; channel++) { + dma[channel].d_ops = &isa_dma_ops; + isa_disable_dma(channel, NULL); + } + + outb(0x40, 0x0b); + outb(0x41, 0x0b); + outb(0x42, 0x0b); + outb(0x43, 0x0b); + + outb(0xc0, 0xd6); + outb(0x41, 0xd6); + outb(0x42, 0xd6); + outb(0x43, 0xd6); + + outb(0, 0xd4); + + outb(0x10, 0x08); + 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); + */ + outb(0x30, 0x40b); + outb(0x31, 0x40b); + outb(0x32, 0x40b); + outb(0x33, 0x40b); + outb(0x31, 0x4d6); + outb(0x32, 0x4d6); + outb(0x33, 0x4d6); + + request_dma(DMA_ISA_CASCADE, "cascade"); + + for (i = 0; i < sizeof(dma_resources) / sizeof(dma_resources[0]); i++) + request_resource(&ioport_resource, dma_resources + i); + } +} diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c new file mode 100644 index 0000000..2b78838 --- /dev/null +++ b/arch/arm/kernel/dma.c @@ -0,0 +1,302 @@ +/* + * linux/arch/arm/kernel/dma.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. + * + * 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/slab.h> +#include <linux/mman.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/errno.h> + +#include <asm/dma.h> + +#include <asm/mach/dma.h> + +DEFINE_SPINLOCK(dma_spin_lock); + +#if MAX_DMA_CHANNELS > 0 + +static dma_t dma_chan[MAX_DMA_CHANNELS]; + +/* + * Get dma list for /proc/dma + */ +int get_dma_list(char *buf) +{ + dma_t *dma; + char *p = buf; + int i; + + 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 + * + * On certain platforms, we have to allocate an interrupt as well... + */ +int request_dma(dmach_t channel, const char *device_id) +{ + 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 + * + * On certain platforms, we have to free interrupt as well... + */ +void free_dma(dmach_t channel) +{ + dma_t *dma = dma_chan + channel; + + if (channel >= MAX_DMA_CHANNELS || !dma->d_ops) + goto bad_dma; + + if (dma->active) { + printk(KERN_ERR "dma%d: freeing active DMA\n", channel); + dma->d_ops->disable(channel, dma); + dma->active = 0; + } + + if (xchg(&dma->lock, 0) != 0) { + if (dma->d_ops->free) + dma->d_ops->free(channel, dma); + return; + } + + 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, struct scatterlist *sg, int nr_sg) +{ + dma_t *dma = dma_chan + channel; + + if (dma->active) + printk(KERN_ERR "dma%d: altering DMA SG while " + "DMA active\n", channel); + + dma->sg = sg; + dma->sgcount = nr_sg; + dma->using_sg = 1; + dma->invalid = 1; +} + +/* Set DMA address + * + * Copy address to the structure, and set the invalid bit + */ +void set_dma_addr (dmach_t channel, unsigned long physaddr) +{ + 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 = bus_to_virt(physaddr); + dma->using_sg = 0; + dma->invalid = 1; +} + +/* Set DMA byte count + * + * Copy address to the structure, and set the invalid bit + */ +void set_dma_count (dmach_t channel, unsigned long count) +{ + 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->using_sg = 0; + dma->invalid = 1; +} + +/* Set DMA direction mode + */ +void set_dma_mode (dmach_t channel, dmamode_t mode) +{ + dma_t *dma = dma_chan + channel; + + if (dma->active) + printk(KERN_ERR "dma%d: altering DMA mode while " + "DMA active\n", channel); + + dma->dma_mode = mode; + dma->invalid = 1; +} + +/* Enable DMA channel + */ +void enable_dma (dmach_t 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) +{ + 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(); +} + +/* + * Is the specified DMA channel active? + */ +int dma_channel_active(dmach_t channel) +{ + return dma_chan[channel].active; +} + +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_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) +{ + 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; +} + +int get_dma_residue(dmach_t channel) +{ + return 0; +} + +#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a) +GLOBAL_ALIAS(disable_dma, get_dma_residue); +GLOBAL_ALIAS(enable_dma, get_dma_residue); +GLOBAL_ALIAS(free_dma, get_dma_residue); +GLOBAL_ALIAS(get_dma_list, get_dma_residue); +GLOBAL_ALIAS(set_dma_mode, get_dma_residue); +GLOBAL_ALIAS(set_dma_page, get_dma_residue); +GLOBAL_ALIAS(set_dma_count, get_dma_residue); +GLOBAL_ALIAS(set_dma_addr, get_dma_residue); +GLOBAL_ALIAS(set_dma_sg, get_dma_residue); +GLOBAL_ALIAS(set_dma_speed, get_dma_residue); +GLOBAL_ALIAS(init_dma, get_dma_residue); + +#endif + +EXPORT_SYMBOL(request_dma); +EXPORT_SYMBOL(free_dma); +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); + +EXPORT_SYMBOL(dma_spin_lock); diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c new file mode 100644 index 0000000..3dc15b1 --- /dev/null +++ b/arch/arm/kernel/ecard.c @@ -0,0 +1,1210 @@ +/* + * linux/arch/arm/kernel/ecard.c + * + * Copyright 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. + * + * Find all installed expansion cards, and handle interrupts from them. + * + * Created from information from Acorns RiscOS3 PRMs + * + * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether + * podule slot. + * 06-May-1997 RMK Added blacklist for cards whose loader doesn't work. + * 12-Sep-1997 RMK Created new handling of interrupt enables/disables + * - cards can now register their own routine to control + * interrupts (recommended). + * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled + * on reset from Linux. (Caused cards not to respond + * under RiscOS without hard reset). + * 15-Feb-1998 RMK Added DMA support + * 12-Sep-1998 RMK Added EASI support + * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment. + * 17-Apr-1999 RMK Support for EASI Type C cycles. + */ +#define ECARD_C + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/completion.h> +#include <linux/reboot.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/proc_fs.h> +#include <linux/device.h> +#include <linux/init.h> + +#include <asm/dma.h> +#include <asm/ecard.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mmu_context.h> +#include <asm/mach/irq.h> +#include <asm/tlbflush.h> + +#ifndef CONFIG_ARCH_RPC +#define HAVE_EXPMASK +#endif + +struct ecard_request { + void (*fn)(struct ecard_request *); + ecard_t *ec; + unsigned int address; + unsigned int length; + unsigned int use_loader; + void *buffer; + struct completion *complete; +}; + +struct expcard_blacklist { + unsigned short manufacturer; + unsigned short product; + const char *type; +}; + +static ecard_t *cards; +static ecard_t *slot_to_expcard[MAX_ECARDS]; +static unsigned int ectcr; +#ifdef HAS_EXPMASK +static unsigned int have_expmask; +#endif + +/* List of descriptions of cards which don't have an extended + * identification, or chunk directories containing a description. + */ +static struct expcard_blacklist __initdata blacklist[] = { + { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" } +}; + +asmlinkage extern int +ecard_loader_reset(unsigned long base, loader_t loader); +asmlinkage extern int +ecard_loader_read(int off, unsigned long base, loader_t loader); + +static inline unsigned short ecard_getu16(unsigned char *v) +{ + return v[0] | v[1] << 8; +} + +static inline signed long ecard_gets24(unsigned char *v) +{ + return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0); +} + +static inline ecard_t *slot_to_ecard(unsigned int slot) +{ + return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL; +} + +/* ===================== Expansion card daemon ======================== */ +/* + * Since the loader programs on the expansion cards need to be run + * in a specific environment, create a separate task with this + * environment up, and pass requests to this task as and when we + * need to. + * + * This should allow 99% of loaders to be called from Linux. + * + * From a security standpoint, we trust the card vendors. This + * may be a misplaced trust. + */ +static void ecard_task_reset(struct ecard_request *req) +{ + struct expansion_card *ec = req->ec; + struct resource *res; + + res = ec->slot_no == 8 + ? &ec->resource[ECARD_RES_MEMC] + : ec->type == ECARD_EASI + ? &ec->resource[ECARD_RES_EASI] + : &ec->resource[ECARD_RES_IOCSYNC]; + + ecard_loader_reset(res->start, ec->loader); +} + +static void ecard_task_readbytes(struct ecard_request *req) +{ + struct expansion_card *ec = req->ec; + unsigned char *buf = req->buffer; + unsigned int len = req->length; + unsigned int off = req->address; + + if (ec->slot_no == 8) { + void __iomem *base = (void __iomem *) + ec->resource[ECARD_RES_MEMC].start; + + /* + * The card maintains an index which increments the address + * into a 4096-byte page on each access. We need to keep + * track of the counter. + */ + static unsigned int index; + unsigned int page; + + page = (off >> 12) * 4; + if (page > 256 * 4) + return; + + off &= 4095; + + /* + * If we are reading offset 0, or our current index is + * greater than the offset, reset the hardware index counter. + */ + if (off == 0 || index > off) { + writeb(0, base); + index = 0; + } + + /* + * Increment the hardware index counter until we get to the + * required offset. The read bytes are discarded. + */ + while (index < off) { + readb(base + page); + index += 1; + } + + while (len--) { + *buf++ = readb(base + page); + index += 1; + } + } else { + unsigned long base = (ec->type == ECARD_EASI + ? &ec->resource[ECARD_RES_EASI] + : &ec->resource[ECARD_RES_IOCSYNC])->start; + void __iomem *pbase = (void __iomem *)base; + + if (!req->use_loader || !ec->loader) { + off *= 4; + while (len--) { + *buf++ = readb(pbase + off); + off += 4; + } + } else { + while(len--) { + /* + * The following is required by some + * expansion card loader programs. + */ + *(unsigned long *)0x108 = 0; + *buf++ = ecard_loader_read(off++, base, + ec->loader); + } + } + } + +} + +static DECLARE_WAIT_QUEUE_HEAD(ecard_wait); +static struct ecard_request *ecard_req; +static DECLARE_MUTEX(ecard_sem); + +/* + * Set up the expansion card daemon's page tables. + */ +static void ecard_init_pgtables(struct mm_struct *mm) +{ + struct vm_area_struct vma; + + /* We want to set up the page tables for the following mapping: + * Virtual Physical + * 0x03000000 0x03000000 + * 0x03010000 unmapped + * 0x03210000 0x03210000 + * 0x03400000 unmapped + * 0x08000000 0x08000000 + * 0x10000000 unmapped + * + * FIXME: we don't follow this 100% yet. + */ + pgd_t *src_pgd, *dst_pgd; + + src_pgd = pgd_offset(mm, (unsigned long)IO_BASE); + dst_pgd = pgd_offset(mm, IO_START); + + memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE)); + + src_pgd = pgd_offset(mm, EASI_BASE); + dst_pgd = pgd_offset(mm, EASI_START); + + memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE)); + + vma.vm_mm = mm; + + flush_tlb_range(&vma, IO_START, IO_START + IO_SIZE); + flush_tlb_range(&vma, EASI_START, EASI_START + EASI_SIZE); +} + +static int ecard_init_mm(void) +{ + struct mm_struct * mm = mm_alloc(); + struct mm_struct *active_mm = current->active_mm; + + if (!mm) + return -ENOMEM; + + current->mm = mm; + current->active_mm = mm; + activate_mm(active_mm, mm); + mmdrop(active_mm); + ecard_init_pgtables(mm); + return 0; +} + +static int +ecard_task(void * unused) +{ + daemonize("kecardd"); + + /* + * Allocate a mm. We're not a lazy-TLB kernel task since we need + * to set page table entries where the user space would be. Note + * that this also creates the page tables. Failure is not an + * option here. + */ + if (ecard_init_mm()) + panic("kecardd: unable to alloc mm\n"); + + while (1) { + struct ecard_request *req; + + wait_event_interruptible(ecard_wait, ecard_req != NULL); + + req = xchg(&ecard_req, NULL); + if (req != NULL) { + req->fn(req); + complete(req->complete); + } + } +} + +/* + * Wake the expansion card daemon to action our request. + * + * FIXME: The test here is not sufficient to detect if the + * kcardd is running. + */ +static void ecard_call(struct ecard_request *req) +{ + DECLARE_COMPLETION(completion); + + req->complete = &completion; + + down(&ecard_sem); + ecard_req = req; + wake_up(&ecard_wait); + + /* + * Now wait for kecardd to run. + */ + wait_for_completion(&completion); + up(&ecard_sem); +} + +/* ======================= Mid-level card control ===================== */ + +static void +ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld) +{ + struct ecard_request req; + + req.fn = ecard_task_readbytes; + req.ec = ec; + req.address = off; + req.length = len; + req.use_loader = useld; + req.buffer = addr; + + ecard_call(&req); +} + +int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num) +{ + struct ex_chunk_dir excd; + int index = 16; + int useld = 0; + + if (!ec->cid.cd) + return 0; + + while(1) { + ecard_readbytes(&excd, ec, index, 8, useld); + index += 8; + if (c_id(&excd) == 0) { + if (!useld && ec->loader) { + useld = 1; + index = 0; + continue; + } + return 0; + } + if (c_id(&excd) == 0xf0) { /* link */ + index = c_start(&excd); + continue; + } + if (c_id(&excd) == 0x80) { /* loader */ + if (!ec->loader) { + ec->loader = (loader_t)kmalloc(c_len(&excd), + GFP_KERNEL); + if (ec->loader) + ecard_readbytes(ec->loader, ec, + (int)c_start(&excd), + c_len(&excd), useld); + else + return 0; + } + continue; + } + if (c_id(&excd) == id && num-- == 0) + break; + } + + if (c_id(&excd) & 0x80) { + switch (c_id(&excd) & 0x70) { + case 0x70: + ecard_readbytes((unsigned char *)excd.d.string, ec, + (int)c_start(&excd), c_len(&excd), + useld); + break; + case 0x00: + break; + } + } + cd->start_offset = c_start(&excd); + memcpy(cd->d.string, excd.d.string, 256); + return 1; +} + +/* ======================= Interrupt control ============================ */ + +static void ecard_def_irq_enable(ecard_t *ec, int irqnr) +{ +#ifdef HAS_EXPMASK + if (irqnr < 4 && have_expmask) { + have_expmask |= 1 << irqnr; + __raw_writeb(have_expmask, EXPMASK_ENABLE); + } +#endif +} + +static void ecard_def_irq_disable(ecard_t *ec, int irqnr) +{ +#ifdef HAS_EXPMASK + if (irqnr < 4 && have_expmask) { + have_expmask &= ~(1 << irqnr); + __raw_writeb(have_expmask, EXPMASK_ENABLE); + } +#endif +} + +static int ecard_def_irq_pending(ecard_t *ec) +{ + return !ec->irqmask || readb(ec->irqaddr) & ec->irqmask; +} + +static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr) +{ + panic("ecard_def_fiq_enable called - impossible"); +} + +static void ecard_def_fiq_disable(ecard_t *ec, int fiqnr) +{ + panic("ecard_def_fiq_disable called - impossible"); +} + +static int ecard_def_fiq_pending(ecard_t *ec) +{ + return !ec->fiqmask || readb(ec->fiqaddr) & ec->fiqmask; +} + +static expansioncard_ops_t ecard_default_ops = { + ecard_def_irq_enable, + ecard_def_irq_disable, + ecard_def_irq_pending, + ecard_def_fiq_enable, + ecard_def_fiq_disable, + ecard_def_fiq_pending +}; + +/* + * Enable and disable interrupts from expansion cards. + * (interrupts are disabled for these functions). + * + * They are not meant to be called directly, but via enable/disable_irq. + */ +static void ecard_irq_unmask(unsigned int irqnr) +{ + ecard_t *ec = slot_to_ecard(irqnr - 32); + + if (ec) { + if (!ec->ops) + ec->ops = &ecard_default_ops; + + if (ec->claimed && ec->ops->irqenable) + ec->ops->irqenable(ec, irqnr); + else + printk(KERN_ERR "ecard: rejecting request to " + "enable IRQs for %d\n", irqnr); + } +} + +static void ecard_irq_mask(unsigned int irqnr) +{ + ecard_t *ec = slot_to_ecard(irqnr - 32); + + if (ec) { + if (!ec->ops) + ec->ops = &ecard_default_ops; + + if (ec->ops && ec->ops->irqdisable) + ec->ops->irqdisable(ec, irqnr); + } +} + +static struct irqchip ecard_chip = { + .ack = ecard_irq_mask, + .mask = ecard_irq_mask, + .unmask = ecard_irq_unmask, +}; + +void ecard_enablefiq(unsigned int fiqnr) +{ + ecard_t *ec = slot_to_ecard(fiqnr); + + if (ec) { + if (!ec->ops) + ec->ops = &ecard_default_ops; + + if (ec->claimed && ec->ops->fiqenable) + ec->ops->fiqenable(ec, fiqnr); + else + printk(KERN_ERR "ecard: rejecting request to " + "enable FIQs for %d\n", fiqnr); + } +} + +void ecard_disablefiq(unsigned int fiqnr) +{ + ecard_t *ec = slot_to_ecard(fiqnr); + + if (ec) { + if (!ec->ops) + ec->ops = &ecard_default_ops; + + if (ec->ops->fiqdisable) + ec->ops->fiqdisable(ec, fiqnr); + } +} + +static void ecard_dump_irq_state(void) +{ + ecard_t *ec; + + printk("Expansion card IRQ state:\n"); + + for (ec = cards; ec; ec = ec->next) { + if (ec->slot_no == 8) + continue; + + printk(" %d: %sclaimed, ", + ec->slot_no, ec->claimed ? "" : "not "); + + if (ec->ops && ec->ops->irqpending && + ec->ops != &ecard_default_ops) + printk("irq %spending\n", + ec->ops->irqpending(ec) ? "" : "not "); + else + printk("irqaddr %p, mask = %02X, status = %02X\n", + ec->irqaddr, ec->irqmask, readb(ec->irqaddr)); + } +} + +static void ecard_check_lockup(struct irqdesc *desc) +{ + static unsigned long last; + static int lockup; + + /* + * If the timer interrupt has not run since the last million + * unrecognised expansion card interrupts, then there is + * something seriously wrong. Disable the expansion card + * interrupts so at least we can continue. + * + * Maybe we ought to start a timer to re-enable them some time + * later? + */ + if (last == jiffies) { + lockup += 1; + if (lockup > 1000000) { + printk(KERN_ERR "\nInterrupt lockup detected - " + "disabling all expansion card interrupts\n"); + + desc->chip->mask(IRQ_EXPANSIONCARD); + ecard_dump_irq_state(); + } + } else + lockup = 0; + + /* + * If we did not recognise the source of this interrupt, + * warn the user, but don't flood the user with these messages. + */ + if (!last || time_after(jiffies, last + 5*HZ)) { + last = jiffies; + printk(KERN_WARNING "Unrecognised interrupt from backplane\n"); + ecard_dump_irq_state(); + } +} + +static void +ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + ecard_t *ec; + int called = 0; + + desc->chip->mask(irq); + for (ec = cards; ec; ec = ec->next) { + int pending; + + if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8) + continue; + + if (ec->ops && ec->ops->irqpending) + pending = ec->ops->irqpending(ec); + else + pending = ecard_default_ops.irqpending(ec); + + if (pending) { + struct irqdesc *d = irq_desc + ec->irq; + d->handle(ec->irq, d, regs); + called ++; + } + } + desc->chip->unmask(irq); + + if (called == 0) + ecard_check_lockup(desc); +} + +#ifdef HAS_EXPMASK +static unsigned char priority_masks[] = +{ + 0xf0, 0xf1, 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff +}; + +static unsigned char first_set[] = +{ + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00 +}; + +static void +ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + const unsigned int statusmask = 15; + unsigned int status; + + status = __raw_readb(EXPMASK_STATUS) & statusmask; + if (status) { + unsigned int slot = first_set[status]; + ecard_t *ec = slot_to_ecard(slot); + + if (ec->claimed) { + struct irqdesc *d = irqdesc + ec->irq; + /* + * this ugly code is so that we can operate a + * prioritorising system: + * + * Card 0 highest priority + * Card 1 + * Card 2 + * Card 3 lowest priority + * + * Serial cards should go in 0/1, ethernet/scsi in 2/3 + * otherwise you will lose serial data at high speeds! + */ + d->handle(ec->irq, d, regs); + } else { + printk(KERN_WARNING "card%d: interrupt from unclaimed " + "card???\n", slot); + have_expmask &= ~(1 << slot); + __raw_writeb(have_expmask, EXPMASK_ENABLE); + } + } else + printk(KERN_WARNING "Wild interrupt from backplane (masks)\n"); +} + +static int __init ecard_probeirqhw(void) +{ + ecard_t *ec; + int found; + + __raw_writeb(0x00, EXPMASK_ENABLE); + __raw_writeb(0xff, EXPMASK_STATUS); + found = (__raw_readb(EXPMASK_STATUS) & 15) == 0; + __raw_writeb(0xff, EXPMASK_ENABLE); + + if (found) { + printk(KERN_DEBUG "Expansion card interrupt " + "management hardware found\n"); + + /* for each card present, set a bit to '1' */ + have_expmask = 0x80000000; + + for (ec = cards; ec; ec = ec->next) + have_expmask |= 1 << ec->slot_no; + + __raw_writeb(have_expmask, EXPMASK_ENABLE); + } + + return found; +} +#else +#define ecard_irqexp_handler NULL +#define ecard_probeirqhw() (0) +#endif + +#ifndef IO_EC_MEMC8_BASE +#define IO_EC_MEMC8_BASE 0 +#endif + +unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) +{ + unsigned long address = 0; + int slot = ec->slot_no; + + if (ec->slot_no == 8) + return IO_EC_MEMC8_BASE; + + ectcr &= ~(1 << slot); + + switch (type) { + case ECARD_MEMC: + if (slot < 4) + address = IO_EC_MEMC_BASE + (slot << 12); + break; + + case ECARD_IOC: + if (slot < 4) + address = IO_EC_IOC_BASE + (slot << 12); +#ifdef IO_EC_IOC4_BASE + else + address = IO_EC_IOC4_BASE + ((slot - 4) << 12); +#endif + if (address) + address += speed << 17; + break; + +#ifdef IO_EC_EASI_BASE + case ECARD_EASI: + address = IO_EC_EASI_BASE + (slot << 22); + if (speed == ECARD_FAST) + ectcr |= 1 << slot; + break; +#endif + default: + break; + } + +#ifdef IOMD_ECTCR + iomd_writeb(ectcr, IOMD_ECTCR); +#endif + return address; +} + +static int ecard_prints(char *buffer, ecard_t *ec) +{ + char *start = buffer; + + buffer += sprintf(buffer, " %d: %s ", ec->slot_no, + ec->type == ECARD_EASI ? "EASI" : " "); + + if (ec->cid.id == 0) { + struct in_chunk_dir incd; + + buffer += sprintf(buffer, "[%04X:%04X] ", + ec->cid.manufacturer, ec->cid.product); + + if (!ec->card_desc && ec->cid.cd && + ecard_readchunk(&incd, ec, 0xf5, 0)) { + ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL); + + if (ec->card_desc) + strcpy((char *)ec->card_desc, incd.d.string); + } + + buffer += sprintf(buffer, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*"); + } else + buffer += sprintf(buffer, "Simple card %d\n", ec->cid.id); + + return buffer - start; +} + +static int get_ecard_dev_info(char *buf, char **start, off_t pos, int count) +{ + ecard_t *ec = cards; + off_t at = 0; + int len, cnt; + + cnt = 0; + while (ec && count > cnt) { + len = ecard_prints(buf, ec); + at += len; + if (at >= pos) { + if (!*start) { + *start = buf + (pos - (at - len)); + cnt = at - pos; + } else + cnt += len; + buf += len; + } + ec = ec->next; + } + return (count > cnt) ? cnt : count; +} + +static struct proc_dir_entry *proc_bus_ecard_dir = NULL; + +static void ecard_proc_init(void) +{ + proc_bus_ecard_dir = proc_mkdir("ecard", proc_bus); + create_proc_info_entry("devices", 0, proc_bus_ecard_dir, + get_ecard_dev_info); +} + +#define ec_set_resource(ec,nr,st,sz) \ + do { \ + (ec)->resource[nr].name = ec->dev.bus_id; \ + (ec)->resource[nr].start = st; \ + (ec)->resource[nr].end = (st) + (sz) - 1; \ + (ec)->resource[nr].flags = IORESOURCE_MEM; \ + } while (0) + +static void __init ecard_free_card(struct expansion_card *ec) +{ + int i; + + for (i = 0; i < ECARD_NUM_RESOURCES; i++) + if (ec->resource[i].flags) + release_resource(&ec->resource[i]); + + kfree(ec); +} + +static struct expansion_card *__init ecard_alloc_card(int type, int slot) +{ + struct expansion_card *ec; + unsigned long base; + int i; + + ec = kmalloc(sizeof(ecard_t), GFP_KERNEL); + if (!ec) { + ec = ERR_PTR(-ENOMEM); + goto nomem; + } + + memset(ec, 0, sizeof(ecard_t)); + + ec->slot_no = slot; + ec->type = type; + ec->irq = NO_IRQ; + ec->fiq = NO_IRQ; + ec->dma = NO_DMA; + ec->ops = &ecard_default_ops; + + snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot); + ec->dev.parent = NULL; + ec->dev.bus = &ecard_bus_type; + ec->dev.dma_mask = &ec->dma_mask; + ec->dma_mask = (u64)0xffffffff; + + if (slot < 4) { + ec_set_resource(ec, ECARD_RES_MEMC, + PODSLOT_MEMC_BASE + (slot << 14), + PODSLOT_MEMC_SIZE); + base = PODSLOT_IOC0_BASE + (slot << 14); + } else + base = PODSLOT_IOC4_BASE + ((slot - 4) << 14); + +#ifdef CONFIG_ARCH_RPC + if (slot < 8) { + ec_set_resource(ec, ECARD_RES_EASI, + PODSLOT_EASI_BASE + (slot << 24), + PODSLOT_EASI_SIZE); + } + + if (slot == 8) { + ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE, NETSLOT_SIZE); + } else +#endif + + for (i = 0; i <= ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) + ec_set_resource(ec, i + ECARD_RES_IOCSLOW, + base + (i << 19), PODSLOT_IOC_SIZE); + + for (i = 0; i < ECARD_NUM_RESOURCES; i++) { + if (ec->resource[i].flags && + request_resource(&iomem_resource, &ec->resource[i])) { + printk(KERN_ERR "%s: resource(s) not available\n", + ec->dev.bus_id); + ec->resource[i].end -= ec->resource[i].start; + ec->resource[i].start = 0; + ec->resource[i].flags = 0; + } + } + + nomem: + return ec; +} + +static ssize_t ecard_show_irq(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%u\n", ec->irq); +} + +static ssize_t ecard_show_dma(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%u\n", ec->dma); +} + +static ssize_t ecard_show_resources(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + char *str = buf; + int i; + + for (i = 0; i < ECARD_NUM_RESOURCES; i++) + str += sprintf(str, "%08lx %08lx %08lx\n", + ec->resource[i].start, + ec->resource[i].end, + ec->resource[i].flags); + + return str - buf; +} + +static ssize_t ecard_show_vendor(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%u\n", ec->cid.manufacturer); +} + +static ssize_t ecard_show_device(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%u\n", ec->cid.product); +} + +static ssize_t ecard_show_type(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC"); +} + +static struct device_attribute ecard_dev_attrs[] = { + __ATTR(device, S_IRUGO, ecard_show_device, NULL), + __ATTR(dma, S_IRUGO, ecard_show_dma, NULL), + __ATTR(irq, S_IRUGO, ecard_show_irq, NULL), + __ATTR(resource, S_IRUGO, ecard_show_resources, NULL), + __ATTR(type, S_IRUGO, ecard_show_type, NULL), + __ATTR(vendor, S_IRUGO, ecard_show_vendor, NULL), + __ATTR_NULL, +}; + + +int ecard_request_resources(struct expansion_card *ec) +{ + int i, err = 0; + + for (i = 0; i < ECARD_NUM_RESOURCES; i++) { + if (ecard_resource_end(ec, i) && + !request_mem_region(ecard_resource_start(ec, i), + ecard_resource_len(ec, i), + ec->dev.driver->name)) { + err = -EBUSY; + break; + } + } + + if (err) { + while (i--) + if (ecard_resource_end(ec, i)) + release_mem_region(ecard_resource_start(ec, i), + ecard_resource_len(ec, i)); + } + return err; +} +EXPORT_SYMBOL(ecard_request_resources); + +void ecard_release_resources(struct expansion_card *ec) +{ + int i; + + for (i = 0; i < ECARD_NUM_RESOURCES; i++) + if (ecard_resource_end(ec, i)) + release_mem_region(ecard_resource_start(ec, i), + ecard_resource_len(ec, i)); +} +EXPORT_SYMBOL(ecard_release_resources); + +/* + * Probe for an expansion card. + * + * If bit 1 of the first byte of the card is set, then the + * card does not exist. + */ +static int __init +ecard_probe(int slot, card_type_t type) +{ + ecard_t **ecp; + ecard_t *ec; + struct ex_ecid cid; + int i, rc; + + ec = ecard_alloc_card(type, slot); + if (IS_ERR(ec)) { + rc = PTR_ERR(ec); + goto nomem; + } + + rc = -ENODEV; + if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0) + goto nodev; + + cid.r_zero = 1; + ecard_readbytes(&cid, ec, 0, 16, 0); + if (cid.r_zero) + goto nodev; + + ec->cid.id = cid.r_id; + ec->cid.cd = cid.r_cd; + ec->cid.is = cid.r_is; + ec->cid.w = cid.r_w; + ec->cid.manufacturer = ecard_getu16(cid.r_manu); + ec->cid.product = ecard_getu16(cid.r_prod); + ec->cid.country = cid.r_country; + ec->cid.irqmask = cid.r_irqmask; + ec->cid.irqoff = ecard_gets24(cid.r_irqoff); + ec->cid.fiqmask = cid.r_fiqmask; + ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff); + ec->fiqaddr = + ec->irqaddr = (void __iomem *)ioaddr(ec->podaddr); + + if (ec->cid.is) { + ec->irqmask = ec->cid.irqmask; + ec->irqaddr += ec->cid.irqoff; + ec->fiqmask = ec->cid.fiqmask; + ec->fiqaddr += ec->cid.fiqoff; + } else { + ec->irqmask = 1; + ec->fiqmask = 4; + } + + for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++) + if (blacklist[i].manufacturer == ec->cid.manufacturer && + blacklist[i].product == ec->cid.product) { + ec->card_desc = blacklist[i].type; + break; + } + + /* + * hook the interrupt handlers + */ + if (slot < 8) { + ec->irq = 32 + slot; + set_irq_chip(ec->irq, &ecard_chip); + set_irq_handler(ec->irq, do_level_IRQ); + set_irq_flags(ec->irq, IRQF_VALID); + } + +#ifdef IO_EC_MEMC8_BASE + if (slot == 8) + ec->irq = 11; +#endif +#ifdef CONFIG_ARCH_RPC + /* On RiscPC, only first two slots have DMA capability */ + if (slot < 2) + ec->dma = 2 + slot; +#endif + + for (ecp = &cards; *ecp; ecp = &(*ecp)->next); + + *ecp = ec; + slot_to_expcard[slot] = ec; + + device_register(&ec->dev); + + return 0; + + nodev: + ecard_free_card(ec); + nomem: + return rc; +} + +/* + * Initialise the expansion card system. + * Locate all hardware - interrupt management and + * actual cards. + */ +static int __init ecard_init(void) +{ + int slot, irqhw, ret; + + ret = kernel_thread(ecard_task, NULL, CLONE_KERNEL); + if (ret < 0) { + printk(KERN_ERR "Ecard: unable to create kernel thread: %d\n", + ret); + return ret; + } + + printk("Probing expansion cards\n"); + + for (slot = 0; slot < 8; slot ++) { + if (ecard_probe(slot, ECARD_EASI) == -ENODEV) + ecard_probe(slot, ECARD_IOC); + } + +#ifdef IO_EC_MEMC8_BASE + ecard_probe(8, ECARD_IOC); +#endif + + irqhw = ecard_probeirqhw(); + + set_irq_chained_handler(IRQ_EXPANSIONCARD, + irqhw ? ecard_irqexp_handler : ecard_irq_handler); + + ecard_proc_init(); + + return 0; +} + +subsys_initcall(ecard_init); + +/* + * ECARD "bus" + */ +static const struct ecard_id * +ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec) +{ + int i; + + for (i = 0; ids[i].manufacturer != 65535; i++) + if (ec->cid.manufacturer == ids[i].manufacturer && + ec->cid.product == ids[i].product) + return ids + i; + + return NULL; +} + +static int ecard_drv_probe(struct device *dev) +{ + struct expansion_card *ec = ECARD_DEV(dev); + struct ecard_driver *drv = ECARD_DRV(dev->driver); + const struct ecard_id *id; + int ret; + + id = ecard_match_device(drv->id_table, ec); + + ecard_claim(ec); + ret = drv->probe(ec, id); + if (ret) + ecard_release(ec); + return ret; +} + +static int ecard_drv_remove(struct device *dev) +{ + struct expansion_card *ec = ECARD_DEV(dev); + struct ecard_driver *drv = ECARD_DRV(dev->driver); + + drv->remove(ec); + ecard_release(ec); + + return 0; +} + +/* + * Before rebooting, we must make sure that the expansion card is in a + * sensible state, so it can be re-detected. This means that the first + * page of the ROM must be visible. We call the expansion cards reset + * handler, if any. + */ +static void ecard_drv_shutdown(struct device *dev) +{ + struct expansion_card *ec = ECARD_DEV(dev); + struct ecard_driver *drv = ECARD_DRV(dev->driver); + struct ecard_request req; + + if (drv->shutdown) + drv->shutdown(ec); + ecard_release(ec); + + /* + * If this card has a loader, call the reset handler. + */ + if (ec->loader) { + req.fn = ecard_task_reset; + req.ec = ec; + ecard_call(&req); + } +} + +int ecard_register_driver(struct ecard_driver *drv) +{ + drv->drv.bus = &ecard_bus_type; + drv->drv.probe = ecard_drv_probe; + drv->drv.remove = ecard_drv_remove; + drv->drv.shutdown = ecard_drv_shutdown; + + return driver_register(&drv->drv); +} + +void ecard_remove_driver(struct ecard_driver *drv) +{ + driver_unregister(&drv->drv); +} + +static int ecard_match(struct device *_dev, struct device_driver *_drv) +{ + struct expansion_card *ec = ECARD_DEV(_dev); + struct ecard_driver *drv = ECARD_DRV(_drv); + int ret; + + if (drv->id_table) { + ret = ecard_match_device(drv->id_table, ec) != NULL; + } else { + ret = ec->cid.id == drv->id; + } + + return ret; +} + +struct bus_type ecard_bus_type = { + .name = "ecard", + .dev_attrs = ecard_dev_attrs, + .match = ecard_match, +}; + +static int ecard_bus_init(void) +{ + return bus_register(&ecard_bus_type); +} + +postcore_initcall(ecard_bus_init); + +EXPORT_SYMBOL(ecard_readchunk); +EXPORT_SYMBOL(__ecard_address); +EXPORT_SYMBOL(ecard_register_driver); +EXPORT_SYMBOL(ecard_remove_driver); +EXPORT_SYMBOL(ecard_bus_type); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S new file mode 100644 index 0000000..bb27c31 --- /dev/null +++ b/arch/arm/kernel/entry-armv.S @@ -0,0 +1,745 @@ +/* + * linux/arch/arm/kernel/entry-armv.S + * + * Copyright (C) 1996,1997,1998 Russell King. + * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) + * + * 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. + * + * Low-level vector interface routines + * + * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes + * it to save wrong values... Be aware! + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/thread_info.h> +#include <asm/glue.h> +#include <asm/ptrace.h> +#include <asm/vfpmacros.h> + +#include "entry-header.S" + +/* + * Invalid mode handlers + */ + .macro inv_entry, sym, reason + sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go + stmia sp, {r0 - lr} @ Save XXX r0 - lr + ldr r4, .LC\sym + mov r1, #\reason + .endm + +__pabt_invalid: + inv_entry abt, BAD_PREFETCH + b 1f + +__dabt_invalid: + inv_entry abt, BAD_DATA + b 1f + +__irq_invalid: + inv_entry irq, BAD_IRQ + b 1f + +__und_invalid: + inv_entry und, BAD_UNDEFINSTR + +1: zero_fp + ldmia r4, {r5 - r7} @ Get XXX pc, cpsr, old_r0 + add r4, sp, #S_PC + stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0 + mov r0, sp + and r2, r6, #31 @ int mode + b bad_mode + +/* + * SVC mode handlers + */ + .macro svc_entry, sym + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ save r0 - r12 + ldr r2, .LC\sym + add r0, sp, #S_FRAME_SIZE + ldmia r2, {r2 - r4} @ get pc, cpsr + add r5, sp, #S_SP + mov r1, lr + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r0 - sp_svc + @ r1 - lr_svc + @ r2 - lr_<exception>, already fixed up for correct return/restart + @ r3 - spsr_<exception> + @ r4 - orig_r0 (see pt_regs definition in ptrace.h) + @ + stmia r5, {r0 - r4} + .endm + + .align 5 +__dabt_svc: + svc_entry abt + + @ + @ get ready to re-enable interrupts if appropriate + @ + mrs r9, cpsr + tst r3, #PSR_I_BIT + biceq r9, r9, #PSR_I_BIT + + @ + @ Call the processor-specific abort handler: + @ + @ r2 - aborted context pc + @ r3 - aborted context cpsr + @ + @ The abort handler must return the aborted address in r0, and + @ the fault status register in r1. r9 must be preserved. + @ +#ifdef MULTI_ABORT + ldr r4, .LCprocfns + mov lr, pc + ldr pc, [r4] +#else + bl CPU_ABORT_HANDLER +#endif + + @ + @ set desired IRQ state, then call main handler + @ + msr cpsr_c, r9 + mov r2, sp + bl do_DataAbort + + @ + @ IRQs off again before pulling preserved data off the stack + @ + disable_irq r0 + + @ + @ restore SPSR and restart the instruction + @ + ldr r0, [sp, #S_PSR] + msr spsr_cxsf, r0 + ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr + + .align 5 +__irq_svc: + svc_entry irq +#ifdef CONFIG_PREEMPT + get_thread_info r8 + ldr r9, [r8, #TI_PREEMPT] @ get preempt count + add r7, r9, #1 @ increment it + str r7, [r8, #TI_PREEMPT] +#endif +1: get_irqnr_and_base r0, r6, r5, lr + movne r1, sp + @ + @ routine called with r0 = irq number, r1 = struct pt_regs * + @ + adrne lr, 1b + bne asm_do_IRQ +#ifdef CONFIG_PREEMPT + ldr r0, [r8, #TI_FLAGS] @ get flags + tst r0, #_TIF_NEED_RESCHED + blne svc_preempt +preempt_return: + ldr r0, [r8, #TI_PREEMPT] @ read preempt value + teq r0, r7 + str r9, [r8, #TI_PREEMPT] @ restore preempt count + strne r0, [r0, -r0] @ bug() +#endif + ldr r0, [sp, #S_PSR] @ irqs are already disabled + msr spsr_cxsf, r0 + ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr + + .ltorg + +#ifdef CONFIG_PREEMPT +svc_preempt: + teq r9, #0 @ was preempt count = 0 + ldreq r6, .LCirq_stat + movne pc, lr @ no + ldr r0, [r6, #4] @ local_irq_count + ldr r1, [r6, #8] @ local_bh_count + adds r0, r0, r1 + movne pc, lr + mov r7, #0 @ preempt_schedule_irq + str r7, [r8, #TI_PREEMPT] @ expects preempt_count == 0 +1: bl preempt_schedule_irq @ irq en/disable is done inside + ldr r0, [r8, #TI_FLAGS] @ get new tasks TI_FLAGS + tst r0, #_TIF_NEED_RESCHED + beq preempt_return @ go again + b 1b +#endif + + .align 5 +__und_svc: + svc_entry und + + @ + @ call emulation code, which returns using r9 if it has emulated + @ the instruction, or the more conventional lr if we are to treat + @ this as a real undefined instruction + @ + @ r0 - instruction + @ + ldr r0, [r2, #-4] + adr r9, 1f + bl call_fpe + + mov r0, sp @ struct pt_regs *regs + bl do_undefinstr + + @ + @ IRQs off again before pulling preserved data off the stack + @ +1: disable_irq r0 + + @ + @ restore SPSR and restart the instruction + @ + ldr lr, [sp, #S_PSR] @ Get SVC cpsr + msr spsr_cxsf, lr + ldmia sp, {r0 - pc}^ @ Restore SVC registers + + .align 5 +__pabt_svc: + svc_entry abt + + @ + @ re-enable interrupts if appropriate + @ + mrs r9, cpsr + tst r3, #PSR_I_BIT + biceq r9, r9, #PSR_I_BIT + msr cpsr_c, r9 + + @ + @ set args, then call main handler + @ + @ r0 - address of faulting instruction + @ r1 - pointer to registers on stack + @ + mov r0, r2 @ address (pc) + mov r1, sp @ regs + bl do_PrefetchAbort @ call abort handler + + @ + @ IRQs off again before pulling preserved data off the stack + @ + disable_irq r0 + + @ + @ restore SPSR and restart the instruction + @ + ldr r0, [sp, #S_PSR] + msr spsr_cxsf, r0 + ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr + + .align 5 +.LCirq: + .word __temp_irq +.LCund: + .word __temp_und +.LCabt: + .word __temp_abt +#ifdef MULTI_ABORT +.LCprocfns: + .word processor +#endif +.LCfp: + .word fp_enter +#ifdef CONFIG_PREEMPT +.LCirq_stat: + .word irq_stat +#endif + +/* + * User mode handlers + */ + .macro usr_entry, sym + sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go + stmia sp, {r0 - r12} @ save r0 - r12 + ldr r7, .LC\sym + add r5, sp, #S_PC + ldmia r7, {r2 - r4} @ Get USR pc, cpsr + + @ + @ We are now ready to fill in the remaining blanks on the stack: + @ + @ r2 - lr_<exception>, already fixed up for correct return/restart + @ r3 - spsr_<exception> + @ r4 - orig_r0 (see pt_regs definition in ptrace.h) + @ + @ Also, separately save sp_usr and lr_usr + @ + stmia r5, {r2 - r4} + stmdb r5, {sp, lr}^ + + @ + @ Enable the alignment trap while in kernel mode + @ + alignment_trap r7, r0, __temp_\sym + + @ + @ Clear FP to mark the first stack frame + @ + zero_fp + .endm + + .align 5 +__dabt_usr: + usr_entry abt + + @ + @ Call the processor-specific abort handler: + @ + @ r2 - aborted context pc + @ r3 - aborted context cpsr + @ + @ The abort handler must return the aborted address in r0, and + @ the fault status register in r1. + @ +#ifdef MULTI_ABORT + ldr r4, .LCprocfns + mov lr, pc + ldr pc, [r4] +#else + bl CPU_ABORT_HANDLER +#endif + + @ + @ IRQs on, then call the main handler + @ + enable_irq r2 + mov r2, sp + adr lr, ret_from_exception + b do_DataAbort + + .align 5 +__irq_usr: + usr_entry irq + +#ifdef CONFIG_PREEMPT + get_thread_info r8 + ldr r9, [r8, #TI_PREEMPT] @ get preempt count + add r7, r9, #1 @ increment it + str r7, [r8, #TI_PREEMPT] +#endif +1: get_irqnr_and_base r0, r6, r5, lr + movne r1, sp + adrne lr, 1b + @ + @ routine called with r0 = irq number, r1 = struct pt_regs * + @ + bne asm_do_IRQ +#ifdef CONFIG_PREEMPT + ldr r0, [r8, #TI_PREEMPT] + teq r0, r7 + str r9, [r8, #TI_PREEMPT] + strne r0, [r0, -r0] + mov tsk, r8 +#else + get_thread_info tsk +#endif + mov why, #0 + b ret_to_user + + .ltorg + + .align 5 +__und_usr: + usr_entry und + + tst r3, #PSR_T_BIT @ Thumb mode? + bne fpundefinstr @ ignore FP + sub r4, r2, #4 + + @ + @ fall through to the emulation code, which returns using r9 if + @ it has emulated the instruction, or the more conventional lr + @ if we are to treat this as a real undefined instruction + @ + @ r0 - instruction + @ +1: ldrt r0, [r4] + adr r9, ret_from_exception + adr lr, fpundefinstr + @ + @ fallthrough to call_fpe + @ + +/* + * The out of line fixup for the ldrt above. + */ + .section .fixup, "ax" +2: mov pc, r9 + .previous + .section __ex_table,"a" + .long 1b, 2b + .previous + +/* + * Check whether the instruction is a co-processor instruction. + * If yes, we need to call the relevant co-processor handler. + * + * Note that we don't do a full check here for the co-processor + * instructions; all instructions with bit 27 set are well + * defined. The only instructions that should fault are the + * co-processor instructions. However, we have to watch out + * for the ARM6/ARM7 SWI bug. + * + * Emulators may wish to make use of the following registers: + * r0 = instruction opcode. + * r2 = PC+4 + * r10 = this threads thread_info structure. + */ +call_fpe: + tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 +#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) + and r8, r0, #0x0f000000 @ mask out op-code bits + teqne r8, #0x0f000000 @ SWI (ARM6/7 bug)? +#endif + moveq pc, lr + get_thread_info r10 @ get current thread + and r8, r0, #0x00000f00 @ mask out CP number + mov r7, #1 + add r6, r10, #TI_USED_CP + strb r7, [r6, r8, lsr #8] @ set appropriate used_cp[] +#ifdef CONFIG_IWMMXT + @ Test if we need to give access to iWMMXt coprocessors + ldr r5, [r10, #TI_FLAGS] + rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only + movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) + bcs iwmmxt_task_enable +#endif + enable_irq r7 + add pc, pc, r8, lsr #6 + mov r0, r0 + + mov pc, lr @ CP#0 + b do_fpe @ CP#1 (FPE) + b do_fpe @ CP#2 (FPE) + mov pc, lr @ CP#3 + mov pc, lr @ CP#4 + mov pc, lr @ CP#5 + mov pc, lr @ CP#6 + mov pc, lr @ CP#7 + mov pc, lr @ CP#8 + mov pc, lr @ CP#9 +#ifdef CONFIG_VFP + b do_vfp @ CP#10 (VFP) + b do_vfp @ CP#11 (VFP) +#else + mov pc, lr @ CP#10 (VFP) + mov pc, lr @ CP#11 (VFP) +#endif + mov pc, lr @ CP#12 + mov pc, lr @ CP#13 + mov pc, lr @ CP#14 (Debug) + mov pc, lr @ CP#15 (Control) + +do_fpe: + ldr r4, .LCfp + add r10, r10, #TI_FPSTATE @ r10 = workspace + ldr pc, [r4] @ Call FP module USR entry point + +/* + * The FP module is called with these registers set: + * r0 = instruction + * r2 = PC+4 + * r9 = normal "successful" return address + * r10 = FP workspace + * lr = unrecognised FP instruction return address + */ + + .data +ENTRY(fp_enter) + .word fpundefinstr + .text + +fpundefinstr: + mov r0, sp + adr lr, ret_from_exception + b do_undefinstr + + .align 5 +__pabt_usr: + usr_entry abt + + enable_irq r0 @ Enable interrupts + mov r0, r2 @ address (pc) + mov r1, sp @ regs + bl do_PrefetchAbort @ call abort handler + /* fall through */ +/* + * This is the return code to user mode for abort handlers + */ +ENTRY(ret_from_exception) + get_thread_info tsk + mov why, #0 + b ret_to_user + +/* + * Register switch for ARMv3 and ARMv4 processors + * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info + * previous and next are guaranteed not to be the same. + */ +ENTRY(__switch_to) + add ip, r1, #TI_CPU_SAVE + ldr r3, [r2, #TI_TP_VALUE] + stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack + ldr r6, [r2, #TI_CPU_DOMAIN]! +#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) + mra r4, r5, acc0 + stmia ip, {r4, r5} +#endif + mov r4, #0xffff0fff + str r3, [r4, #-3] @ Set TLS ptr + mcr p15, 0, r6, c3, c0, 0 @ Set domain register +#ifdef CONFIG_VFP + @ Always disable VFP so we can lazily save/restore the old + @ state. This occurs in the context of the previous thread. + VFPFMRX r4, FPEXC + bic r4, r4, #FPEXC_ENABLE + VFPFMXR FPEXC, r4 +#endif +#if defined(CONFIG_IWMMXT) + bl iwmmxt_task_switch +#elif defined(CONFIG_CPU_XSCALE) + add r4, r2, #40 @ cpu_context_save->extra + ldmib r4, {r4, r5} + mar acc0, r4, r5 +#endif + ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously + + __INIT +/* + * Vector stubs. + * + * This code is copied to 0x200 or 0xffff0200 so we can use branches in the + * vectors, rather than ldr's. + * + * Common stub entry macro: + * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC + */ + .macro vector_stub, name, sym, correction=0 + .align 5 + +vector_\name: + ldr r13, .LCs\sym + .if \correction + sub lr, lr, #\correction + .endif + str lr, [r13] @ save lr_IRQ + mrs lr, spsr + str lr, [r13, #4] @ save spsr_IRQ + @ + @ now branch to the relevant MODE handling routine + @ + mrs r13, cpsr + bic r13, r13, #MODE_MASK + orr r13, r13, #MODE_SVC + msr spsr_cxsf, r13 @ switch to SVC_32 mode + + and lr, lr, #15 + ldr lr, [pc, lr, lsl #2] + movs pc, lr @ Changes mode and branches + .endm + +__stubs_start: +/* + * Interrupt dispatcher + */ + vector_stub irq, irq, 4 + + .long __irq_usr @ 0 (USR_26 / USR_32) + .long __irq_invalid @ 1 (FIQ_26 / FIQ_32) + .long __irq_invalid @ 2 (IRQ_26 / IRQ_32) + .long __irq_svc @ 3 (SVC_26 / SVC_32) + .long __irq_invalid @ 4 + .long __irq_invalid @ 5 + .long __irq_invalid @ 6 + .long __irq_invalid @ 7 + .long __irq_invalid @ 8 + .long __irq_invalid @ 9 + .long __irq_invalid @ a + .long __irq_invalid @ b + .long __irq_invalid @ c + .long __irq_invalid @ d + .long __irq_invalid @ e + .long __irq_invalid @ f + +/* + * Data abort dispatcher + * Enter in ABT mode, spsr = USR CPSR, lr = USR PC + */ + vector_stub dabt, abt, 8 + + .long __dabt_usr @ 0 (USR_26 / USR_32) + .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32) + .long __dabt_invalid @ 2 (IRQ_26 / IRQ_32) + .long __dabt_svc @ 3 (SVC_26 / SVC_32) + .long __dabt_invalid @ 4 + .long __dabt_invalid @ 5 + .long __dabt_invalid @ 6 + .long __dabt_invalid @ 7 + .long __dabt_invalid @ 8 + .long __dabt_invalid @ 9 + .long __dabt_invalid @ a + .long __dabt_invalid @ b + .long __dabt_invalid @ c + .long __dabt_invalid @ d + .long __dabt_invalid @ e + .long __dabt_invalid @ f + +/* + * Prefetch abort dispatcher + * Enter in ABT mode, spsr = USR CPSR, lr = USR PC + */ + vector_stub pabt, abt, 4 + + .long __pabt_usr @ 0 (USR_26 / USR_32) + .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32) + .long __pabt_invalid @ 2 (IRQ_26 / IRQ_32) + .long __pabt_svc @ 3 (SVC_26 / SVC_32) + .long __pabt_invalid @ 4 + .long __pabt_invalid @ 5 + .long __pabt_invalid @ 6 + .long __pabt_invalid @ 7 + .long __pabt_invalid @ 8 + .long __pabt_invalid @ 9 + .long __pabt_invalid @ a + .long __pabt_invalid @ b + .long __pabt_invalid @ c + .long __pabt_invalid @ d + .long __pabt_invalid @ e + .long __pabt_invalid @ f + +/* + * Undef instr entry dispatcher + * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC + */ + vector_stub und, und + + .long __und_usr @ 0 (USR_26 / USR_32) + .long __und_invalid @ 1 (FIQ_26 / FIQ_32) + .long __und_invalid @ 2 (IRQ_26 / IRQ_32) + .long __und_svc @ 3 (SVC_26 / SVC_32) + .long __und_invalid @ 4 + .long __und_invalid @ 5 + .long __und_invalid @ 6 + .long __und_invalid @ 7 + .long __und_invalid @ 8 + .long __und_invalid @ 9 + .long __und_invalid @ a + .long __und_invalid @ b + .long __und_invalid @ c + .long __und_invalid @ d + .long __und_invalid @ e + .long __und_invalid @ f + + .align 5 + +/*============================================================================= + * Undefined FIQs + *----------------------------------------------------------------------------- + * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC + * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg. + * Basically to switch modes, we *HAVE* to clobber one register... brain + * damage alert! I don't think that we can execute any code in here in any + * other mode than FIQ... Ok you can switch to another mode, but you can't + * get out of that mode without clobbering one register. + */ +vector_fiq: + disable_fiq + subs pc, lr, #4 + +/*============================================================================= + * Address exception handler + *----------------------------------------------------------------------------- + * These aren't too critical. + * (they're not supposed to happen, and won't happen in 32-bit data mode). + */ + +vector_addrexcptn: + b vector_addrexcptn + +/* + * We group all the following data together to optimise + * for CPUs with separate I & D caches. + */ + .align 5 + +.LCvswi: + .word vector_swi + +.LCsirq: + .word __temp_irq +.LCsund: + .word __temp_und +.LCsabt: + .word __temp_abt + +__stubs_end: + + .equ __real_stubs_start, .LCvectors + 0x200 + +.LCvectors: + swi SYS_ERROR0 + b __real_stubs_start + (vector_und - __stubs_start) + ldr pc, __real_stubs_start + (.LCvswi - __stubs_start) + b __real_stubs_start + (vector_pabt - __stubs_start) + b __real_stubs_start + (vector_dabt - __stubs_start) + b __real_stubs_start + (vector_addrexcptn - __stubs_start) + b __real_stubs_start + (vector_irq - __stubs_start) + b __real_stubs_start + (vector_fiq - __stubs_start) + +ENTRY(__trap_init) + stmfd sp!, {r4 - r6, lr} + + mov r0, #0xff000000 + orr r0, r0, #0x00ff0000 @ high vectors position + adr r1, .LCvectors @ set up the vectors + ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr} + stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr} + + add r2, r0, #0x200 + adr r0, __stubs_start @ copy stubs to 0x200 + adr r1, __stubs_end +1: ldr r3, [r0], #4 + str r3, [r2], #4 + cmp r0, r1 + blt 1b + LOADREGS(fd, sp!, {r4 - r6, pc}) + + .data + +/* + * Do not reorder these, and do not insert extra data between... + */ + +__temp_irq: + .word 0 @ saved lr_irq + .word 0 @ saved spsr_irq + .word -1 @ old_r0 +__temp_und: + .word 0 @ Saved lr_und + .word 0 @ Saved spsr_und + .word -1 @ old_r0 +__temp_abt: + .word 0 @ Saved lr_abt + .word 0 @ Saved spsr_abt + .word -1 @ old_r0 + + .globl cr_alignment + .globl cr_no_alignment +cr_alignment: + .space 4 +cr_no_alignment: + .space 4 diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S new file mode 100644 index 0000000..53a7e0d --- /dev/null +++ b/arch/arm/kernel/entry-common.S @@ -0,0 +1,260 @@ +/* + * linux/arch/arm/kernel/entry-common.S + * + * Copyright (C) 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 <asm/thread_info.h> +#include <asm/ptrace.h> +#include <asm/unistd.h> + +#include "entry-header.S" + +/* + * We rely on the fact that R0 is at the bottom of the stack (due to + * slow/fast restore user regs). + */ +#if S_R0 != 0 +#error "Please fix" +#endif + + .align 5 +/* + * This is the fast syscall return path. We do as little as + * possible here, and this includes saving r0 back into the SVC + * stack. + */ +ret_fast_syscall: + disable_irq r1 @ disable interrupts + ldr r1, [tsk, #TI_FLAGS] + tst r1, #_TIF_WORK_MASK + bne fast_work_pending + fast_restore_user_regs + +/* + * Ok, we need to do extra processing, enter the slow path. + */ +fast_work_pending: + str r0, [sp, #S_R0+S_OFF]! @ returned r0 +work_pending: + tst r1, #_TIF_NEED_RESCHED + bne work_resched + tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING + beq no_work_pending + mov r0, sp @ 'regs' + mov r2, why @ 'syscall' + bl do_notify_resume + disable_irq r1 @ disable interrupts + b no_work_pending + +work_resched: + bl schedule +/* + * "slow" syscall return path. "why" tells us if this was a real syscall. + */ +ENTRY(ret_to_user) +ret_slow_syscall: + disable_irq r1 @ disable interrupts + ldr r1, [tsk, #TI_FLAGS] + tst r1, #_TIF_WORK_MASK + bne work_pending +no_work_pending: + slow_restore_user_regs + +/* + * This is how we return from a fork. + */ +ENTRY(ret_from_fork) + bl schedule_tail + get_thread_info tsk + ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing + mov why, #1 + tst r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? + beq ret_slow_syscall + mov r1, sp + mov r0, #1 @ trace exit [IP = 1] + bl syscall_trace + b ret_slow_syscall + + +#include "calls.S" + +/*============================================================================= + * SWI handler + *----------------------------------------------------------------------------- + */ + + /* If we're optimising for StrongARM the resulting code won't + run on an ARM7 and we can save a couple of instructions. + --pb */ +#ifdef CONFIG_CPU_ARM710 + .macro arm710_bug_check, instr, temp + and \temp, \instr, #0x0f000000 @ check for SWI + teq \temp, #0x0f000000 + bne .Larm700bug + .endm + +.Larm700bug: + ldr r0, [sp, #S_PSR] @ Get calling cpsr + sub lr, lr, #4 + str lr, [r8] + msr spsr_cxsf, r0 + ldmia sp, {r0 - lr}^ @ Get calling r0 - lr + mov r0, r0 + ldr lr, [sp, #S_PC] @ Get PC + add sp, sp, #S_FRAME_SIZE + movs pc, lr +#else + .macro arm710_bug_check, instr, temp + .endm +#endif + + .align 5 +ENTRY(vector_swi) + save_user_regs + zero_fp + get_scno + arm710_bug_check scno, ip + +#ifdef CONFIG_ALIGNMENT_TRAP + ldr ip, __cr_alignment + ldr ip, [ip] + mcr p15, 0, ip, c1, c0 @ update control register +#endif + enable_irq ip + + str r4, [sp, #-S_OFF]! @ push fifth arg + + get_thread_info tsk + ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing + bic scno, scno, #0xff000000 @ mask off SWI op-code + eor scno, scno, #OS_NUMBER << 20 @ check OS number + adr tbl, sys_call_table @ load syscall table pointer + tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? + bne __sys_trace + + adr lr, ret_fast_syscall @ return address + cmp scno, #NR_syscalls @ check upper syscall limit + ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine + + add r1, sp, #S_OFF +2: mov why, #0 @ no longer a real syscall + cmp scno, #ARMSWI_OFFSET + eor r0, scno, #OS_NUMBER << 20 @ put OS number back + bcs arm_syscall + b sys_ni_syscall @ not private func + + /* + * This is the really slow path. We're going to be doing + * context switches, and waiting for our parent to respond. + */ +__sys_trace: + add r1, sp, #S_OFF + mov r0, #0 @ trace entry [IP = 0] + bl syscall_trace + + adr lr, __sys_trace_return @ return address + add r1, sp, #S_R0 + S_OFF @ pointer to regs + cmp scno, #NR_syscalls @ check upper syscall limit + ldmccia r1, {r0 - r3} @ have to reload r0 - r3 + ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine + b 2b + +__sys_trace_return: + str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 + mov r1, sp + mov r0, #1 @ trace exit [IP = 1] + bl syscall_trace + b ret_slow_syscall + + .align 5 +#ifdef CONFIG_ALIGNMENT_TRAP + .type __cr_alignment, #object +__cr_alignment: + .word cr_alignment +#endif + + .type sys_call_table, #object +ENTRY(sys_call_table) +#include "calls.S" + +/*============================================================================ + * Special system call wrappers + */ +@ r0 = syscall number +@ r5 = syscall table + .type sys_syscall, #function +sys_syscall: + eor scno, r0, #OS_NUMBER << 20 + cmp scno, #__NR_syscall - __NR_SYSCALL_BASE + cmpne scno, #NR_syscalls @ check range + stmloia sp, {r5, r6} @ shuffle args + movlo r0, r1 + movlo r1, r2 + movlo r2, r3 + movlo r3, r4 + ldrlo pc, [tbl, scno, lsl #2] + b sys_ni_syscall + +sys_fork_wrapper: + add r0, sp, #S_OFF + b sys_fork + +sys_vfork_wrapper: + add r0, sp, #S_OFF + b sys_vfork + +sys_execve_wrapper: + add r3, sp, #S_OFF + b sys_execve + +sys_clone_wrapper: + add ip, sp, #S_OFF + str ip, [sp, #4] + b sys_clone + +sys_sigsuspend_wrapper: + add r3, sp, #S_OFF + b sys_sigsuspend + +sys_rt_sigsuspend_wrapper: + add r2, sp, #S_OFF + b sys_rt_sigsuspend + +sys_sigreturn_wrapper: + add r0, sp, #S_OFF + b sys_sigreturn + +sys_rt_sigreturn_wrapper: + add r0, sp, #S_OFF + b sys_rt_sigreturn + +sys_sigaltstack_wrapper: + ldr r2, [sp, #S_OFF + S_SP] + b do_sigaltstack + +sys_futex_wrapper: + str r5, [sp, #4] @ push sixth arg + b sys_futex + +/* + * Note: off_4k (r5) is always units of 4K. If we can't do the requested + * offset, we return EINVAL. + */ +sys_mmap2: +#if PAGE_SHIFT > 12 + tst r5, #PGOFF_MASK + moveq r5, r5, lsr #PAGE_SHIFT - 12 + streq r5, [sp, #4] + beq do_mmap2 + mov r0, #-EINVAL + RETINSTR(mov,pc, lr) +#else + str r5, [sp, #4] + b do_mmap2 +#endif diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S new file mode 100644 index 0000000..4039d8c --- /dev/null +++ b/arch/arm/kernel/entry-header.S @@ -0,0 +1,182 @@ +#include <linux/config.h> /* for CONFIG_ARCH_xxxx */ +#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/arch/entry-macro.S> + +#ifndef MODE_SVC +#define MODE_SVC 0x13 +#endif + + .macro zero_fp +#ifdef CONFIG_FRAME_POINTER + mov fp, #0 +#endif + .endm + + .text + +@ Bad Abort numbers +@ ----------------- +@ +#define BAD_PREFETCH 0 +#define BAD_DATA 1 +#define BAD_ADDREXCPTN 2 +#define BAD_IRQ 3 +#define BAD_UNDEFINSTR 4 + +#define PT_TRACESYS 0x00000002 + +@ OS version number used in SWIs +@ RISC OS is 0 +@ RISC iX is 8 +@ +#define OS_NUMBER 9 +#define ARMSWI_OFFSET 0x000f0000 + +@ +@ Stack format (ensured by USER_* and SVC_*) +@ +#define S_FRAME_SIZE 72 +#define S_OLD_R0 68 +#define S_PSR 64 + +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 +#define S_OFF 8 + + .macro set_cpsr_c, reg, mode + msr cpsr_c, \mode + .endm + +#if __LINUX_ARM_ARCH__ >= 6 + .macro disable_irq, temp + cpsid i + .endm + + .macro enable_irq, temp + cpsie i + .endm +#else + .macro disable_irq, temp + set_cpsr_c \temp, #PSR_I_BIT | MODE_SVC + .endm + + .macro enable_irq, temp + set_cpsr_c \temp, #MODE_SVC + .endm +#endif + + .macro save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0 - r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling sp, lr + mrs r8, spsr @ called from non-FIQ mode, so ok. + str lr, [sp, #S_PC] @ Save calling PC + str r8, [sp, #S_PSR] @ Save CPSR + str r0, [sp, #S_OLD_R0] @ Save OLD_R0 + .endm + + .macro restore_user_regs + ldr r1, [sp, #S_PSR] @ Get calling cpsr + disable_irq ip @ disable IRQs + ldr lr, [sp, #S_PC]! @ Get PC + msr spsr_cxsf, r1 @ save in spsr_svc + ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr + mov r0, r0 + add sp, sp, #S_FRAME_SIZE - S_PC + movs pc, lr @ return & move spsr_svc into cpsr + .endm + +/* + * Must be called with IRQs already disabled. + */ + .macro fast_restore_user_regs + ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr + ldr lr, [sp, #S_OFF + S_PC]! @ get pc + msr spsr_cxsf, r1 @ save in spsr_svc + ldmdb sp, {r1 - lr}^ @ get calling r1 - lr + mov r0, r0 + add sp, sp, #S_FRAME_SIZE - S_PC + movs pc, lr @ return & move spsr_svc into cpsr + .endm + +/* + * Must be called with IRQs already disabled. + */ + .macro slow_restore_user_regs + ldr r1, [sp, #S_PSR] @ get calling cpsr + ldr lr, [sp, #S_PC]! @ get pc + msr spsr_cxsf, r1 @ save in spsr_svc + ldmdb sp, {r0 - lr}^ @ get calling r1 - lr + mov r0, r0 + add sp, sp, #S_FRAME_SIZE - S_PC + movs pc, lr @ return & move spsr_svc into cpsr + .endm + + .macro mask_pc, rd, rm + .endm + + .macro get_thread_info, rd + mov \rd, sp, lsr #13 + mov \rd, \rd, lsl #13 + .endm + + .macro alignment_trap, rbase, rtemp, sym +#ifdef CONFIG_ALIGNMENT_TRAP +#define OFF_CR_ALIGNMENT(x) cr_alignment - x + + ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)] + mcr p15, 0, \rtemp, c1, c0 +#endif + .endm + + +/* + * These are the registers used in the syscall handler, and allow us to + * have in theory up to 7 arguments to a function - r0 to r6. + * + * r7 is reserved for the system call number for thumb mode. + * + * Note that tbl == why is intentional. + * + * We must set at least "tsk" and "why" when calling ret_with_reschedule. + */ +scno .req r7 @ syscall number +tbl .req r8 @ syscall table pointer +why .req r8 @ Linux syscall (!= 0) +tsk .req r9 @ current thread_info + +/* + * Get the system call number. + */ + .macro get_scno +#ifdef CONFIG_ARM_THUMB + tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs + addne scno, r7, #OS_NUMBER << 20 @ put OS number in + ldreq scno, [lr, #-4] + +#else + mask_pc lr, lr + ldr scno, [lr, #-4] @ get SWI instruction +#endif + .endm diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c new file mode 100644 index 0000000..9299dfc25 --- /dev/null +++ b/arch/arm/kernel/fiq.c @@ -0,0 +1,181 @@ +/* + * linux/arch/arm/kernel/fiq.c + * + * Copyright (C) 1998 Russell King + * Copyright (C) 1998, 1999 Phil Blundell + * + * FIQ support written by Philip Blundell <philb@gnu.org>, 1998. + * + * FIQ support re-written by Russell King to be more generic + * + * We now properly support a method by which the FIQ handlers can + * be stacked onto the vector. We still do not support sharing + * the FIQ vector itself. + * + * Operation is as follows: + * 1. Owner A claims FIQ: + * - default_fiq relinquishes control. + * 2. Owner A: + * - inserts code. + * - sets any registers, + * - enables FIQ. + * 3. Owner B claims FIQ: + * - if owner A has a relinquish function. + * - disable FIQs. + * - saves any registers. + * - returns zero. + * 4. Owner B: + * - inserts code. + * - sets any registers, + * - enables FIQ. + * 5. Owner B releases FIQ: + * - Owner A is asked to reacquire FIQ: + * - inserts code. + * - restores saved registers. + * - enables FIQ. + * 6. Goto 3 + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/seq_file.h> + +#include <asm/cacheflush.h> +#include <asm/fiq.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/uaccess.h> + +static unsigned long no_fiq_insn; + +/* Default reacquire function + * - we always relinquish FIQ control + * - we always reacquire FIQ control + */ +static int fiq_def_op(void *ref, int relinquish) +{ + if (!relinquish) + set_fiq_handler(&no_fiq_insn, sizeof(no_fiq_insn)); + + return 0; +} + +static struct fiq_handler default_owner = { + .name = "default", + .fiq_op = fiq_def_op, +}; + +static struct fiq_handler *current_fiq = &default_owner; + +int show_fiq_list(struct seq_file *p, void *v) +{ + if (current_fiq != &default_owner) + seq_printf(p, "FIQ: %s\n", current_fiq->name); + + return 0; +} + +void set_fiq_handler(void *start, unsigned int length) +{ + memcpy((void *)0xffff001c, start, length); + flush_icache_range(0xffff001c, 0xffff001c + length); + if (!vectors_high()) + flush_icache_range(0x1c, 0x1c + length); +} + +/* + * Taking an interrupt in FIQ mode is death, so both these functions + * disable irqs for the duration. Note - these functions are almost + * entirely coded in assembly. + */ +void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs) +{ + register unsigned long tmp; + asm volatile ( + "mov ip, sp\n\ + stmfd sp!, {fp, ip, lr, pc}\n\ + sub fp, ip, #4\n\ + mrs %0, cpsr\n\ + msr cpsr_c, %2 @ select FIQ mode\n\ + mov r0, r0\n\ + ldmia %1, {r8 - r14}\n\ + msr cpsr_c, %0 @ return to SVC mode\n\ + mov r0, r0\n\ + ldmea fp, {fp, sp, pc}" + : "=&r" (tmp) + : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); +} + +void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs) +{ + register unsigned long tmp; + asm volatile ( + "mov ip, sp\n\ + stmfd sp!, {fp, ip, lr, pc}\n\ + sub fp, ip, #4\n\ + mrs %0, cpsr\n\ + msr cpsr_c, %2 @ select FIQ mode\n\ + mov r0, r0\n\ + stmia %1, {r8 - r14}\n\ + msr cpsr_c, %0 @ return to SVC mode\n\ + mov r0, r0\n\ + ldmea fp, {fp, sp, pc}" + : "=&r" (tmp) + : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); +} + +int claim_fiq(struct fiq_handler *f) +{ + int ret = 0; + + if (current_fiq) { + ret = -EBUSY; + + if (current_fiq->fiq_op != NULL) + ret = current_fiq->fiq_op(current_fiq->dev_id, 1); + } + + if (!ret) { + f->next = current_fiq; + current_fiq = f; + } + + return ret; +} + +void release_fiq(struct fiq_handler *f) +{ + if (current_fiq != f) { + printk(KERN_ERR "%s FIQ trying to release %s FIQ\n", + f->name, current_fiq->name); + dump_stack(); + return; + } + + do + current_fiq = current_fiq->next; + while (current_fiq->fiq_op(current_fiq->dev_id, 0)); +} + +void enable_fiq(int fiq) +{ + enable_irq(fiq + FIQ_START); +} + +void disable_fiq(int fiq) +{ + disable_irq(fiq + FIQ_START); +} + +EXPORT_SYMBOL(set_fiq_handler); +EXPORT_SYMBOL(set_fiq_regs); +EXPORT_SYMBOL(get_fiq_regs); +EXPORT_SYMBOL(claim_fiq); +EXPORT_SYMBOL(release_fiq); +EXPORT_SYMBOL(enable_fiq); +EXPORT_SYMBOL(disable_fiq); + +void __init init_FIQ(void) +{ + no_fiq_insn = *(unsigned long *)0xffff001c; +} diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S new file mode 100644 index 0000000..171b3e8 --- /dev/null +++ b/arch/arm/kernel/head.S @@ -0,0 +1,516 @@ +/* + * linux/arch/arm/kernel/head.S + * + * Copyright (C) 1994-2002 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. + * + * Kernel startup code for all 32-bit CPUs + */ +#include <linux/config.h> +#include <linux/linkage.h> +#include <linux/init.h> + +#include <asm/assembler.h> +#include <asm/domain.h> +#include <asm/mach-types.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> +#include <asm/constants.h> +#include <asm/system.h> + +#define PROCINFO_MMUFLAGS 8 +#define PROCINFO_INITFUNC 12 + +#define MACHINFO_TYPE 0 +#define MACHINFO_PHYSRAM 4 +#define MACHINFO_PHYSIO 8 +#define MACHINFO_PGOFFIO 12 +#define MACHINFO_NAME 16 + +#ifndef CONFIG_XIP_KERNEL +/* + * We place the page tables 16K below TEXTADDR. Therefore, we must make sure + * that TEXTADDR is correctly set. Currently, we expect the least significant + * 16 bits to be 0x8000, but we could probably relax this restriction to + * TEXTADDR >= PAGE_OFFSET + 0x4000 + * + * Note that swapper_pg_dir is the virtual address of the page tables, and + * pgtbl gives us a position-independent reference to these tables. We can + * do this because stext == TEXTADDR + */ +#if (TEXTADDR & 0xffff) != 0x8000 +#error TEXTADDR must start at 0xXXXX8000 +#endif + + .globl swapper_pg_dir + .equ swapper_pg_dir, TEXTADDR - 0x4000 + + .macro pgtbl, rd, phys + adr \rd, stext + sub \rd, \rd, #0x4000 + .endm +#else +/* + * XIP Kernel: + * + * We place the page tables 16K below DATAADDR. Therefore, we must make sure + * that DATAADDR is correctly set. Currently, we expect the least significant + * 16 bits to be 0x8000, but we could probably relax this restriction to + * DATAADDR >= PAGE_OFFSET + 0x4000 + * + * Note that pgtbl is meant to return the physical address of swapper_pg_dir. + * We can't make it relative to the kernel position in this case since + * the kernel can physically be anywhere. + */ +#if (DATAADDR & 0xffff) != 0x8000 +#error DATAADDR must start at 0xXXXX8000 +#endif + + .globl swapper_pg_dir + .equ swapper_pg_dir, DATAADDR - 0x4000 + + .macro pgtbl, rd, phys + ldr \rd, =((DATAADDR - 0x4000) - VIRT_OFFSET) + add \rd, \rd, \phys + .endm +#endif + +/* + * Kernel startup entry point. + * --------------------------- + * + * This is normally called from the decompressor code. The requirements + * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, + * r1 = machine nr. + * + * This code is mostly position independent, so if you link the kernel at + * 0xc0008000, you call this at __pa(0xc0008000). + * + * See linux/arch/arm/tools/mach-types for the complete list of machine + * numbers for r1. + * + * We're trying to keep crap to a minimum; DO NOT add any machine specific + * crap here - that's what the boot loader (or in extreme, well justified + * circumstances, zImage) is for. + */ + __INIT + .type stext, %function +ENTRY(stext) + msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode + @ and irqs disabled + bl __lookup_processor_type @ r5=procinfo r9=cpuid + movs r10, r5 @ invalid processor (r5=0)? + beq __error_p @ yes, error 'p' + bl __lookup_machine_type @ r5=machinfo + movs r8, r5 @ invalid machine (r5=0)? + beq __error_a @ yes, error 'a' + bl __create_page_tables + + /* + * The following calls CPU specific code in a position independent + * manner. See arch/arm/mm/proc-*.S for details. r10 = base of + * xxx_proc_info structure selected by __lookup_machine_type + * above. On return, the CPU will be ready for the MMU to be + * turned on, and r0 will hold the CPU control register value. + */ + ldr r13, __switch_data @ address to jump to after + @ mmu has been enabled + adr lr, __enable_mmu @ return (PIC) address + add pc, r10, #PROCINFO_INITFUNC + + .type __switch_data, %object +__switch_data: + .long __mmap_switched + .long __data_loc @ r4 + .long __data_start @ r5 + .long __bss_start @ r6 + .long _end @ r7 + .long processor_id @ r4 + .long __machine_arch_type @ r5 + .long cr_alignment @ r6 + .long init_thread_union+8192 @ sp + +/* + * The following fragment of code is executed with the MMU on, and uses + * absolute addresses; this is not position independent. + * + * r0 = cp#15 control register + * r1 = machine ID + * r9 = processor ID + */ + .type __mmap_switched, %function +__mmap_switched: + adr r3, __switch_data + 4 + + ldmia r3!, {r4, r5, r6, r7} + cmp r4, r5 @ Copy data segment if needed +1: cmpne r5, r6 + ldrne fp, [r4], #4 + strne fp, [r5], #4 + bne 1b + + mov fp, #0 @ Clear BSS (and zero fp) +1: cmp r6, r7 + strcc fp, [r6],#4 + bcc 1b + + ldmia r3, {r4, r5, r6, sp} + str r9, [r4] @ Save processor ID + str r1, [r5] @ Save machine type + bic r4, r0, #CR_A @ Clear 'A' bit + stmia r6, {r0, r4} @ Save control register values + b start_kernel + + + +/* + * Setup common bits before finally enabling the MMU. Essentially + * this is just loading the page table pointer and domain access + * registers. + */ + .type __enable_mmu, %function +__enable_mmu: +#ifdef CONFIG_ALIGNMENT_TRAP + orr r0, r0, #CR_A +#else + bic r0, r0, #CR_A +#endif +#ifdef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CR_C +#endif +#ifdef CONFIG_CPU_BPREDICT_DISABLE + bic r0, r0, #CR_Z +#endif +#ifdef CONFIG_CPU_ICACHE_DISABLE + bic r0, r0, #CR_I +#endif + mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_IO, DOMAIN_CLIENT)) + mcr p15, 0, r5, c3, c0, 0 @ load domain access register + mcr p15, 0, r4, c2, c0, 0 @ load page table pointer + b __turn_mmu_on + +/* + * Enable the MMU. This completely changes the structure of the visible + * memory space. You will not be able to trace execution through this. + * If you have an enquiry about this, *please* check the linux-arm-kernel + * mailing list archives BEFORE sending another post to the list. + * + * r0 = cp#15 control register + * r13 = *virtual* address to jump to upon completion + * + * other registers depend on the function called upon completion + */ + .align 5 + .type __turn_mmu_on, %function +__turn_mmu_on: + mov r0, r0 + mcr p15, 0, r0, c1, c0, 0 @ write control reg + mrc p15, 0, r3, c0, c0, 0 @ read id reg + mov r3, r3 + mov r3, r3 + mov pc, r13 + + + +/* + * Setup the initial page tables. We only setup the barest + * amount which are required to get the kernel running, which + * generally means mapping in the kernel code. + * + * r8 = machinfo + * r9 = cpuid + * r10 = procinfo + * + * Returns: + * r0, r3, r5, r6, r7 corrupted + * r4 = physical page table address + */ + .type __create_page_tables, %function +__create_page_tables: + ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram + pgtbl r4, r5 @ page table address + + /* + * Clear the 16K level 1 swapper page table + */ + mov r0, r4 + mov r3, #0 + add r6, r0, #0x4000 +1: str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 + teq r0, r6 + bne 1b + + ldr r7, [r10, #PROCINFO_MMUFLAGS] @ mmuflags + + /* + * Create identity mapping for first MB of kernel to + * cater for the MMU enable. This identity mapping + * will be removed by paging_init(). We use our current program + * counter to determine corresponding section base address. + */ + mov r6, pc, lsr #20 @ start of kernel section + orr r3, r7, r6, lsl #20 @ flags + kernel base + str r3, [r4, r6, lsl #2] @ identity mapping + + /* + * Now setup the pagetables for our kernel direct + * mapped region. We round TEXTADDR down to the + * nearest megabyte boundary. It is assumed that + * the kernel fits within 4 contigous 1MB sections. + */ + add r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel + str r3, [r0, #(TEXTADDR & 0x00f00000) >> 18]! + add r3, r3, #1 << 20 + str r3, [r0, #4]! @ KERNEL + 1MB + add r3, r3, #1 << 20 + str r3, [r0, #4]! @ KERNEL + 2MB + add r3, r3, #1 << 20 + str r3, [r0, #4] @ KERNEL + 3MB + + /* + * Then map first 1MB of ram in case it contains our boot params. + */ + add r0, r4, #VIRT_OFFSET >> 18 + orr r6, r5, r7 + str r6, [r0] + +#ifdef CONFIG_XIP_KERNEL + /* + * Map some ram to cover our .data and .bss areas. + * Mapping 3MB should be plenty. + */ + sub r3, r4, r5 + mov r3, r3, lsr #20 + add r0, r0, r3, lsl #2 + add r6, r6, r3, lsl #20 + str r6, [r0], #4 + add r6, r6, #(1 << 20) + str r6, [r0], #4 + add r6, r6, #(1 << 20) + str r6, [r0] +#endif + + bic r7, r7, #0x0c @ turn off cacheable + @ and bufferable bits +#ifdef CONFIG_DEBUG_LL + /* + * Map in IO space for serial debugging. + * This allows debug messages to be output + * via a serial console before paging_init. + */ + ldr r3, [r8, #MACHINFO_PGOFFIO] + add r0, r4, r3 + rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long) + cmp r3, #0x0800 @ limit to 512MB + movhi r3, #0x0800 + add r6, r0, r3 + ldr r3, [r8, #MACHINFO_PHYSIO] + orr r3, r3, r7 +1: str r3, [r0], #4 + add r3, r3, #1 << 20 + teq r0, r6 + bne 1b +#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) + /* + * If we're using the NetWinder, we need to map in + * the 16550-type serial port for the debug messages + */ + teq r1, #MACH_TYPE_NETWINDER + teqne r1, #MACH_TYPE_CATS + bne 1f + add r0, r4, #0x3fc0 @ ff000000 + mov r3, #0x7c000000 + orr r3, r3, r7 + str r3, [r0], #4 + add r3, r3, #1 << 20 + str r3, [r0], #4 +1: +#endif +#endif +#ifdef CONFIG_ARCH_RPC + /* + * Map in screen at 0x02000000 & SCREEN2_BASE + * Similar reasons here - for debug. This is + * only for Acorn RiscPC architectures. + */ + add r0, r4, #0x80 @ 02000000 + mov r3, #0x02000000 + orr r3, r3, r7 + str r3, [r0] + add r0, r4, #0x3600 @ d8000000 + str r3, [r0] +#endif + mov pc, lr + .ltorg + + + +/* + * Exception handling. Something went wrong and we can't proceed. We + * ought to tell the user, but since we don't have any guarantee that + * we're even running on the right architecture, we do virtually nothing. + * + * If CONFIG_DEBUG_LL is set we try to print out something about the error + * and hope for the best (useful if bootloader fails to pass a proper + * machine ID for example). + */ + + .type __error_p, %function +__error_p: +#ifdef CONFIG_DEBUG_LL + adr r0, str_p1 + bl printascii + b __error +str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n" + .align +#endif + + .type __error_a, %function +__error_a: +#ifdef CONFIG_DEBUG_LL + mov r4, r1 @ preserve machine ID + adr r0, str_a1 + bl printascii + mov r0, r4 + bl printhex8 + adr r0, str_a2 + bl printascii + adr r3, 3f + ldmia r3, {r4, r5, r6} @ get machine desc list + sub r4, r3, r4 @ get offset between virt&phys + add r5, r5, r4 @ convert virt addresses to + add r6, r6, r4 @ physical address space +1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type + bl printhex8 + mov r0, #'\t' + bl printch + ldr r0, [r5, #MACHINFO_NAME] @ get machine name + add r0, r0, r4 + bl printascii + mov r0, #'\n' + bl printch + add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc + cmp r5, r6 + blo 1b + adr r0, str_a3 + bl printascii + b __error +str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" +str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" +str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" + .align +#endif + + .type __error, %function +__error: +#ifdef CONFIG_ARCH_RPC +/* + * Turn the screen red on a error - RiscPC only. + */ + mov r0, #0x02000000 + mov r3, #0x11 + orr r3, r3, r3, lsl #8 + orr r3, r3, r3, lsl #16 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 +#endif +1: mov r0, r0 + b 1b + + +/* + * Read processor ID register (CP#15, CR0), and look up in the linker-built + * supported processor list. Note that we can't use the absolute addresses + * for the __proc_info lists since we aren't running with the MMU on + * (and therefore, we are not in the correct address space). We have to + * calculate the offset. + * + * Returns: + * r3, r4, r6 corrupted + * r5 = proc_info pointer in physical address space + * r9 = cpuid + */ + .type __lookup_processor_type, %function +__lookup_processor_type: + adr r3, 3f + ldmda r3, {r5, r6, r9} + sub r3, r3, r9 @ get offset between virt&phys + add r5, r5, r3 @ convert virt addresses to + add r6, r6, r3 @ physical address space + mrc p15, 0, r9, c0, c0 @ get processor id +1: ldmia r5, {r3, r4} @ value, mask + and r4, r4, r9 @ mask wanted bits + teq r3, r4 + beq 2f + add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) + cmp r5, r6 + blo 1b + mov r5, #0 @ unknown processor +2: mov pc, lr + +/* + * This provides a C-API version of the above function. + */ +ENTRY(lookup_processor_type) + stmfd sp!, {r4 - r6, r9, lr} + bl __lookup_processor_type + mov r0, r5 + ldmfd sp!, {r4 - r6, r9, pc} + +/* + * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for + * more information about the __proc_info and __arch_info structures. + */ + .long __proc_info_begin + .long __proc_info_end +3: .long . + .long __arch_info_begin + .long __arch_info_end + +/* + * Lookup machine architecture in the linker-build list of architectures. + * Note that we can't use the absolute addresses for the __arch_info + * lists since we aren't running with the MMU on (and therefore, we are + * not in the correct address space). We have to calculate the offset. + * + * r1 = machine architecture number + * Returns: + * r3, r4, r6 corrupted + * r5 = mach_info pointer in physical address space + */ + .type __lookup_machine_type, %function +__lookup_machine_type: + adr r3, 3b + ldmia r3, {r4, r5, r6} + sub r3, r3, r4 @ get offset between virt&phys + add r5, r5, r3 @ convert virt addresses to + add r6, r6, r3 @ physical address space +1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type + teq r3, r1 @ matches loader number? + beq 2f @ found + add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc + cmp r5, r6 + blo 1b + mov r5, #0 @ unknown machine +2: mov pc, lr + +/* + * This provides a C-API version of the above function. + */ +ENTRY(lookup_machine_type) + stmfd sp!, {r4 - r6, lr} + mov r1, r0 + bl __lookup_machine_type + mov r0, r5 + ldmfd sp!, {r4 - r6, pc} diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c new file mode 100644 index 0000000..a00cca0 --- /dev/null +++ b/arch/arm/kernel/init_task.c @@ -0,0 +1,44 @@ +/* + * linux/arch/arm/kernel/init_task.c + */ +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/init_task.h> +#include <linux/mqueue.h> + +#include <asm/uaccess.h> +#include <asm/pgtable.h> + +static struct fs_struct init_fs = INIT_FS; +static struct files_struct init_files = INIT_FILES; +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); +struct mm_struct init_mm = INIT_MM(init_mm); + +EXPORT_SYMBOL(init_mm); + +/* + * Initial thread structure. + * + * We need to make sure that this is 8192-byte aligned due to the + * way process stacks are handled. This is done by making sure + * the linker maps this in the .text segment right after head.S, + * and making head.S ensure the proper alignment. + * + * The things we do for performance.. + */ +union thread_union init_thread_union + __attribute__((__section__(".init.task"))) = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); + +EXPORT_SYMBOL(init_task); diff --git a/arch/arm/kernel/io.c b/arch/arm/kernel/io.c new file mode 100644 index 0000000..6c20c11 --- /dev/null +++ b/arch/arm/kernel/io.c @@ -0,0 +1,51 @@ +#include <linux/module.h> +#include <linux/types.h> + +#include <asm/io.h> + +/* + * Copy data from IO memory space to "real" memory space. + * This needs to be optimized. + */ +void _memcpy_fromio(void *to, void __iomem *from, size_t count) +{ + unsigned char *t = to; + while (count) { + count--; + *t = readb(from); + t++; + from++; + } +} + +/* + * Copy data from "real" memory space to IO memory space. + * This needs to be optimized. + */ +void _memcpy_toio(void __iomem *to, const void *from, size_t count) +{ + const unsigned char *f = from; + while (count) { + count--; + writeb(*f, to); + f++; + to++; + } +} + +/* + * "memset" on IO memory space. + * This needs to be optimized. + */ +void _memset_io(void __iomem *dst, int c, size_t count) +{ + while (count) { + count--; + writeb(c, dst); + dst++; + } +} + +EXPORT_SYMBOL(_memcpy_fromio); +EXPORT_SYMBOL(_memcpy_toio); +EXPORT_SYMBOL(_memset_io); diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c new file mode 100644 index 0000000..ff187f4 --- /dev/null +++ b/arch/arm/kernel/irq.c @@ -0,0 +1,1038 @@ +/* + * linux/arch/arm/kernel/irq.c + * + * Copyright (C) 1992 Linus Torvalds + * Modifications for ARM processor 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. + * + * This file contains the code used by various IRQ handling routines: + * asking for different IRQ's should be done through these routines + * instead of just grabbing them. Thus setups with different IRQ numbers + * shouldn't result in any weird surprises, and installing new handlers + * should be easier. + * + * IRQ's are in fact implemented a bit like signal handlers for the kernel. + * Naturally it's not a 1:1 relation, but there are similarities. + */ +#include <linux/config.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/smp.h> +#include <linux/init.h> +#include <linux/seq_file.h> +#include <linux/errno.h> +#include <linux/list.h> +#include <linux/kallsyms.h> +#include <linux/proc_fs.h> + +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/mach/irq.h> + +/* + * Maximum IRQ count. Currently, this is arbitary. However, it should + * not be set too low to prevent false triggering. Conversely, if it + * is set too high, then you could miss a stuck IRQ. + * + * Maybe we ought to set a timer and re-enable the IRQ at a later time? + */ +#define MAX_IRQ_CNT 100000 + +static int noirqdebug; +static volatile unsigned long irq_err_count; +static DEFINE_SPINLOCK(irq_controller_lock); +static LIST_HEAD(irq_pending); + +struct irqdesc irq_desc[NR_IRQS]; +void (*init_arch_irq)(void) __initdata = NULL; + +/* + * No architecture-specific irq_finish function defined in arm/arch/irqs.h. + */ +#ifndef irq_finish +#define irq_finish(irq) do { } while (0) +#endif + +/* + * Dummy mask/unmask handler + */ +void dummy_mask_unmask_irq(unsigned int irq) +{ +} + +irqreturn_t no_action(int irq, void *dev_id, struct pt_regs *regs) +{ + return IRQ_NONE; +} + +void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + irq_err_count += 1; + printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); +} + +static struct irqchip bad_chip = { + .ack = dummy_mask_unmask_irq, + .mask = dummy_mask_unmask_irq, + .unmask = dummy_mask_unmask_irq, +}; + +static struct irqdesc bad_irq_desc = { + .chip = &bad_chip, + .handle = do_bad_IRQ, + .pend = LIST_HEAD_INIT(bad_irq_desc.pend), + .disable_depth = 1, +}; + +#ifdef CONFIG_SMP +void synchronize_irq(unsigned int irq) +{ + struct irqdesc *desc = irq_desc + irq; + + while (desc->running) + barrier(); +} +EXPORT_SYMBOL(synchronize_irq); + +#define smp_set_running(desc) do { desc->running = 1; } while (0) +#define smp_clear_running(desc) do { desc->running = 0; } while (0) +#else +#define smp_set_running(desc) do { } while (0) +#define smp_clear_running(desc) do { } while (0) +#endif + +/** + * disable_irq_nosync - disable an irq without waiting + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Enables and disables + * are nested. We do this lazily. + * + * This function may be called from IRQ context. + */ +void disable_irq_nosync(unsigned int irq) +{ + struct irqdesc *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&irq_controller_lock, flags); + desc->disable_depth++; + list_del_init(&desc->pend); + spin_unlock_irqrestore(&irq_controller_lock, flags); +} +EXPORT_SYMBOL(disable_irq_nosync); + +/** + * disable_irq - disable an irq and wait for completion + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Enables and disables + * are nested. This functions waits for any pending IRQ + * handlers for this interrupt to complete before returning. + * If you use this function while holding a resource the IRQ + * handler may need you will deadlock. + * + * This function may be called - with care - from IRQ context. + */ +void disable_irq(unsigned int irq) +{ + struct irqdesc *desc = irq_desc + irq; + + disable_irq_nosync(irq); + if (desc->action) + synchronize_irq(irq); +} +EXPORT_SYMBOL(disable_irq); + +/** + * enable_irq - enable interrupt handling on an irq + * @irq: Interrupt to enable + * + * Re-enables the processing of interrupts on this IRQ line. + * Note that this may call the interrupt handler, so you may + * get unexpected results if you hold IRQs disabled. + * + * This function may be called from IRQ context. + */ +void enable_irq(unsigned int irq) +{ + struct irqdesc *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&irq_controller_lock, flags); + if (unlikely(!desc->disable_depth)) { + printk("enable_irq(%u) unbalanced from %p\n", irq, + __builtin_return_address(0)); + } else if (!--desc->disable_depth) { + desc->probing = 0; + desc->chip->unmask(irq); + + /* + * If the interrupt is waiting to be processed, + * try to re-run it. We can't directly run it + * from here since the caller might be in an + * interrupt-protected region. + */ + if (desc->pending && list_empty(&desc->pend)) { + desc->pending = 0; + if (!desc->chip->retrigger || + desc->chip->retrigger(irq)) + list_add(&desc->pend, &irq_pending); + } + } + spin_unlock_irqrestore(&irq_controller_lock, flags); +} +EXPORT_SYMBOL(enable_irq); + +/* + * Enable wake on selected irq + */ +void enable_irq_wake(unsigned int irq) +{ + struct irqdesc *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&irq_controller_lock, flags); + if (desc->chip->wake) + desc->chip->wake(irq, 1); + spin_unlock_irqrestore(&irq_controller_lock, flags); +} +EXPORT_SYMBOL(enable_irq_wake); + +void disable_irq_wake(unsigned int irq) +{ + struct irqdesc *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&irq_controller_lock, flags); + if (desc->chip->wake) + desc->chip->wake(irq, 0); + spin_unlock_irqrestore(&irq_controller_lock, flags); +} +EXPORT_SYMBOL(disable_irq_wake); + +int show_interrupts(struct seq_file *p, void *v) +{ + int i = *(loff_t *) v, cpu; + struct irqaction * action; + unsigned long flags; + + if (i == 0) { + char cpuname[12]; + + seq_printf(p, " "); + for_each_present_cpu(cpu) { + sprintf(cpuname, "CPU%d", cpu); + seq_printf(p, " %10s", cpuname); + } + seq_putc(p, '\n'); + } + + if (i < NR_IRQS) { + spin_lock_irqsave(&irq_controller_lock, flags); + action = irq_desc[i].action; + if (!action) + goto unlock; + + seq_printf(p, "%3d: ", i); + for_each_present_cpu(cpu) + seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); + seq_printf(p, " %s", action->name); + for (action = action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +unlock: + spin_unlock_irqrestore(&irq_controller_lock, flags); + } else if (i == NR_IRQS) { +#ifdef CONFIG_ARCH_ACORN + show_fiq_list(p, v); +#endif +#ifdef CONFIG_SMP + show_ipi_list(p); +#endif + seq_printf(p, "Err: %10lu\n", irq_err_count); + } + return 0; +} + +/* + * IRQ lock detection. + * + * Hopefully, this should get us out of a few locked situations. + * However, it may take a while for this to happen, since we need + * a large number if IRQs to appear in the same jiffie with the + * same instruction pointer (or within 2 instructions). + */ +static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs) +{ + unsigned long instr_ptr = instruction_pointer(regs); + + if (desc->lck_jif == jiffies && + desc->lck_pc >= instr_ptr && desc->lck_pc < instr_ptr + 8) { + desc->lck_cnt += 1; + + if (desc->lck_cnt > MAX_IRQ_CNT) { + printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq); + return 1; + } + } else { + desc->lck_cnt = 0; + desc->lck_pc = instruction_pointer(regs); + desc->lck_jif = jiffies; + } + return 0; +} + +static void +report_bad_irq(unsigned int irq, struct pt_regs *regs, struct irqdesc *desc, int ret) +{ + static int count = 100; + struct irqaction *action; + + if (!count || noirqdebug) + return; + + count--; + + if (ret != IRQ_HANDLED && ret != IRQ_NONE) { + printk("irq%u: bogus retval mask %x\n", irq, ret); + } else { + printk("irq%u: nobody cared\n", irq); + } + show_regs(regs); + dump_stack(); + printk(KERN_ERR "handlers:"); + action = desc->action; + do { + printk("\n" KERN_ERR "[<%p>]", action->handler); + print_symbol(" (%s)", (unsigned long)action->handler); + action = action->next; + } while (action); + printk("\n"); +} + +static int +__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) +{ + unsigned int status; + int ret, retval = 0; + + spin_unlock(&irq_controller_lock); + + if (!(action->flags & SA_INTERRUPT)) + local_irq_enable(); + + status = 0; + do { + ret = action->handler(irq, action->dev_id, regs); + if (ret == IRQ_HANDLED) + status |= action->flags; + retval |= ret; + action = action->next; + } while (action); + + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + + spin_lock_irq(&irq_controller_lock); + + return retval; +} + +/* + * This is for software-decoded IRQs. The caller is expected to + * handle the ack, clear, mask and unmask issues. + */ +void +do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + struct irqaction *action; + const unsigned int cpu = smp_processor_id(); + + desc->triggered = 1; + + kstat_cpu(cpu).irqs[irq]++; + + smp_set_running(desc); + + action = desc->action; + if (action) { + int ret = __do_irq(irq, action, regs); + if (ret != IRQ_HANDLED) + report_bad_irq(irq, regs, desc, ret); + } + + smp_clear_running(desc); +} + +/* + * Most edge-triggered IRQ implementations seem to take a broken + * approach to this. Hence the complexity. + */ +void +do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + const unsigned int cpu = smp_processor_id(); + + desc->triggered = 1; + + /* + * If we're currently running this IRQ, or its disabled, + * we shouldn't process the IRQ. Instead, turn on the + * hardware masks. + */ + if (unlikely(desc->running || desc->disable_depth)) + goto running; + + /* + * Acknowledge and clear the IRQ, but don't mask it. + */ + desc->chip->ack(irq); + + /* + * Mark the IRQ currently in progress. + */ + desc->running = 1; + + kstat_cpu(cpu).irqs[irq]++; + + do { + struct irqaction *action; + + action = desc->action; + if (!action) + break; + + if (desc->pending && !desc->disable_depth) { + desc->pending = 0; + desc->chip->unmask(irq); + } + + __do_irq(irq, action, regs); + } while (desc->pending && !desc->disable_depth); + + desc->running = 0; + + /* + * If we were disabled or freed, shut down the handler. + */ + if (likely(desc->action && !check_irq_lock(desc, irq, regs))) + return; + + running: + /* + * We got another IRQ while this one was masked or + * currently running. Delay it. + */ + desc->pending = 1; + desc->chip->mask(irq); + desc->chip->ack(irq); +} + +/* + * Level-based IRQ handler. Nice and simple. + */ +void +do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + struct irqaction *action; + const unsigned int cpu = smp_processor_id(); + + desc->triggered = 1; + + /* + * Acknowledge, clear _AND_ disable the interrupt. + */ + desc->chip->ack(irq); + + if (likely(!desc->disable_depth)) { + kstat_cpu(cpu).irqs[irq]++; + + smp_set_running(desc); + + /* + * Return with this interrupt masked if no action + */ + action = desc->action; + if (action) { + int ret = __do_irq(irq, desc->action, regs); + + if (ret != IRQ_HANDLED) + report_bad_irq(irq, regs, desc, ret); + + if (likely(!desc->disable_depth && + !check_irq_lock(desc, irq, regs))) + desc->chip->unmask(irq); + } + + smp_clear_running(desc); + } +} + +static void do_pending_irqs(struct pt_regs *regs) +{ + struct list_head head, *l, *n; + + do { + struct irqdesc *desc; + + /* + * First, take the pending interrupts off the list. + * The act of calling the handlers may add some IRQs + * back onto the list. + */ + head = irq_pending; + INIT_LIST_HEAD(&irq_pending); + head.next->prev = &head; + head.prev->next = &head; + + /* + * Now run each entry. We must delete it from our + * list before calling the handler. + */ + list_for_each_safe(l, n, &head) { + desc = list_entry(l, struct irqdesc, pend); + list_del_init(&desc->pend); + desc->handle(desc - irq_desc, desc, regs); + } + + /* + * The list must be empty. + */ + BUG_ON(!list_empty(&head)); + } while (!list_empty(&irq_pending)); +} + +/* + * do_IRQ handles all hardware IRQ's. Decoded IRQs should not + * come via this function. Instead, they should provide their + * own 'handler' + */ +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) +{ + struct irqdesc *desc = irq_desc + irq; + + /* + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. + */ + if (irq >= NR_IRQS) + desc = &bad_irq_desc; + + irq_enter(); + spin_lock(&irq_controller_lock); + desc->handle(irq, desc, regs); + + /* + * Now re-run any pending interrupts. + */ + if (!list_empty(&irq_pending)) + do_pending_irqs(regs); + + irq_finish(irq); + + spin_unlock(&irq_controller_lock); + irq_exit(); +} + +void __set_irq_handler(unsigned int irq, irq_handler_t handle, int is_chained) +{ + struct irqdesc *desc; + unsigned long flags; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq); + return; + } + + if (handle == NULL) + handle = do_bad_IRQ; + + desc = irq_desc + irq; + + if (is_chained && desc->chip == &bad_chip) + printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq); + + spin_lock_irqsave(&irq_controller_lock, flags); + if (handle == do_bad_IRQ) { + desc->chip->mask(irq); + desc->chip->ack(irq); + desc->disable_depth = 1; + } + desc->handle = handle; + if (handle != do_bad_IRQ && is_chained) { + desc->valid = 0; + desc->probe_ok = 0; + desc->disable_depth = 0; + desc->chip->unmask(irq); + } + spin_unlock_irqrestore(&irq_controller_lock, flags); +} + +void set_irq_chip(unsigned int irq, struct irqchip *chip) +{ + struct irqdesc *desc; + unsigned long flags; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq); + return; + } + + if (chip == NULL) + chip = &bad_chip; + + desc = irq_desc + irq; + spin_lock_irqsave(&irq_controller_lock, flags); + desc->chip = chip; + spin_unlock_irqrestore(&irq_controller_lock, flags); +} + +int set_irq_type(unsigned int irq, unsigned int type) +{ + struct irqdesc *desc; + unsigned long flags; + int ret = -ENXIO; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq); + return -ENODEV; + } + + desc = irq_desc + irq; + if (desc->chip->type) { + spin_lock_irqsave(&irq_controller_lock, flags); + ret = desc->chip->type(irq, type); + spin_unlock_irqrestore(&irq_controller_lock, flags); + } + + return ret; +} +EXPORT_SYMBOL(set_irq_type); + +void set_irq_flags(unsigned int irq, unsigned int iflags) +{ + struct irqdesc *desc; + unsigned long flags; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq); + return; + } + + desc = irq_desc + irq; + spin_lock_irqsave(&irq_controller_lock, flags); + desc->valid = (iflags & IRQF_VALID) != 0; + desc->probe_ok = (iflags & IRQF_PROBE) != 0; + desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0; + spin_unlock_irqrestore(&irq_controller_lock, flags); +} + +int setup_irq(unsigned int irq, struct irqaction *new) +{ + int shared = 0; + struct irqaction *old, **p; + unsigned long flags; + struct irqdesc *desc; + + /* + * Some drivers like serial.c use request_irq() heavily, + * so we have to be careful not to interfere with a + * running system. + */ + if (new->flags & SA_SAMPLE_RANDOM) { + /* + * This function might sleep, we want to call it first, + * outside of the atomic block. + * Yes, this might clear the entropy pool if the wrong + * driver is attempted to be loaded, without actually + * installing a new handler, but is this really a problem, + * only the sysadmin is able to do this. + */ + rand_initialize_irq(irq); + } + + /* + * The following block of code has to be executed atomically + */ + desc = irq_desc + irq; + spin_lock_irqsave(&irq_controller_lock, flags); + p = &desc->action; + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&irq_controller_lock, flags); + return -EBUSY; + } + + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + shared = 1; + } + + *p = new; + + if (!shared) { + desc->probing = 0; + desc->running = 0; + desc->pending = 0; + desc->disable_depth = 1; + if (!desc->noautoenable) { + desc->disable_depth = 0; + desc->chip->unmask(irq); + } + } + + spin_unlock_irqrestore(&irq_controller_lock, flags); + return 0; +} + +/** + * request_irq - allocate an interrupt line + * @irq: Interrupt line to allocate + * @handler: Function to be called when the IRQ occurs + * @irqflags: Interrupt type flags + * @devname: An ascii name for the claiming device + * @dev_id: A cookie passed back to the handler function + * + * This call allocates interrupt resources and enables the + * interrupt line and IRQ handling. From the point this + * call is made your handler function may be invoked. Since + * your handler function must clear any interrupt the board + * raises, you must take care both to initialise your hardware + * and to set up the interrupt handler in the right order. + * + * Dev_id must be globally unique. Normally the address of the + * device data structure is used as the cookie. Since the handler + * receives this value it makes sense to use it. + * + * If your interrupt is shared you must pass a non NULL dev_id + * as this is required when freeing the interrupt. + * + * Flags: + * + * SA_SHIRQ Interrupt is shared + * + * SA_INTERRUPT Disable local interrupts while processing + * + * SA_SAMPLE_RANDOM The interrupt can be used for entropy + * + */ +int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long irq_flags, const char * devname, void *dev_id) +{ + unsigned long retval; + struct irqaction *action; + + if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler || + (irq_flags & SA_SHIRQ && !dev_id)) + return -EINVAL; + + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + if (!action) + return -ENOMEM; + + action->handler = handler; + action->flags = irq_flags; + cpus_clear(action->mask); + action->name = devname; + action->next = NULL; + action->dev_id = dev_id; + + retval = setup_irq(irq, action); + + if (retval) + kfree(action); + return retval; +} + +EXPORT_SYMBOL(request_irq); + +/** + * free_irq - free an interrupt + * @irq: Interrupt line to free + * @dev_id: Device identity to free + * + * Remove an interrupt handler. The handler is removed and if the + * interrupt line is no longer in use by any driver it is disabled. + * On a shared IRQ the caller must ensure the interrupt is disabled + * on the card it drives before calling this function. + * + * This function must not be called from interrupt context. + */ +void free_irq(unsigned int irq, void *dev_id) +{ + struct irqaction * action, **p; + unsigned long flags; + + if (irq >= NR_IRQS || !irq_desc[irq].valid) { + printk(KERN_ERR "Trying to free IRQ%d\n",irq); + dump_stack(); + return; + } + + spin_lock_irqsave(&irq_controller_lock, flags); + for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) { + if (action->dev_id != dev_id) + continue; + + /* Found it - now free it */ + *p = action->next; + break; + } + spin_unlock_irqrestore(&irq_controller_lock, flags); + + if (!action) { + printk(KERN_ERR "Trying to free free IRQ%d\n",irq); + dump_stack(); + } else { + synchronize_irq(irq); + kfree(action); + } +} + +EXPORT_SYMBOL(free_irq); + +static DECLARE_MUTEX(probe_sem); + +/* Start the interrupt probing. Unlike other architectures, + * we don't return a mask of interrupts from probe_irq_on, + * but return the number of interrupts enabled for the probe. + * The interrupts which have been enabled for probing is + * instead recorded in the irq_desc structure. + */ +unsigned long probe_irq_on(void) +{ + unsigned int i, irqs = 0; + unsigned long delay; + + down(&probe_sem); + + /* + * first snaffle up any unassigned but + * probe-able interrupts + */ + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < NR_IRQS; i++) { + if (!irq_desc[i].probe_ok || irq_desc[i].action) + continue; + + irq_desc[i].probing = 1; + irq_desc[i].triggered = 0; + if (irq_desc[i].chip->type) + irq_desc[i].chip->type(i, IRQT_PROBE); + irq_desc[i].chip->unmask(i); + irqs += 1; + } + spin_unlock_irq(&irq_controller_lock); + + /* + * wait for spurious interrupts to mask themselves out again + */ + for (delay = jiffies + HZ/10; time_before(jiffies, delay); ) + /* min 100ms delay */; + + /* + * now filter out any obviously spurious interrupts + */ + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < NR_IRQS; i++) { + if (irq_desc[i].probing && irq_desc[i].triggered) { + irq_desc[i].probing = 0; + irqs -= 1; + } + } + spin_unlock_irq(&irq_controller_lock); + + return irqs; +} + +EXPORT_SYMBOL(probe_irq_on); + +unsigned int probe_irq_mask(unsigned long irqs) +{ + unsigned int mask = 0, i; + + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < 16 && i < NR_IRQS; i++) + if (irq_desc[i].probing && irq_desc[i].triggered) + mask |= 1 << i; + spin_unlock_irq(&irq_controller_lock); + + up(&probe_sem); + + return mask; +} +EXPORT_SYMBOL(probe_irq_mask); + +/* + * Possible return values: + * >= 0 - interrupt number + * -1 - no interrupt/many interrupts + */ +int probe_irq_off(unsigned long irqs) +{ + unsigned int i; + int irq_found = NO_IRQ; + + /* + * look at the interrupts, and find exactly one + * that we were probing has been triggered + */ + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < NR_IRQS; i++) { + if (irq_desc[i].probing && + irq_desc[i].triggered) { + if (irq_found != NO_IRQ) { + irq_found = NO_IRQ; + goto out; + } + irq_found = i; + } + } + + if (irq_found == -1) + irq_found = NO_IRQ; +out: + spin_unlock_irq(&irq_controller_lock); + + up(&probe_sem); + + return irq_found; +} + +EXPORT_SYMBOL(probe_irq_off); + +#ifdef CONFIG_SMP +static void route_irq(struct irqdesc *desc, unsigned int irq, unsigned int cpu) +{ + pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->cpu, cpu); + + spin_lock_irq(&irq_controller_lock); + desc->cpu = cpu; + desc->chip->set_cpu(desc, irq, cpu); + spin_unlock_irq(&irq_controller_lock); +} + +#ifdef CONFIG_PROC_FS +static int +irq_affinity_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + struct irqdesc *desc = irq_desc + ((int)data); + int len = cpumask_scnprintf(page, count, desc->affinity); + + if (count - len < 2) + return -EINVAL; + page[len++] = '\n'; + page[len] = '\0'; + + return len; +} + +static int +irq_affinity_write_proc(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + unsigned int irq = (unsigned int)data; + struct irqdesc *desc = irq_desc + irq; + cpumask_t affinity, tmp; + int ret = -EIO; + + if (!desc->chip->set_cpu) + goto out; + + ret = cpumask_parse(buffer, count, affinity); + if (ret) + goto out; + + cpus_and(tmp, affinity, cpu_online_map); + if (cpus_empty(tmp)) { + ret = -EINVAL; + goto out; + } + + desc->affinity = affinity; + route_irq(desc, irq, first_cpu(tmp)); + ret = count; + + out: + return ret; +} +#endif +#endif + +void __init init_irq_proc(void) +{ +#if defined(CONFIG_SMP) && defined(CONFIG_PROC_FS) + struct proc_dir_entry *dir; + int irq; + + dir = proc_mkdir("irq", 0); + if (!dir) + return; + + for (irq = 0; irq < NR_IRQS; irq++) { + struct proc_dir_entry *entry; + struct irqdesc *desc; + char name[16]; + + desc = irq_desc + irq; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name) - 1, "%u", irq); + + desc->procdir = proc_mkdir(name, dir); + if (!desc->procdir) + continue; + + entry = create_proc_entry("smp_affinity", 0600, desc->procdir); + if (entry) { + entry->nlink = 1; + entry->data = (void *)irq; + entry->read_proc = irq_affinity_read_proc; + entry->write_proc = irq_affinity_write_proc; + } + } +#endif +} + +void __init init_IRQ(void) +{ + struct irqdesc *desc; + extern void init_dma(void); + int irq; + +#ifdef CONFIG_SMP + bad_irq_desc.affinity = CPU_MASK_ALL; + bad_irq_desc.cpu = smp_processor_id(); +#endif + + for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) { + *desc = bad_irq_desc; + INIT_LIST_HEAD(&desc->pend); + } + + init_arch_irq(); + init_dma(); +} + +static int __init noirqdebug_setup(char *str) +{ + noirqdebug = 1; + return 1; +} + +__setup("noirqdebug", noirqdebug_setup); diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c new file mode 100644 index 0000000..685c3e5 --- /dev/null +++ b/arch/arm/kernel/isa.c @@ -0,0 +1,53 @@ +/* + * linux/arch/arm/kernel/isa.c + * + * Copyright (C) 1999 Phil Blundell + * + * ISA shared memory and I/O port support + */ + +/* + * 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. + */ + +/* + * Nothing about this is actually ARM specific. One day we could move + * it into kernel/resource.c or some place like that. + */ + +#include <linux/stddef.h> +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/sysctl.h> +#include <linux/init.h> + +static unsigned int isa_membase, isa_portbase, isa_portshift; + +static ctl_table ctl_isa_vars[4] = { + {BUS_ISA_MEM_BASE, "membase", &isa_membase, + sizeof(isa_membase), 0444, NULL, &proc_dointvec}, + {BUS_ISA_PORT_BASE, "portbase", &isa_portbase, + sizeof(isa_portbase), 0444, NULL, &proc_dointvec}, + {BUS_ISA_PORT_SHIFT, "portshift", &isa_portshift, + sizeof(isa_portshift), 0444, NULL, &proc_dointvec}, + {0} +}; + +static struct ctl_table_header *isa_sysctl_header; + +static ctl_table ctl_isa[2] = {{CTL_BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars}, + {0}}; +static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa}, + {0}}; + +void __init +register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift) +{ + isa_membase = membase; + isa_portbase = portbase; + isa_portshift = portshift; + isa_sysctl_header = register_sysctl_table(ctl_bus, 0); +} diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S new file mode 100644 index 0000000..8f74e24 --- /dev/null +++ b/arch/arm/kernel/iwmmxt.S @@ -0,0 +1,320 @@ +/* + * linux/arch/arm/kernel/iwmmxt.S + * + * XScale iWMMXt (Concan) context switching and handling + * + * Initial code: + * Copyright (c) 2003, Intel Corporation + * + * Full lazy switching support, optimizations and more, by Nicolas Pitre +* Copyright (c) 2003-2004, MontaVista Software, Inc. + * + * 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/linkage.h> +#include <asm/ptrace.h> +#include <asm/thread_info.h> +#include <asm/constants.h> + +#define MMX_WR0 (0x00) +#define MMX_WR1 (0x08) +#define MMX_WR2 (0x10) +#define MMX_WR3 (0x18) +#define MMX_WR4 (0x20) +#define MMX_WR5 (0x28) +#define MMX_WR6 (0x30) +#define MMX_WR7 (0x38) +#define MMX_WR8 (0x40) +#define MMX_WR9 (0x48) +#define MMX_WR10 (0x50) +#define MMX_WR11 (0x58) +#define MMX_WR12 (0x60) +#define MMX_WR13 (0x68) +#define MMX_WR14 (0x70) +#define MMX_WR15 (0x78) +#define MMX_WCSSF (0x80) +#define MMX_WCASF (0x84) +#define MMX_WCGR0 (0x88) +#define MMX_WCGR1 (0x8C) +#define MMX_WCGR2 (0x90) +#define MMX_WCGR3 (0x94) + +#define MMX_SIZE (0x98) + + .text + +/* + * Lazy switching of Concan coprocessor context + * + * r10 = struct thread_info pointer + * r9 = ret_from_exception + * lr = undefined instr exit + * + * called from prefetch exception handler with interrupts disabled + */ + +ENTRY(iwmmxt_task_enable) + + mrc p15, 0, r2, c15, c1, 0 + tst r2, #0x3 @ CP0 and CP1 accessible? + movne pc, lr @ if so no business here + orr r2, r2, #0x3 @ enable access to CP0 and CP1 + mcr p15, 0, r2, c15, c1, 0 + + ldr r3, =concan_owner + add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area + ldr r2, [sp, #60] @ current task pc value + ldr r1, [r3] @ get current Concan owner + str r0, [r3] @ this task now owns Concan regs + sub r2, r2, #4 @ adjust pc back + str r2, [sp, #60] + + mrc p15, 0, r2, c2, c0, 0 + mov r2, r2 @ cpwait + + teq r1, #0 @ test for last ownership + mov lr, r9 @ normal exit from exception + beq concan_load @ no owner, skip save + +concan_save: + + tmrc r2, wCon + + @ CUP? wCx + tst r2, #0x1 + beq 1f + +concan_dump: + + wstrw wCSSF, [r1, #MMX_WCSSF] + wstrw wCASF, [r1, #MMX_WCASF] + wstrw wCGR0, [r1, #MMX_WCGR0] + wstrw wCGR1, [r1, #MMX_WCGR1] + wstrw wCGR2, [r1, #MMX_WCGR2] + wstrw wCGR3, [r1, #MMX_WCGR3] + +1: @ MUP? wRn + tst r2, #0x2 + beq 2f + + wstrd wR0, [r1, #MMX_WR0] + wstrd wR1, [r1, #MMX_WR1] + wstrd wR2, [r1, #MMX_WR2] + wstrd wR3, [r1, #MMX_WR3] + wstrd wR4, [r1, #MMX_WR4] + wstrd wR5, [r1, #MMX_WR5] + wstrd wR6, [r1, #MMX_WR6] + wstrd wR7, [r1, #MMX_WR7] + wstrd wR8, [r1, #MMX_WR8] + wstrd wR9, [r1, #MMX_WR9] + wstrd wR10, [r1, #MMX_WR10] + wstrd wR11, [r1, #MMX_WR11] + wstrd wR12, [r1, #MMX_WR12] + wstrd wR13, [r1, #MMX_WR13] + wstrd wR14, [r1, #MMX_WR14] + wstrd wR15, [r1, #MMX_WR15] + +2: teq r0, #0 @ anything to load? + moveq pc, lr + +concan_load: + + @ Load wRn + wldrd wR0, [r0, #MMX_WR0] + wldrd wR1, [r0, #MMX_WR1] + wldrd wR2, [r0, #MMX_WR2] + wldrd wR3, [r0, #MMX_WR3] + wldrd wR4, [r0, #MMX_WR4] + wldrd wR5, [r0, #MMX_WR5] + wldrd wR6, [r0, #MMX_WR6] + wldrd wR7, [r0, #MMX_WR7] + wldrd wR8, [r0, #MMX_WR8] + wldrd wR9, [r0, #MMX_WR9] + wldrd wR10, [r0, #MMX_WR10] + wldrd wR11, [r0, #MMX_WR11] + wldrd wR12, [r0, #MMX_WR12] + wldrd wR13, [r0, #MMX_WR13] + wldrd wR14, [r0, #MMX_WR14] + wldrd wR15, [r0, #MMX_WR15] + + @ Load wCx + wldrw wCSSF, [r0, #MMX_WCSSF] + wldrw wCASF, [r0, #MMX_WCASF] + wldrw wCGR0, [r0, #MMX_WCGR0] + wldrw wCGR1, [r0, #MMX_WCGR1] + wldrw wCGR2, [r0, #MMX_WCGR2] + wldrw wCGR3, [r0, #MMX_WCGR3] + + @ clear CUP/MUP (only if r1 != 0) + teq r1, #0 + mov r2, #0 + moveq pc, lr + tmcr wCon, r2 + mov pc, lr + +/* + * Back up Concan regs to save area and disable access to them + * (mainly for gdb or sleep mode usage) + * + * r0 = struct thread_info pointer of target task or NULL for any + */ + +ENTRY(iwmmxt_task_disable) + + stmfd sp!, {r4, lr} + + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r3, =concan_owner + add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area + ldr r1, [r3] @ get current Concan owner + teq r1, #0 @ any current owner? + beq 1f @ no: quit + teq r0, #0 @ any owner? + teqne r1, r2 @ or specified one? + bne 1f @ no: quit + + mrc p15, 0, r4, c15, c1, 0 + orr r4, r4, #0x3 @ enable access to CP0 and CP1 + mcr p15, 0, r4, c15, c1, 0 + mov r0, #0 @ nothing to load + str r0, [r3] @ no more current owner + mrc p15, 0, r2, c2, c0, 0 + mov r2, r2 @ cpwait + bl concan_save + + bic r4, r4, #0x3 @ disable access to CP0 and CP1 + mcr p15, 0, r4, c15, c1, 0 + mrc p15, 0, r2, c2, c0, 0 + mov r2, r2 @ cpwait + +1: msr cpsr_c, ip @ restore interrupt mode + ldmfd sp!, {r4, pc} + +/* + * Copy Concan state to given memory address + * + * r0 = struct thread_info pointer of target task + * r1 = memory address where to store Concan state + * + * this is called mainly in the creation of signal stack frames + */ + +ENTRY(iwmmxt_task_copy) + + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r3, =concan_owner + add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area + ldr r3, [r3] @ get current Concan owner + teq r2, r3 @ does this task own it... + beq 1f + + @ current Concan values are in the task save area + msr cpsr_c, ip @ restore interrupt mode + mov r0, r1 + mov r1, r2 + mov r2, #MMX_SIZE + b memcpy + +1: @ this task owns Concan regs -- grab a copy from there + mov r0, #0 @ nothing to load + mov r2, #3 @ save all regs + mov r3, lr @ preserve return address + bl concan_dump + msr cpsr_c, ip @ restore interrupt mode + mov pc, r3 + +/* + * Restore Concan state from given memory address + * + * r0 = struct thread_info pointer of target task + * r1 = memory address where to get Concan state from + * + * this is used to restore Concan state when unwinding a signal stack frame + */ + +ENTRY(iwmmxt_task_restore) + + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r3, =concan_owner + add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area + ldr r3, [r3] @ get current Concan owner + bic r2, r2, #0x7 @ 64-bit alignment + teq r2, r3 @ does this task own it... + beq 1f + + @ this task doesn't own Concan regs -- use its save area + msr cpsr_c, ip @ restore interrupt mode + mov r0, r2 + mov r2, #MMX_SIZE + b memcpy + +1: @ this task owns Concan regs -- load them directly + mov r0, r1 + mov r1, #0 @ don't clear CUP/MUP + mov r3, lr @ preserve return address + bl concan_load + msr cpsr_c, ip @ restore interrupt mode + mov pc, r3 + +/* + * Concan handling on task switch + * + * r0 = previous task_struct pointer (must be preserved) + * r1 = previous thread_info pointer + * r2 = next thread_info.cpu_domain pointer (must be preserved) + * + * Called only from __switch_to with task preemption disabled. + * No need to care about preserving r4 and above. + */ +ENTRY(iwmmxt_task_switch) + + mrc p15, 0, r4, c15, c1, 0 + tst r4, #0x3 @ CP0 and CP1 accessible? + bne 1f @ yes: block them for next task + + ldr r5, =concan_owner + add r6, r2, #(TI_IWMMXT_STATE - TI_CPU_DOMAIN) @ get next task Concan save area + ldr r5, [r5] @ get current Concan owner + teq r5, r6 @ next task owns it? + movne pc, lr @ no: leave Concan disabled + +1: eor r4, r4, #3 @ flip Concan access + mcr p15, 0, r4, c15, c1, 0 + + mrc p15, 0, r4, c2, c0, 0 + sub pc, lr, r4, lsr #32 @ cpwait and return + +/* + * Remove Concan ownership of given task + * + * r0 = struct thread_info pointer + */ +ENTRY(iwmmxt_task_release) + + mrs r2, cpsr + orr ip, r2, #PSR_I_BIT @ disable interrupts + msr cpsr_c, ip + ldr r3, =concan_owner + add r0, r0, #TI_IWMMXT_STATE @ get task Concan save area + ldr r1, [r3] @ get current Concan owner + eors r0, r0, r1 @ if equal... + streq r0, [r3] @ then clear ownership + msr cpsr_c, r2 @ restore interrupts + mov pc, lr + + .data +concan_owner: + .word 0 + diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c new file mode 100644 index 0000000..1a85cfd --- /dev/null +++ b/arch/arm/kernel/module.c @@ -0,0 +1,152 @@ +/* + * linux/arch/arm/kernel/module.c + * + * Copyright (C) 2002 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. + * + * Module allocation method suggested by Andi Kleen. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/elf.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <linux/string.h> + +#include <asm/pgtable.h> + +#ifdef CONFIG_XIP_KERNEL +/* + * The XIP kernel text is mapped in the module area for modules and + * some other stuff to work without any indirect relocations. + * MODULE_START is redefined here and not in asm/memory.h to avoid + * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off. + */ +extern void _etext; +#undef MODULE_START +#define MODULE_START (((unsigned long)&_etext + ~PGDIR_MASK) & PGDIR_MASK) +#endif + +void *module_alloc(unsigned long size) +{ + struct vm_struct *area; + + size = PAGE_ALIGN(size); + if (!size) + return NULL; + + area = __get_vm_area(size, VM_ALLOC, MODULE_START, MODULE_END); + if (!area) + return NULL; + + return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); +} + +void module_free(struct module *module, void *region) +{ + vfree(region); +} + +int module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) +{ + return 0; +} + +int +apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, + unsigned int relindex, struct module *module) +{ + Elf32_Shdr *symsec = sechdrs + symindex; + Elf32_Shdr *relsec = sechdrs + relindex; + Elf32_Shdr *dstsec = sechdrs + relsec->sh_info; + Elf32_Rel *rel = (void *)relsec->sh_addr; + unsigned int i; + + for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { + unsigned long loc; + Elf32_Sym *sym; + s32 offset; + + offset = ELF32_R_SYM(rel->r_info); + if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { + printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n", + module->name, relindex, i); + return -ENOEXEC; + } + + sym = ((Elf32_Sym *)symsec->sh_addr) + offset; + + if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { + printk(KERN_ERR "%s: out of bounds relocation, " + "section %d reloc %d offset %d size %d\n", + module->name, relindex, i, rel->r_offset, + dstsec->sh_size); + return -ENOEXEC; + } + + loc = dstsec->sh_addr + rel->r_offset; + + switch (ELF32_R_TYPE(rel->r_info)) { + case R_ARM_ABS32: + *(u32 *)loc += sym->st_value; + break; + + case R_ARM_PC24: + offset = (*(u32 *)loc & 0x00ffffff) << 2; + if (offset & 0x02000000) + offset -= 0x04000000; + + offset += sym->st_value - loc; + if (offset & 3 || + offset <= (s32)0xfc000000 || + offset >= (s32)0x04000000) { + printk(KERN_ERR + "%s: relocation out of range, section " + "%d reloc %d sym '%s'\n", module->name, + relindex, i, strtab + sym->st_name); + return -ENOEXEC; + } + + offset >>= 2; + + *(u32 *)loc &= 0xff000000; + *(u32 *)loc |= offset & 0x00ffffff; + break; + + default: + printk(KERN_ERR "%s: unknown relocation: %u\n", + module->name, ELF32_R_TYPE(rel->r_info)); + return -ENOEXEC; + } + } + return 0; +} + +int +apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, + unsigned int symindex, unsigned int relsec, struct module *module) +{ + printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", + module->name); + return -ENOEXEC; +} + +int +module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, + struct module *module) +{ + return 0; +} + +void +module_arch_cleanup(struct module *mod) +{ +} diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c new file mode 100644 index 0000000..dbd8ca8 --- /dev/null +++ b/arch/arm/kernel/process.c @@ -0,0 +1,460 @@ +/* + * linux/arch/arm/kernel/process.c + * + * Copyright (C) 1996-2000 Russell King - Converted to ARM. + * Original Copyright (C) 1995 Linus Torvalds + * + * 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 <stdarg.h> + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/stddef.h> +#include <linux/unistd.h> +#include <linux/ptrace.h> +#include <linux/slab.h> +#include <linux/user.h> +#include <linux/a.out.h> +#include <linux/delay.h> +#include <linux/reboot.h> +#include <linux/interrupt.h> +#include <linux/kallsyms.h> +#include <linux/init.h> + +#include <asm/system.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/processor.h> +#include <asm/uaccess.h> + +extern const char *processor_modes[]; +extern void setup_mm_for_reboot(char mode); + +static volatile int hlt_counter; + +#include <asm/arch/system.h> + +void disable_hlt(void) +{ + hlt_counter++; +} + +EXPORT_SYMBOL(disable_hlt); + +void enable_hlt(void) +{ + hlt_counter--; +} + +EXPORT_SYMBOL(enable_hlt); + +static int __init nohlt_setup(char *__unused) +{ + hlt_counter = 1; + return 1; +} + +static int __init hlt_setup(char *__unused) +{ + hlt_counter = 0; + return 1; +} + +__setup("nohlt", nohlt_setup); +__setup("hlt", hlt_setup); + +/* + * The following aren't currently used. + */ +void (*pm_idle)(void); +EXPORT_SYMBOL(pm_idle); + +void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); + +/* + * This is our default idle handler. We need to disable + * interrupts here to ensure we don't miss a wakeup call. + */ +void default_idle(void) +{ + local_irq_disable(); + if (!need_resched() && !hlt_counter) + arch_idle(); + local_irq_enable(); +} + +/* + * 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. + */ +void cpu_idle(void) +{ + local_fiq_enable(); + + /* endless idle loop with no priority at all */ + while (1) { + void (*idle)(void) = pm_idle; + if (!idle) + idle = default_idle; + preempt_disable(); + leds_event(led_idle_start); + while (!need_resched()) + idle(); + leds_event(led_idle_end); + preempt_enable(); + schedule(); + } +} + +static char reboot_mode = 'h'; + +int __init reboot_setup(char *str) +{ + reboot_mode = str[0]; + return 1; +} + +__setup("reboot=", reboot_setup); + +void machine_halt(void) +{ +} + +EXPORT_SYMBOL(machine_halt); + +void machine_power_off(void) +{ + if (pm_power_off) + pm_power_off(); +} + +EXPORT_SYMBOL(machine_power_off); + +void machine_restart(char * __unused) +{ + /* + * Clean and disable cache, and turn off interrupts + */ + cpu_proc_fin(); + + /* + * Tell the mm system that we are going to reboot - + * we may need it to insert some 1:1 mappings so that + * soft boot works. + */ + setup_mm_for_reboot(reboot_mode); + + /* + * Now call the architecture specific reboot code. + */ + arch_reset(reboot_mode); + + /* + * Whoops - the architecture was unable to reboot. + * Tell the user! + */ + mdelay(1000); + printk("Reboot failed -- System halted\n"); + while (1); +} + +EXPORT_SYMBOL(machine_restart); + +void show_regs(struct pt_regs * regs) +{ + unsigned long flags; + + flags = condition_codes(regs); + + print_symbol("PC is at %s\n", instruction_pointer(regs)); + print_symbol("LR is at %s\n", regs->ARM_lr); + printk("pc : [<%08lx>] lr : [<%08lx>] %s\n" + "sp : %08lx ip : %08lx fp : %08lx\n", + instruction_pointer(regs), + regs->ARM_lr, print_tainted(), regs->ARM_sp, + regs->ARM_ip, regs->ARM_fp); + printk("r10: %08lx r9 : %08lx r8 : %08lx\n", + regs->ARM_r10, regs->ARM_r9, + regs->ARM_r8); + printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", + regs->ARM_r7, regs->ARM_r6, + regs->ARM_r5, regs->ARM_r4); + printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", + regs->ARM_r3, regs->ARM_r2, + regs->ARM_r1, regs->ARM_r0); + printk("Flags: %c%c%c%c", + flags & PSR_N_BIT ? 'N' : 'n', + flags & PSR_Z_BIT ? 'Z' : 'z', + flags & PSR_C_BIT ? 'C' : 'c', + flags & PSR_V_BIT ? 'V' : 'v'); + printk(" IRQs o%s FIQs o%s Mode %s%s Segment %s\n", + interrupts_enabled(regs) ? "n" : "ff", + fast_interrupts_enabled(regs) ? "n" : "ff", + processor_modes[processor_mode(regs)], + thumb_mode(regs) ? " (T)" : "", + get_fs() == get_ds() ? "kernel" : "user"); + { + unsigned int ctrl, transbase, dac; + __asm__ ( + " mrc p15, 0, %0, c1, c0\n" + " mrc p15, 0, %1, c2, c0\n" + " mrc p15, 0, %2, c3, c0\n" + : "=r" (ctrl), "=r" (transbase), "=r" (dac)); + printk("Control: %04X Table: %08X DAC: %08X\n", + ctrl, transbase, dac); + } +} + +void show_fpregs(struct user_fp *regs) +{ + int i; + + for (i = 0; i < 8; i++) { + unsigned long *p; + char type; + + p = (unsigned long *)(regs->fpregs + i); + + switch (regs->ftype[i]) { + case 1: type = 'f'; break; + case 2: type = 'd'; break; + case 3: type = 'e'; break; + default: type = '?'; break; + } + if (regs->init_flag) + type = '?'; + + printk(" f%d(%c): %08lx %08lx %08lx%c", + i, type, p[0], p[1], p[2], i & 1 ? '\n' : ' '); + } + + + printk("FPSR: %08lx FPCR: %08lx\n", + (unsigned long)regs->fpsr, + (unsigned long)regs->fpcr); +} + +/* + * Task structure and kernel stack allocation. + */ +static unsigned long *thread_info_head; +static unsigned int nr_thread_info; + +#define EXTRA_TASK_STRUCT 4 +#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) +#define ll_free_task_struct(p) free_pages((unsigned long)(p),1) + +struct thread_info *alloc_thread_info(struct task_struct *task) +{ + struct thread_info *thread = NULL; + + if (EXTRA_TASK_STRUCT) { + unsigned long *p = thread_info_head; + + if (p) { + thread_info_head = (unsigned long *)p[0]; + nr_thread_info -= 1; + } + thread = (struct thread_info *)p; + } + + if (!thread) + thread = ll_alloc_task_struct(); + +#ifdef CONFIG_MAGIC_SYSRQ + /* + * The stack must be cleared if you want SYSRQ-T to + * give sensible stack usage information + */ + if (thread) { + char *p = (char *)thread; + memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE); + } +#endif + return thread; +} + +void free_thread_info(struct thread_info *thread) +{ + if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) { + unsigned long *p = (unsigned long *)thread; + p[0] = (unsigned long)thread_info_head; + thread_info_head = p; + nr_thread_info += 1; + } else + ll_free_task_struct(thread); +} + +/* + * Free current thread data structures etc.. + */ +void exit_thread(void) +{ +} + +static void default_fp_init(union fp_state *fp) +{ + memset(fp, 0, sizeof(union fp_state)); +} + +void (*fp_init)(union fp_state *) = default_fp_init; +EXPORT_SYMBOL(fp_init); + +void flush_thread(void) +{ + struct thread_info *thread = current_thread_info(); + struct task_struct *tsk = current; + + memset(thread->used_cp, 0, sizeof(thread->used_cp)); + memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); +#if defined(CONFIG_IWMMXT) + iwmmxt_task_release(thread); +#endif + fp_init(&thread->fpstate); +#if defined(CONFIG_VFP) + vfp_flush_thread(&thread->vfpstate); +#endif +} + +void release_thread(struct task_struct *dead_task) +{ +#if defined(CONFIG_VFP) + vfp_release_thread(&dead_task->thread_info->vfpstate); +#endif +#if defined(CONFIG_IWMMXT) + iwmmxt_task_release(dead_task->thread_info); +#endif +} + +asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); + +int +copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, + unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs) +{ + struct thread_info *thread = p->thread_info; + struct pt_regs *childregs; + + childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1; + *childregs = *regs; + childregs->ARM_r0 = 0; + childregs->ARM_sp = stack_start; + + memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); + thread->cpu_context.sp = (unsigned long)childregs; + thread->cpu_context.pc = (unsigned long)ret_from_fork; + + if (clone_flags & CLONE_SETTLS) + thread->tp_value = regs->ARM_r3; + + return 0; +} + +/* + * fill in the fpe structure for a core dump... + */ +int dump_fpu (struct pt_regs *regs, struct user_fp *fp) +{ + struct thread_info *thread = current_thread_info(); + int used_math = thread->used_cp[1] | thread->used_cp[2]; + + if (used_math) + memcpy(fp, &thread->fpstate.soft, sizeof (*fp)); + + return used_math != 0; +} +EXPORT_SYMBOL(dump_fpu); + +/* + * fill in the user structure for a core dump.. + */ +void dump_thread(struct pt_regs * regs, struct user * dump) +{ + struct task_struct *tsk = current; + + dump->magic = CMAGIC; + dump->start_code = tsk->mm->start_code; + dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1); + + dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT; + dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; + dump->u_ssize = 0; + + dump->u_debugreg[0] = tsk->thread.debug.bp[0].address; + dump->u_debugreg[1] = tsk->thread.debug.bp[1].address; + dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn.arm; + dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn.arm; + dump->u_debugreg[4] = tsk->thread.debug.nsaved; + + if (dump->start_stack < 0x04000000) + dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; + + dump->regs = *regs; + dump->u_fpvalid = dump_fpu (regs, &dump->u_fp); +} +EXPORT_SYMBOL(dump_thread); + +/* + * Shuffle the argument into the correct register before calling the + * thread function. r1 is the thread argument, r2 is the pointer to + * the thread function, and r3 points to the exit function. + */ +extern void kernel_thread_helper(void); +asm( ".section .text\n" +" .align\n" +" .type kernel_thread_helper, #function\n" +"kernel_thread_helper:\n" +" mov r0, r1\n" +" mov lr, r3\n" +" mov pc, r2\n" +" .size kernel_thread_helper, . - kernel_thread_helper\n" +" .previous"); + +/* + * Create a kernel thread. + */ +pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + struct pt_regs regs; + + memset(®s, 0, sizeof(regs)); + + regs.ARM_r1 = (unsigned long)arg; + regs.ARM_r2 = (unsigned long)fn; + regs.ARM_r3 = (unsigned long)do_exit; + regs.ARM_pc = (unsigned long)kernel_thread_helper; + regs.ARM_cpsr = SVC_MODE; + + return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); +} +EXPORT_SYMBOL(kernel_thread); + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long fp, lr; + unsigned long stack_page; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + stack_page = 4096 + (unsigned long)p->thread_info; + fp = thread_saved_fp(p); + do { + if (fp < stack_page || fp > 4092+stack_page) + return 0; + lr = pc_pointer (((unsigned long *)fp)[-1]); + if (!in_sched_functions(lr)) + return lr; + fp = *(unsigned long *) (fp - 12); + } while (count ++ < 16); + return 0; +} +EXPORT_SYMBOL(get_wchan); diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c new file mode 100644 index 0000000..efd7a34 --- /dev/null +++ b/arch/arm/kernel/ptrace.c @@ -0,0 +1,861 @@ +/* + * linux/arch/arm/kernel/ptrace.c + * + * By Ross Biro 1/23/92 + * edited by Linus Torvalds + * ARM modifications Copyright (C) 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/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/ptrace.h> +#include <linux/user.h> +#include <linux/security.h> +#include <linux/init.h> + +#include <asm/uaccess.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/traps.h> + +#include "ptrace.h" + +#define REG_PC 15 +#define REG_PSR 16 +/* + * does not yet catch signals sent when the child dies. + * in exit.c or in signal.c. + */ + +#if 0 +/* + * Breakpoint SWI instruction: SWI &9F0001 + */ +#define BREAKINST_ARM 0xef9f0001 +#define BREAKINST_THUMB 0xdf00 /* fill this in later */ +#else +/* + * New breakpoints - use an undefined instruction. The ARM architecture + * reference manual guarantees that the following instruction space + * will produce an undefined instruction exception on all CPUs: + * + * ARM: xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx + * Thumb: 1101 1110 xxxx xxxx + */ +#define BREAKINST_ARM 0xe7f001f0 +#define BREAKINST_THUMB 0xde01 +#endif + +/* + * Get the address of the live pt_regs for the specified task. + * These are saved onto the top kernel stack when the process + * is not running. + * + * Note: if a user thread is execve'd from kernel space, the + * kernel stack will not be empty on entry to the kernel, so + * ptracing these tasks will fail. + */ +static inline struct pt_regs * +get_user_regs(struct task_struct *task) +{ + return (struct pt_regs *) + ((unsigned long)task->thread_info + THREAD_SIZE - + 8 - sizeof(struct pt_regs)); +} + +/* + * this routine will get a word off of the processes privileged stack. + * the offset is how far from the base addr as stored in the THREAD. + * this routine assumes that all the privileged stacks are in our + * data space. + */ +static inline long get_user_reg(struct task_struct *task, int offset) +{ + return get_user_regs(task)->uregs[offset]; +} + +/* + * this routine will put a word on the processes privileged stack. + * the offset is how far from the base addr as stored in the THREAD. + * this routine assumes that all the privileged stacks are in our + * data space. + */ +static inline int +put_user_reg(struct task_struct *task, int offset, long data) +{ + struct pt_regs newregs, *regs = get_user_regs(task); + int ret = -EINVAL; + + newregs = *regs; + newregs.uregs[offset] = data; + + if (valid_user_regs(&newregs)) { + regs->uregs[offset] = data; + ret = 0; + } + + return ret; +} + +static inline int +read_u32(struct task_struct *task, unsigned long addr, u32 *res) +{ + int ret; + + ret = access_process_vm(task, addr, res, sizeof(*res), 0); + + return ret == sizeof(*res) ? 0 : -EIO; +} + +static inline int +read_instr(struct task_struct *task, unsigned long addr, u32 *res) +{ + int ret; + + if (addr & 1) { + u16 val; + ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0); + ret = ret == sizeof(val) ? 0 : -EIO; + *res = val; + } else { + u32 val; + ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0); + ret = ret == sizeof(val) ? 0 : -EIO; + *res = val; + } + return ret; +} + +/* + * Get value of register `rn' (in the instruction) + */ +static unsigned long +ptrace_getrn(struct task_struct *child, unsigned long insn) +{ + unsigned int reg = (insn >> 16) & 15; + unsigned long val; + + val = get_user_reg(child, reg); + if (reg == 15) + val = pc_pointer(val + 8); + + return val; +} + +/* + * Get value of operand 2 (in an ALU instruction) + */ +static unsigned long +ptrace_getaluop2(struct task_struct *child, unsigned long insn) +{ + unsigned long val; + int shift; + int type; + + if (insn & 1 << 25) { + val = insn & 255; + shift = (insn >> 8) & 15; + type = 3; + } else { + val = get_user_reg (child, insn & 15); + + if (insn & (1 << 4)) + shift = (int)get_user_reg (child, (insn >> 8) & 15); + else + shift = (insn >> 7) & 31; + + type = (insn >> 5) & 3; + } + + switch (type) { + case 0: val <<= shift; break; + case 1: val >>= shift; break; + case 2: + val = (((signed long)val) >> shift); + break; + case 3: + val = (val >> shift) | (val << (32 - shift)); + break; + } + return val; +} + +/* + * Get value of operand 2 (in a LDR instruction) + */ +static unsigned long +ptrace_getldrop2(struct task_struct *child, unsigned long insn) +{ + unsigned long val; + int shift; + int type; + + val = get_user_reg(child, insn & 15); + shift = (insn >> 7) & 31; + type = (insn >> 5) & 3; + + switch (type) { + case 0: val <<= shift; break; + case 1: val >>= shift; break; + case 2: + val = (((signed long)val) >> shift); + break; + case 3: + val = (val >> shift) | (val << (32 - shift)); + break; + } + return val; +} + +#define OP_MASK 0x01e00000 +#define OP_AND 0x00000000 +#define OP_EOR 0x00200000 +#define OP_SUB 0x00400000 +#define OP_RSB 0x00600000 +#define OP_ADD 0x00800000 +#define OP_ADC 0x00a00000 +#define OP_SBC 0x00c00000 +#define OP_RSC 0x00e00000 +#define OP_ORR 0x01800000 +#define OP_MOV 0x01a00000 +#define OP_BIC 0x01c00000 +#define OP_MVN 0x01e00000 + +static unsigned long +get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn) +{ + u32 alt = 0; + + switch (insn & 0x0e000000) { + case 0x00000000: + case 0x02000000: { + /* + * data processing + */ + long aluop1, aluop2, ccbit; + + if ((insn & 0xf000) != 0xf000) + break; + + aluop1 = ptrace_getrn(child, insn); + aluop2 = ptrace_getaluop2(child, insn); + ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0; + + switch (insn & OP_MASK) { + case OP_AND: alt = aluop1 & aluop2; break; + case OP_EOR: alt = aluop1 ^ aluop2; break; + case OP_SUB: alt = aluop1 - aluop2; break; + case OP_RSB: alt = aluop2 - aluop1; break; + case OP_ADD: alt = aluop1 + aluop2; break; + case OP_ADC: alt = aluop1 + aluop2 + ccbit; break; + case OP_SBC: alt = aluop1 - aluop2 + ccbit; break; + case OP_RSC: alt = aluop2 - aluop1 + ccbit; break; + case OP_ORR: alt = aluop1 | aluop2; break; + case OP_MOV: alt = aluop2; break; + case OP_BIC: alt = aluop1 & ~aluop2; break; + case OP_MVN: alt = ~aluop2; break; + } + break; + } + + case 0x04000000: + case 0x06000000: + /* + * ldr + */ + if ((insn & 0x0010f000) == 0x0010f000) { + unsigned long base; + + base = ptrace_getrn(child, insn); + if (insn & 1 << 24) { + long aluop2; + + if (insn & 0x02000000) + aluop2 = ptrace_getldrop2(child, insn); + else + aluop2 = insn & 0xfff; + + if (insn & 1 << 23) + base += aluop2; + else + base -= aluop2; + } + if (read_u32(child, base, &alt) == 0) + alt = pc_pointer(alt); + } + break; + + case 0x08000000: + /* + * ldm + */ + if ((insn & 0x00108000) == 0x00108000) { + unsigned long base; + unsigned int nr_regs; + + if (insn & (1 << 23)) { + nr_regs = hweight16(insn & 65535) << 2; + + if (!(insn & (1 << 24))) + nr_regs -= 4; + } else { + if (insn & (1 << 24)) + nr_regs = -4; + else + nr_regs = 0; + } + + base = ptrace_getrn(child, insn); + + if (read_u32(child, base + nr_regs, &alt) == 0) + alt = pc_pointer(alt); + break; + } + break; + + case 0x0a000000: { + /* + * bl or b + */ + signed long displ; + /* It's a branch/branch link: instead of trying to + * figure out whether the branch will be taken or not, + * we'll put a breakpoint at both locations. This is + * simpler, more reliable, and probably not a whole lot + * slower than the alternative approach of emulating the + * branch. + */ + displ = (insn & 0x00ffffff) << 8; + displ = (displ >> 6) + 8; + if (displ != 0 && displ != 4) + alt = pc + displ; + } + break; + } + + return alt; +} + +static int +swap_insn(struct task_struct *task, unsigned long addr, + void *old_insn, void *new_insn, int size) +{ + int ret; + + ret = access_process_vm(task, addr, old_insn, size, 0); + if (ret == size) + ret = access_process_vm(task, addr, new_insn, size, 1); + return ret; +} + +static void +add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr) +{ + int nr = dbg->nsaved; + + if (nr < 2) { + u32 new_insn = BREAKINST_ARM; + int res; + + res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4); + + if (res == 4) { + dbg->bp[nr].address = addr; + dbg->nsaved += 1; + } + } else + printk(KERN_ERR "ptrace: too many breakpoints\n"); +} + +/* + * Clear one breakpoint in the user program. We copy what the hardware + * does and use bit 0 of the address to indicate whether this is a Thumb + * breakpoint or an ARM breakpoint. + */ +static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp) +{ + unsigned long addr = bp->address; + union debug_insn old_insn; + int ret; + + if (addr & 1) { + ret = swap_insn(task, addr & ~1, &old_insn.thumb, + &bp->insn.thumb, 2); + + if (ret != 2 || old_insn.thumb != BREAKINST_THUMB) + printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at " + "0x%08lx (0x%04x)\n", task->comm, task->pid, + addr, old_insn.thumb); + } else { + ret = swap_insn(task, addr & ~3, &old_insn.arm, + &bp->insn.arm, 4); + + if (ret != 4 || old_insn.arm != BREAKINST_ARM) + printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at " + "0x%08lx (0x%08x)\n", task->comm, task->pid, + addr, old_insn.arm); + } +} + +void ptrace_set_bpt(struct task_struct *child) +{ + struct pt_regs *regs; + unsigned long pc; + u32 insn; + int res; + + regs = get_user_regs(child); + pc = instruction_pointer(regs); + + if (thumb_mode(regs)) { + printk(KERN_WARNING "ptrace: can't handle thumb mode\n"); + return; + } + + res = read_instr(child, pc, &insn); + if (!res) { + struct debug_info *dbg = &child->thread.debug; + unsigned long alt; + + dbg->nsaved = 0; + + alt = get_branch_address(child, pc, insn); + if (alt) + add_breakpoint(child, dbg, alt); + + /* + * Note that we ignore the result of setting the above + * breakpoint since it may fail. When it does, this is + * not so much an error, but a forewarning that we may + * be receiving a prefetch abort shortly. + * + * If we don't set this breakpoint here, then we can + * lose control of the thread during single stepping. + */ + if (!alt || predicate(insn) != PREDICATE_ALWAYS) + add_breakpoint(child, dbg, pc + 4); + } +} + +/* + * Ensure no single-step breakpoint is pending. Returns non-zero + * value if child was being single-stepped. + */ +void ptrace_cancel_bpt(struct task_struct *child) +{ + int i, nsaved = child->thread.debug.nsaved; + + child->thread.debug.nsaved = 0; + + if (nsaved > 2) { + printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); + nsaved = 2; + } + + for (i = 0; i < nsaved; i++) + clear_breakpoint(child, &child->thread.debug.bp[i]); +} + +/* + * Called by kernel/ptrace.c when detaching.. + * + * Make sure the single step bit is not set. + */ +void ptrace_disable(struct task_struct *child) +{ + child->ptrace &= ~PT_SINGLESTEP; + ptrace_cancel_bpt(child); +} + +/* + * Handle hitting a breakpoint. + */ +void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) +{ + siginfo_t info; + + ptrace_cancel_bpt(tsk); + + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_BRKPT; + info.si_addr = (void __user *)instruction_pointer(regs); + + force_sig_info(SIGTRAP, &info, tsk); +} + +static int break_trap(struct pt_regs *regs, unsigned int instr) +{ + ptrace_break(current, regs); + return 0; +} + +static struct undef_hook arm_break_hook = { + .instr_mask = 0x0fffffff, + .instr_val = 0x07f001f0, + .cpsr_mask = PSR_T_BIT, + .cpsr_val = 0, + .fn = break_trap, +}; + +static struct undef_hook thumb_break_hook = { + .instr_mask = 0xffff, + .instr_val = 0xde01, + .cpsr_mask = PSR_T_BIT, + .cpsr_val = PSR_T_BIT, + .fn = break_trap, +}; + +static int __init ptrace_break_init(void) +{ + register_undef_hook(&arm_break_hook); + register_undef_hook(&thumb_break_hook); + return 0; +} + +core_initcall(ptrace_break_init); + +/* + * Read the word at offset "off" into the "struct user". We + * actually access the pt_regs stored on the kernel stack. + */ +static int ptrace_read_user(struct task_struct *tsk, unsigned long off, + unsigned long __user *ret) +{ + unsigned long tmp; + + if (off & 3 || off >= sizeof(struct user)) + return -EIO; + + tmp = 0; + if (off < sizeof(struct pt_regs)) + tmp = get_user_reg(tsk, off >> 2); + + return put_user(tmp, ret); +} + +/* + * Write the word at offset "off" into "struct user". We + * actually access the pt_regs stored on the kernel stack. + */ +static int ptrace_write_user(struct task_struct *tsk, unsigned long off, + unsigned long val) +{ + if (off & 3 || off >= sizeof(struct user)) + return -EIO; + + if (off >= sizeof(struct pt_regs)) + return 0; + + return put_user_reg(tsk, off >> 2, val); +} + +/* + * Get all user integer registers. + */ +static int ptrace_getregs(struct task_struct *tsk, void __user *uregs) +{ + struct pt_regs *regs = get_user_regs(tsk); + + return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; +} + +/* + * Set all user integer registers. + */ +static int ptrace_setregs(struct task_struct *tsk, void __user *uregs) +{ + struct pt_regs newregs; + int ret; + + ret = -EFAULT; + if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { + struct pt_regs *regs = get_user_regs(tsk); + + ret = -EINVAL; + if (valid_user_regs(&newregs)) { + *regs = newregs; + ret = 0; + } + } + + return ret; +} + +/* + * Get the child FPU state. + */ +static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp) +{ + return copy_to_user(ufp, &tsk->thread_info->fpstate, + sizeof(struct user_fp)) ? -EFAULT : 0; +} + +/* + * Set the child FPU state. + */ +static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp) +{ + struct thread_info *thread = tsk->thread_info; + thread->used_cp[1] = thread->used_cp[2] = 1; + return copy_from_user(&thread->fpstate, ufp, + sizeof(struct user_fp)) ? -EFAULT : 0; +} + +#ifdef CONFIG_IWMMXT + +/* + * Get the child iWMMXt state. + */ +static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp) +{ + struct thread_info *thread = tsk->thread_info; + void *ptr = &thread->fpstate; + + if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT)) + return -ENODATA; + iwmmxt_task_disable(thread); /* force it to ram */ + /* The iWMMXt state is stored doubleword-aligned. */ + if (((long) ptr) & 4) + ptr += 4; + return copy_to_user(ufp, ptr, 0x98) ? -EFAULT : 0; +} + +/* + * Set the child iWMMXt state. + */ +static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) +{ + struct thread_info *thread = tsk->thread_info; + void *ptr = &thread->fpstate; + + if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT)) + return -EACCES; + iwmmxt_task_release(thread); /* force a reload */ + /* The iWMMXt state is stored doubleword-aligned. */ + if (((long) ptr) & 4) + ptr += 4; + return copy_from_user(ptr, ufp, 0x98) ? -EFAULT : 0; +} + +#endif + +static int do_ptrace(int request, struct task_struct *child, long addr, long data) +{ + unsigned long tmp; + int ret; + + switch (request) { + /* + * read word at location "addr" in the child process. + */ + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: + ret = access_process_vm(child, addr, &tmp, + sizeof(unsigned long), 0); + if (ret == sizeof(unsigned long)) + ret = put_user(tmp, (unsigned long __user *) data); + else + ret = -EIO; + break; + + case PTRACE_PEEKUSR: + ret = ptrace_read_user(child, addr, (unsigned long __user *)data); + break; + + /* + * write the word at location addr. + */ + case PTRACE_POKETEXT: + case PTRACE_POKEDATA: + ret = access_process_vm(child, addr, &data, + sizeof(unsigned long), 1); + if (ret == sizeof(unsigned long)) + ret = 0; + else + ret = -EIO; + break; + + case PTRACE_POKEUSR: + ret = ptrace_write_user(child, addr, data); + break; + + /* + * continue/restart and stop at next (return from) syscall + */ + case PTRACE_SYSCALL: + case PTRACE_CONT: + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + if (request == PTRACE_SYSCALL) + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + else + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + child->exit_code = data; + /* make sure single-step breakpoint is gone. */ + child->ptrace &= ~PT_SINGLESTEP; + ptrace_cancel_bpt(child); + wake_up_process(child); + ret = 0; + break; + + /* + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to + * exit. + */ + case PTRACE_KILL: + /* make sure single-step breakpoint is gone. */ + child->ptrace &= ~PT_SINGLESTEP; + ptrace_cancel_bpt(child); + if (child->exit_state != EXIT_ZOMBIE) { + child->exit_code = SIGKILL; + wake_up_process(child); + } + ret = 0; + break; + + /* + * execute single instruction. + */ + case PTRACE_SINGLESTEP: + ret = -EIO; + if ((unsigned long) data > _NSIG) + break; + child->ptrace |= PT_SINGLESTEP; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + child->exit_code = data; + /* give it a chance to run. */ + wake_up_process(child); + ret = 0; + break; + + case PTRACE_DETACH: + ret = ptrace_detach(child, data); + break; + + case PTRACE_GETREGS: + ret = ptrace_getregs(child, (void __user *)data); + break; + + case PTRACE_SETREGS: + ret = ptrace_setregs(child, (void __user *)data); + break; + + case PTRACE_GETFPREGS: + ret = ptrace_getfpregs(child, (void __user *)data); + break; + + case PTRACE_SETFPREGS: + ret = ptrace_setfpregs(child, (void __user *)data); + break; + +#ifdef CONFIG_IWMMXT + case PTRACE_GETWMMXREGS: + ret = ptrace_getwmmxregs(child, (void __user *)data); + break; + + case PTRACE_SETWMMXREGS: + ret = ptrace_setwmmxregs(child, (void __user *)data); + break; +#endif + + case PTRACE_GET_THREAD_AREA: + ret = put_user(child->thread_info->tp_value, + (unsigned long __user *) data); + break; + + default: + ret = ptrace_request(child, request, addr, data); + break; + } + + return ret; +} + +asmlinkage int sys_ptrace(long request, long pid, long addr, long data) +{ + struct task_struct *child; + int ret; + + lock_kernel(); + ret = -EPERM; + if (request == PTRACE_TRACEME) { + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) + goto out; + ret = security_ptrace(current->parent, current); + if (ret) + goto out; + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; + ret = 0; + goto out; + } + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) + goto out; + + ret = -EPERM; + if (pid == 1) /* you may not mess with init */ + goto out_tsk; + + if (request == PTRACE_ATTACH) { + ret = ptrace_attach(child); + goto out_tsk; + } + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret == 0) + ret = do_ptrace(request, child, addr, data); + +out_tsk: + put_task_struct(child); +out: + unlock_kernel(); + return ret; +} + +asmlinkage void syscall_trace(int why, struct pt_regs *regs) +{ + unsigned long ip; + + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + return; + if (!(current->ptrace & PT_PTRACED)) + return; + + /* + * Save IP. IP is used to denote syscall entry/exit: + * IP = 0 -> entry, = 1 -> exit + */ + ip = regs->ARM_ip; + regs->ARM_ip = why; + + /* the 0x80 provides a way for the tracing parent to distinguish + between a syscall stop and SIGTRAP delivery */ + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0)); + /* + * this isn't the same as continuing with a signal, but it will do + * for normal use. strace only continues with a signal if the + * stopping signal is not SIGTRAP. -brl + */ + if (current->exit_code) { + send_sig(current->exit_code, current, 1); + current->exit_code = 0; + } + regs->ARM_ip = ip; +} diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h new file mode 100644 index 0000000..f7cad13 --- /dev/null +++ b/arch/arm/kernel/ptrace.h @@ -0,0 +1,12 @@ +/* + * linux/arch/arm/kernel/ptrace.h + * + * Copyright (C) 2000-2003 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. + */ +extern void ptrace_cancel_bpt(struct task_struct *); +extern void ptrace_set_bpt(struct task_struct *); +extern void ptrace_break(struct task_struct *, struct pt_regs *); diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c new file mode 100644 index 0000000..ac423e3 --- /dev/null +++ b/arch/arm/kernel/semaphore.c @@ -0,0 +1,220 @@ +/* + * ARM semaphore implementation, taken from + * + * i386 semaphore implementation. + * + * (C) Copyright 1999 Linus Torvalds + * + * Modified for ARM by 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/module.h> +#include <linux/sched.h> +#include <linux/errno.h> +#include <linux/init.h> + +#include <asm/semaphore.h> + +/* + * Semaphores are implemented using a two-way counter: + * The "count" variable is decremented for each process + * that tries to acquire the semaphore, while the "sleeping" + * variable is a count of such acquires. + * + * Notably, the inline "up()" and "down()" functions can + * efficiently test if they need to do any extra work (up + * needs to do something only if count was negative before + * the increment operation. + * + * "sleeping" and the contention routine ordering is + * protected by the semaphore spinlock. + * + * Note that these functions are only called when there is + * contention on the lock, and as such all this is the + * "non-critical" part of the whole semaphore business. The + * critical part is the inline stuff in <asm/semaphore.h> + * where we want to avoid any extra jumps and calls. + */ + +/* + * Logic: + * - only on a boundary condition do we need to care. When we go + * from a negative count to a non-negative, we wake people up. + * - when we go from a non-negative count to a negative do we + * (a) synchronize with the "sleeper" count and (b) make sure + * that we're on the wakeup list before we synchronize so that + * we cannot lose wakeup events. + */ + +void __up(struct semaphore *sem) +{ + wake_up(&sem->wait); +} + +static DEFINE_SPINLOCK(semaphore_lock); + +void __sched __down(struct semaphore * sem) +{ + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + tsk->state = TASK_UNINTERRUPTIBLE; + add_wait_queue_exclusive(&sem->wait, &wait); + + spin_lock_irq(&semaphore_lock); + sem->sleepers++; + for (;;) { + int sleepers = sem->sleepers; + + /* + * Add "everybody else" into it. They aren't + * playing, because we own the spinlock. + */ + if (!atomic_add_negative(sleepers - 1, &sem->count)) { + sem->sleepers = 0; + break; + } + sem->sleepers = 1; /* us - see -1 above */ + spin_unlock_irq(&semaphore_lock); + + schedule(); + tsk->state = TASK_UNINTERRUPTIBLE; + spin_lock_irq(&semaphore_lock); + } + spin_unlock_irq(&semaphore_lock); + remove_wait_queue(&sem->wait, &wait); + tsk->state = TASK_RUNNING; + wake_up(&sem->wait); +} + +int __sched __down_interruptible(struct semaphore * sem) +{ + int retval = 0; + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + tsk->state = TASK_INTERRUPTIBLE; + add_wait_queue_exclusive(&sem->wait, &wait); + + spin_lock_irq(&semaphore_lock); + sem->sleepers ++; + for (;;) { + int sleepers = sem->sleepers; + + /* + * With signals pending, this turns into + * the trylock failure case - we won't be + * sleeping, and we* can't get the lock as + * it has contention. Just correct the count + * and exit. + */ + if (signal_pending(current)) { + retval = -EINTR; + sem->sleepers = 0; + atomic_add(sleepers, &sem->count); + break; + } + + /* + * Add "everybody else" into it. They aren't + * playing, because we own the spinlock. The + * "-1" is because we're still hoping to get + * the lock. + */ + if (!atomic_add_negative(sleepers - 1, &sem->count)) { + sem->sleepers = 0; + break; + } + sem->sleepers = 1; /* us - see -1 above */ + spin_unlock_irq(&semaphore_lock); + + schedule(); + tsk->state = TASK_INTERRUPTIBLE; + spin_lock_irq(&semaphore_lock); + } + spin_unlock_irq(&semaphore_lock); + tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); + wake_up(&sem->wait); + return retval; +} + +/* + * Trylock failed - make sure we correct for + * having decremented the count. + * + * We could have done the trylock with a + * single "cmpxchg" without failure cases, + * but then it wouldn't work on a 386. + */ +int __down_trylock(struct semaphore * sem) +{ + int sleepers; + unsigned long flags; + + spin_lock_irqsave(&semaphore_lock, flags); + sleepers = sem->sleepers + 1; + sem->sleepers = 0; + + /* + * Add "everybody else" and us into it. They aren't + * playing, because we own the spinlock. + */ + if (!atomic_add_negative(sleepers, &sem->count)) + wake_up(&sem->wait); + + spin_unlock_irqrestore(&semaphore_lock, flags); + return 1; +} + +/* + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines + * need to convert that sequence back into the C sequence when + * there is contention on the semaphore. + * + * ip contains the semaphore pointer on entry. Save the C-clobbered + * registers (r0 to r3 and lr), but not ip, as we use it as a return + * value in some cases.. + */ +asm(" .section .sched.text,\"ax\" \n\ + .align 5 \n\ + .globl __down_failed \n\ +__down_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down \n\ + ldmfd sp!, {r0 - r3, pc} \n\ + \n\ + .align 5 \n\ + .globl __down_interruptible_failed \n\ +__down_interruptible_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down_interruptible \n\ + mov ip, r0 \n\ + ldmfd sp!, {r0 - r3, pc} \n\ + \n\ + .align 5 \n\ + .globl __down_trylock_failed \n\ +__down_trylock_failed: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __down_trylock \n\ + mov ip, r0 \n\ + ldmfd sp!, {r0 - r3, pc} \n\ + \n\ + .align 5 \n\ + .globl __up_wakeup \n\ +__up_wakeup: \n\ + stmfd sp!, {r0 - r3, lr} \n\ + mov r0, ip \n\ + bl __up \n\ + ldmfd sp!, {r0 - r3, pc} \n\ + "); + +EXPORT_SYMBOL(__down_failed); +EXPORT_SYMBOL(__down_interruptible_failed); +EXPORT_SYMBOL(__down_trylock_failed); +EXPORT_SYMBOL(__up_wakeup); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c new file mode 100644 index 0000000..c2a7da3 --- /dev/null +++ b/arch/arm/kernel/setup.c @@ -0,0 +1,875 @@ +/* + * linux/arch/arm/kernel/setup.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/module.h> +#include <linux/kernel.h> +#include <linux/stddef.h> +#include <linux/ioport.h> +#include <linux/delay.h> +#include <linux/utsname.h> +#include <linux/initrd.h> +#include <linux/console.h> +#include <linux/bootmem.h> +#include <linux/seq_file.h> +#include <linux/tty.h> +#include <linux/init.h> +#include <linux/root_dev.h> +#include <linux/cpu.h> +#include <linux/interrupt.h> + +#include <asm/cpu.h> +#include <asm/elf.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/procinfo.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> + +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> + +#ifndef MEM_SIZE +#define MEM_SIZE (16*1024*1024) +#endif + +#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) +char fpe_type[8]; + +static int __init fpe_setup(char *line) +{ + memcpy(fpe_type, line, 8); + return 1; +} + +__setup("fpe=", fpe_setup); +#endif + +extern unsigned int mem_fclk_21285; +extern void paging_init(struct meminfo *, struct machine_desc *desc); +extern void convert_to_tag_list(struct tag *tags); +extern void squash_mem_tags(struct tag *tag); +extern void reboot_setup(char *str); +extern int root_mountflags; +extern void _stext, _text, _etext, __data_start, _edata, _end; + +unsigned int processor_id; +unsigned int __machine_arch_type; +EXPORT_SYMBOL(__machine_arch_type); + +unsigned int system_rev; +EXPORT_SYMBOL(system_rev); + +unsigned int system_serial_low; +EXPORT_SYMBOL(system_serial_low); + +unsigned int system_serial_high; +EXPORT_SYMBOL(system_serial_high); + +unsigned int elf_hwcap; +EXPORT_SYMBOL(elf_hwcap); + + +#ifdef MULTI_CPU +struct processor processor; +#endif +#ifdef MULTI_TLB +struct cpu_tlb_fns cpu_tlb; +#endif +#ifdef MULTI_USER +struct cpu_user_fns cpu_user; +#endif +#ifdef MULTI_CACHE +struct cpu_cache_fns cpu_cache; +#endif + +char elf_platform[ELF_PLATFORM_SIZE]; +EXPORT_SYMBOL(elf_platform); + +unsigned long phys_initrd_start __initdata = 0; +unsigned long phys_initrd_size __initdata = 0; + +static struct meminfo meminfo __initdata = { 0, }; +static const char *cpu_name; +static const char *machine_name; +static char command_line[COMMAND_LINE_SIZE]; + +static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; +static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; +#define ENDIANNESS ((char)endian_test.l) + +DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); + +/* + * Standard memory resources + */ +static struct resource mem_res[] = { + { "Video RAM", 0, 0, IORESOURCE_MEM }, + { "Kernel text", 0, 0, IORESOURCE_MEM }, + { "Kernel data", 0, 0, IORESOURCE_MEM } +}; + +#define video_ram mem_res[0] +#define kernel_code mem_res[1] +#define kernel_data mem_res[2] + +static struct resource io_res[] = { + { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }, + { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY }, + { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY } +}; + +#define lp0 io_res[0] +#define lp1 io_res[1] +#define lp2 io_res[2] + +static const char *cache_types[16] = { + "write-through", + "write-back", + "write-back", + "undefined 3", + "undefined 4", + "undefined 5", + "write-back", + "write-back", + "undefined 8", + "undefined 9", + "undefined 10", + "undefined 11", + "undefined 12", + "undefined 13", + "write-back", + "undefined 15", +}; + +static const char *cache_clean[16] = { + "not required", + "read-block", + "cp15 c7 ops", + "undefined 3", + "undefined 4", + "undefined 5", + "cp15 c7 ops", + "cp15 c7 ops", + "undefined 8", + "undefined 9", + "undefined 10", + "undefined 11", + "undefined 12", + "undefined 13", + "cp15 c7 ops", + "undefined 15", +}; + +static const char *cache_lockdown[16] = { + "not supported", + "not supported", + "not supported", + "undefined 3", + "undefined 4", + "undefined 5", + "format A", + "format B", + "undefined 8", + "undefined 9", + "undefined 10", + "undefined 11", + "undefined 12", + "undefined 13", + "format C", + "undefined 15", +}; + +static const char *proc_arch[] = { + "undefined/unknown", + "3", + "4", + "4T", + "5", + "5T", + "5TE", + "5TEJ", + "6TEJ", + "?(10)", + "?(11)", + "?(12)", + "?(13)", + "?(14)", + "?(15)", + "?(16)", + "?(17)", +}; + +#define CACHE_TYPE(x) (((x) >> 25) & 15) +#define CACHE_S(x) ((x) & (1 << 24)) +#define CACHE_DSIZE(x) (((x) >> 12) & 4095) /* only if S=1 */ +#define CACHE_ISIZE(x) ((x) & 4095) + +#define CACHE_SIZE(y) (((y) >> 6) & 7) +#define CACHE_ASSOC(y) (((y) >> 3) & 7) +#define CACHE_M(y) ((y) & (1 << 2)) +#define CACHE_LINE(y) ((y) & 3) + +static inline void dump_cache(const char *prefix, int cpu, unsigned int cache) +{ + unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0); + + printk("CPU%u: %s: %d bytes, associativity %d, %d byte lines, %d sets\n", + cpu, prefix, + mult << (8 + CACHE_SIZE(cache)), + (mult << CACHE_ASSOC(cache)) >> 1, + 8 << CACHE_LINE(cache), + 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) - + CACHE_LINE(cache))); +} + +static void __init dump_cpu_info(int cpu) +{ + unsigned int info = read_cpuid(CPUID_CACHETYPE); + + if (info != processor_id) { + printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT", + cache_types[CACHE_TYPE(info)]); + if (CACHE_S(info)) { + dump_cache("I cache", cpu, CACHE_ISIZE(info)); + dump_cache("D cache", cpu, CACHE_DSIZE(info)); + } else { + dump_cache("cache", cpu, CACHE_ISIZE(info)); + } + } +} + +int cpu_architecture(void) +{ + int cpu_arch; + + if ((processor_id & 0x0000f000) == 0) { + cpu_arch = CPU_ARCH_UNKNOWN; + } else if ((processor_id & 0x0000f000) == 0x00007000) { + cpu_arch = (processor_id & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3; + } else { + cpu_arch = (processor_id >> 16) & 7; + if (cpu_arch) + cpu_arch += CPU_ARCH_ARMv3; + } + + return cpu_arch; +} + +/* + * These functions re-use the assembly code in head.S, which + * already provide the required functionality. + */ +extern struct proc_info_list *lookup_processor_type(void); +extern struct machine_desc *lookup_machine_type(unsigned int); + +static void __init setup_processor(void) +{ + struct proc_info_list *list; + + /* + * locate processor in the list of supported processor + * types. The linker builds this table for us from the + * entries in arch/arm/mm/proc-*.S + */ + list = lookup_processor_type(); + if (!list) { + printk("CPU configuration botched (ID %08x), unable " + "to continue.\n", processor_id); + while (1); + } + + cpu_name = list->cpu_name; + +#ifdef MULTI_CPU + processor = *list->proc; +#endif +#ifdef MULTI_TLB + cpu_tlb = *list->tlb; +#endif +#ifdef MULTI_USER + cpu_user = *list->user; +#endif +#ifdef MULTI_CACHE + cpu_cache = *list->cache; +#endif + + printk("CPU: %s [%08x] revision %d (ARMv%s)\n", + cpu_name, processor_id, (int)processor_id & 15, + proc_arch[cpu_architecture()]); + + dump_cpu_info(smp_processor_id()); + + sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); + sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); + elf_hwcap = list->elf_hwcap; + + cpu_proc_init(); +} + +static struct machine_desc * __init setup_machine(unsigned int nr) +{ + struct machine_desc *list; + + /* + * locate machine in the list of supported machines. + */ + list = lookup_machine_type(nr); + if (!list) { + printk("Machine configuration botched (nr %d), unable " + "to continue.\n", nr); + while (1); + } + + printk("Machine: %s\n", list->name); + + return list; +} + +static void __init early_initrd(char **p) +{ + unsigned long start, size; + + start = memparse(*p, p); + if (**p == ',') { + size = memparse((*p) + 1, p); + + phys_initrd_start = start; + phys_initrd_size = size; + } +} +__early_param("initrd=", early_initrd); + +/* + * Pick out the memory size. We look for mem=size@start, + * where start and size are "size[KkMm]" + */ +static void __init early_mem(char **p) +{ + static int usermem __initdata = 0; + unsigned long size, start; + + /* + * If the user specifies memory size, we + * blow away any automatically generated + * size. + */ + if (usermem == 0) { + usermem = 1; + meminfo.nr_banks = 0; + } + + start = PHYS_OFFSET; + size = memparse(*p, p); + if (**p == '@') + start = memparse(*p + 1, p); + + meminfo.bank[meminfo.nr_banks].start = start; + meminfo.bank[meminfo.nr_banks].size = size; + meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start); + meminfo.nr_banks += 1; +} +__early_param("mem=", early_mem); + +/* + * Initial parsing of the command line. + */ +static void __init parse_cmdline(char **cmdline_p, char *from) +{ + char c = ' ', *to = command_line; + int len = 0; + + for (;;) { + if (c == ' ') { + extern struct early_params __early_begin, __early_end; + struct early_params *p; + + for (p = &__early_begin; p < &__early_end; p++) { + int len = strlen(p->arg); + + if (memcmp(from, p->arg, len) == 0) { + if (to != command_line) + to -= 1; + from += len; + p->fn(&from); + + while (*from != ' ' && *from != '\0') + from++; + break; + } + } + } + c = *from++; + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *to++ = c; + } + *to = '\0'; + *cmdline_p = command_line; +} + +static void __init +setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) +{ +#ifdef CONFIG_BLK_DEV_RAM + extern int rd_size, rd_image_start, rd_prompt, rd_doload; + + rd_image_start = image_start; + rd_prompt = prompt; + rd_doload = doload; + + if (rd_sz) + rd_size = rd_sz; +#endif +} + +static void __init +request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) +{ + struct resource *res; + int i; + + kernel_code.start = virt_to_phys(&_text); + kernel_code.end = virt_to_phys(&_etext - 1); + kernel_data.start = virt_to_phys(&__data_start); + kernel_data.end = virt_to_phys(&_end - 1); + + for (i = 0; i < mi->nr_banks; i++) { + unsigned long virt_start, virt_end; + + if (mi->bank[i].size == 0) + continue; + + virt_start = __phys_to_virt(mi->bank[i].start); + virt_end = virt_start + mi->bank[i].size - 1; + + res = alloc_bootmem_low(sizeof(*res)); + res->name = "System RAM"; + res->start = __virt_to_phys(virt_start); + res->end = __virt_to_phys(virt_end); + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + + request_resource(&iomem_resource, res); + + if (kernel_code.start >= res->start && + kernel_code.end <= res->end) + request_resource(res, &kernel_code); + if (kernel_data.start >= res->start && + kernel_data.end <= res->end) + request_resource(res, &kernel_data); + } + + if (mdesc->video_start) { + video_ram.start = mdesc->video_start; + video_ram.end = mdesc->video_end; + request_resource(&iomem_resource, &video_ram); + } + + /* + * Some machines don't have the possibility of ever + * possessing lp0, lp1 or lp2 + */ + if (mdesc->reserve_lp0) + request_resource(&ioport_resource, &lp0); + if (mdesc->reserve_lp1) + request_resource(&ioport_resource, &lp1); + if (mdesc->reserve_lp2) + request_resource(&ioport_resource, &lp2); +} + +/* + * Tag parsing. + * + * This is the new way of passing data to the kernel at boot time. Rather + * than passing a fixed inflexible structure to the kernel, we pass a list + * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE + * tag for the list to be recognised (to distinguish the tagged list from + * a param_struct). The list is terminated with a zero-length tag (this tag + * is not parsed in any way). + */ +static int __init parse_tag_core(const struct tag *tag) +{ + if (tag->hdr.size > 2) { + if ((tag->u.core.flags & 1) == 0) + root_mountflags &= ~MS_RDONLY; + ROOT_DEV = old_decode_dev(tag->u.core.rootdev); + } + return 0; +} + +__tagtable(ATAG_CORE, parse_tag_core); + +static int __init parse_tag_mem32(const struct tag *tag) +{ + if (meminfo.nr_banks >= NR_BANKS) { + printk(KERN_WARNING + "Ignoring memory bank 0x%08x size %dKB\n", + tag->u.mem.start, tag->u.mem.size / 1024); + return -EINVAL; + } + meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start; + meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size; + meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start); + meminfo.nr_banks += 1; + + return 0; +} + +__tagtable(ATAG_MEM, parse_tag_mem32); + +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) +struct screen_info screen_info = { + .orig_video_lines = 30, + .orig_video_cols = 80, + .orig_video_mode = 0, + .orig_video_ega_bx = 0, + .orig_video_isVGA = 1, + .orig_video_points = 8 +}; + +static int __init parse_tag_videotext(const struct tag *tag) +{ + screen_info.orig_x = tag->u.videotext.x; + screen_info.orig_y = tag->u.videotext.y; + screen_info.orig_video_page = tag->u.videotext.video_page; + screen_info.orig_video_mode = tag->u.videotext.video_mode; + screen_info.orig_video_cols = tag->u.videotext.video_cols; + screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; + screen_info.orig_video_lines = tag->u.videotext.video_lines; + screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; + screen_info.orig_video_points = tag->u.videotext.video_points; + return 0; +} + +__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); +#endif + +static int __init parse_tag_ramdisk(const struct tag *tag) +{ + setup_ramdisk((tag->u.ramdisk.flags & 1) == 0, + (tag->u.ramdisk.flags & 2) == 0, + tag->u.ramdisk.start, tag->u.ramdisk.size); + return 0; +} + +__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); + +static int __init parse_tag_initrd(const struct tag *tag) +{ + printk(KERN_WARNING "ATAG_INITRD is deprecated; " + "please update your bootloader.\n"); + phys_initrd_start = __virt_to_phys(tag->u.initrd.start); + phys_initrd_size = tag->u.initrd.size; + return 0; +} + +__tagtable(ATAG_INITRD, parse_tag_initrd); + +static int __init parse_tag_initrd2(const struct tag *tag) +{ + phys_initrd_start = tag->u.initrd.start; + phys_initrd_size = tag->u.initrd.size; + return 0; +} + +__tagtable(ATAG_INITRD2, parse_tag_initrd2); + +static int __init parse_tag_serialnr(const struct tag *tag) +{ + system_serial_low = tag->u.serialnr.low; + system_serial_high = tag->u.serialnr.high; + return 0; +} + +__tagtable(ATAG_SERIAL, parse_tag_serialnr); + +static int __init parse_tag_revision(const struct tag *tag) +{ + system_rev = tag->u.revision.rev; + return 0; +} + +__tagtable(ATAG_REVISION, parse_tag_revision); + +static int __init parse_tag_cmdline(const struct tag *tag) +{ + strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); + return 0; +} + +__tagtable(ATAG_CMDLINE, parse_tag_cmdline); + +/* + * Scan the tag table for this tag, and call its parse function. + * The tag table is built by the linker from all the __tagtable + * declarations. + */ +static int __init parse_tag(const struct tag *tag) +{ + extern struct tagtable __tagtable_begin, __tagtable_end; + struct tagtable *t; + + for (t = &__tagtable_begin; t < &__tagtable_end; t++) + if (tag->hdr.tag == t->tag) { + t->parse(tag); + break; + } + + return t < &__tagtable_end; +} + +/* + * Parse all tags in the list, checking both the global and architecture + * specific tag tables. + */ +static void __init parse_tags(const struct tag *t) +{ + for (; t->hdr.size; t = tag_next(t)) + if (!parse_tag(t)) + printk(KERN_WARNING + "Ignoring unrecognised tag 0x%08x\n", + t->hdr.tag); +} + +/* + * This holds our defaults. + */ +static struct init_tags { + struct tag_header hdr1; + struct tag_core core; + struct tag_header hdr2; + struct tag_mem32 mem; + struct tag_header hdr3; +} init_tags __initdata = { + { tag_size(tag_core), ATAG_CORE }, + { 1, PAGE_SIZE, 0xff }, + { tag_size(tag_mem32), ATAG_MEM }, + { MEM_SIZE, PHYS_OFFSET }, + { 0, ATAG_NONE } +}; + +static void (*init_machine)(void) __initdata; + +static int __init customize_machine(void) +{ + /* customizes platform devices, or adds new ones */ + if (init_machine) + init_machine(); + return 0; +} +arch_initcall(customize_machine); + +void __init setup_arch(char **cmdline_p) +{ + struct tag *tags = (struct tag *)&init_tags; + struct machine_desc *mdesc; + char *from = default_command_line; + + setup_processor(); + mdesc = setup_machine(machine_arch_type); + machine_name = mdesc->name; + + if (mdesc->soft_reboot) + reboot_setup("s"); + + if (mdesc->param_offset) + tags = phys_to_virt(mdesc->param_offset); + + /* + * If we have the old style parameters, convert them to + * a tag list. + */ + if (tags->hdr.tag != ATAG_CORE) + convert_to_tag_list(tags); + if (tags->hdr.tag != ATAG_CORE) + tags = (struct tag *)&init_tags; + + if (mdesc->fixup) + mdesc->fixup(mdesc, tags, &from, &meminfo); + + if (tags->hdr.tag == ATAG_CORE) { + if (meminfo.nr_banks != 0) + squash_mem_tags(tags); + parse_tags(tags); + } + + init_mm.start_code = (unsigned long) &_text; + init_mm.end_code = (unsigned long) &_etext; + init_mm.end_data = (unsigned long) &_edata; + init_mm.brk = (unsigned long) &_end; + + memcpy(saved_command_line, from, COMMAND_LINE_SIZE); + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; + parse_cmdline(cmdline_p, from); + paging_init(&meminfo, mdesc); + request_standard_resources(&meminfo, mdesc); + + /* + * Set up various architecture-specific pointers + */ + init_arch_irq = mdesc->init_irq; + system_timer = mdesc->timer; + init_machine = mdesc->init_machine; + +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#endif +} + + +static int __init topology_init(void) +{ + int cpu; + + for_each_cpu(cpu) + register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); + + return 0; +} + +subsys_initcall(topology_init); + +static const char *hwcap_str[] = { + "swp", + "half", + "thumb", + "26bit", + "fastmult", + "fpa", + "vfp", + "edsp", + "java", + NULL +}; + +static void +c_show_cache(struct seq_file *m, const char *type, unsigned int cache) +{ + unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0); + + seq_printf(m, "%s size\t\t: %d\n" + "%s assoc\t\t: %d\n" + "%s line length\t: %d\n" + "%s sets\t\t: %d\n", + type, mult << (8 + CACHE_SIZE(cache)), + type, (mult << CACHE_ASSOC(cache)) >> 1, + type, 8 << CACHE_LINE(cache), + type, 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) - + CACHE_LINE(cache))); +} + +static int c_show(struct seq_file *m, void *v) +{ + int i; + + seq_printf(m, "Processor\t: %s rev %d (%s)\n", + cpu_name, (int)processor_id & 15, elf_platform); + +#if defined(CONFIG_SMP) + for_each_online_cpu(i) { + seq_printf(m, "Processor\t: %d\n", i); + seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n", + per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ), + (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100); + } +#else /* CONFIG_SMP */ + seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", + loops_per_jiffy / (500000/HZ), + (loops_per_jiffy / (5000/HZ)) % 100); +#endif + + /* dump out the processor features */ + seq_puts(m, "Features\t: "); + + for (i = 0; hwcap_str[i]; i++) + if (elf_hwcap & (1 << i)) + seq_printf(m, "%s ", hwcap_str[i]); + + seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24); + seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]); + + if ((processor_id & 0x0000f000) == 0x00000000) { + /* pre-ARM7 */ + seq_printf(m, "CPU part\t\t: %07x\n", processor_id >> 4); + } else { + if ((processor_id & 0x0000f000) == 0x00007000) { + /* ARM7 */ + seq_printf(m, "CPU variant\t: 0x%02x\n", + (processor_id >> 16) & 127); + } else { + /* post-ARM7 */ + seq_printf(m, "CPU variant\t: 0x%x\n", + (processor_id >> 20) & 15); + } + seq_printf(m, "CPU part\t: 0x%03x\n", + (processor_id >> 4) & 0xfff); + } + seq_printf(m, "CPU revision\t: %d\n", processor_id & 15); + + { + unsigned int cache_info = read_cpuid(CPUID_CACHETYPE); + if (cache_info != processor_id) { + seq_printf(m, "Cache type\t: %s\n" + "Cache clean\t: %s\n" + "Cache lockdown\t: %s\n" + "Cache format\t: %s\n", + cache_types[CACHE_TYPE(cache_info)], + cache_clean[CACHE_TYPE(cache_info)], + cache_lockdown[CACHE_TYPE(cache_info)], + CACHE_S(cache_info) ? "Harvard" : "Unified"); + + if (CACHE_S(cache_info)) { + c_show_cache(m, "I", CACHE_ISIZE(cache_info)); + c_show_cache(m, "D", CACHE_DSIZE(cache_info)); + } else { + c_show_cache(m, "Cache", CACHE_ISIZE(cache_info)); + } + } + } + + seq_puts(m, "\n"); + + seq_printf(m, "Hardware\t: %s\n", machine_name); + seq_printf(m, "Revision\t: %04x\n", system_rev); + seq_printf(m, "Serial\t\t: %08x%08x\n", + system_serial_high, system_serial_low); + + return 0; +} + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + return *pos < 1 ? (void *)1 : NULL; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return NULL; +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +struct seq_operations cpuinfo_op = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show +}; diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c new file mode 100644 index 0000000..931919f --- /dev/null +++ b/arch/arm/kernel/signal.c @@ -0,0 +1,748 @@ +/* + * linux/arch/arm/kernel/signal.c + * + * Copyright (C) 1995-2002 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/errno.h> +#include <linux/signal.h> +#include <linux/ptrace.h> +#include <linux/personality.h> + +#include <asm/cacheflush.h> +#include <asm/ucontext.h> +#include <asm/uaccess.h> +#include <asm/unistd.h> + +#include "ptrace.h" + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +/* + * For ARM syscalls, we encode the syscall number into the instruction. + */ +#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)) +#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)) + +/* + * For Thumb syscalls, we pass the syscall number via r7. We therefore + * need two 16-bit instructions. + */ +#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) +#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) + +static const unsigned long retcodes[4] = { + SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, + SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN +}; + +static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); + +/* + * atomically swap in the new signal mask, and wait for a signal. + */ +asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) +{ + sigset_t saveset; + + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + regs->ARM_r0 = -EINTR; + + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(&saveset, regs, 0)) + return regs->ARM_r0; + } +} + +asmlinkage int +sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + regs->ARM_r0 = -EINTR; + + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(&saveset, regs, 0)) + return regs->ARM_r0; + } +} + +asmlinkage int +sys_sigaction(int sig, const struct old_sigaction __user *act, + struct old_sigaction __user *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} + +#ifdef CONFIG_IWMMXT + +/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */ +#define IWMMXT_STORAGE_SIZE (0x98 + 8) +#define IWMMXT_MAGIC0 0x12ef842a +#define IWMMXT_MAGIC1 0x1c07ca71 + +struct iwmmxt_sigframe { + unsigned long magic0; + unsigned long magic1; + unsigned long storage[0x98/4]; +}; + +static int page_present(struct mm_struct *mm, void __user *uptr, int wr) +{ + unsigned long addr = (unsigned long)uptr; + pgd_t *pgd = pgd_offset(mm, addr); + if (pgd_present(*pgd)) { + pmd_t *pmd = pmd_offset(pgd, addr); + if (pmd_present(*pmd)) { + pte_t *pte = pte_offset_map(pmd, addr); + return (pte_present(*pte) && (!wr || pte_write(*pte))); + } + } + return 0; +} + +static int copy_locked(void __user *uptr, void *kptr, size_t size, int write, + void (*copyfn)(void *, void __user *)) +{ + unsigned char v, __user *userptr = uptr; + int err = 0; + + do { + struct mm_struct *mm; + + if (write) { + __put_user_error(0, userptr, err); + __put_user_error(0, userptr + size - 1, err); + } else { + __get_user_error(v, userptr, err); + __get_user_error(v, userptr + size - 1, err); + } + + if (err) + break; + + mm = current->mm; + spin_lock(&mm->page_table_lock); + if (page_present(mm, userptr, write) && + page_present(mm, userptr + size - 1, write)) { + copyfn(kptr, uptr); + } else + err = 1; + spin_unlock(&mm->page_table_lock); + } while (err); + + return err; +} + +static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) +{ + int err = 0; + + /* the iWMMXt context must be 64 bit aligned */ + WARN_ON((unsigned long)frame & 7); + + __put_user_error(IWMMXT_MAGIC0, &frame->magic0, err); + __put_user_error(IWMMXT_MAGIC1, &frame->magic1, err); + + /* + * iwmmxt_task_copy() doesn't check user permissions. + * Let's do a dummy write on the upper boundary to ensure + * access to user mem is OK all way up. + */ + err |= copy_locked(&frame->storage, current_thread_info(), + sizeof(frame->storage), 1, iwmmxt_task_copy); + return err; +} + +static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) +{ + unsigned long magic0, magic1; + int err = 0; + + /* the iWMMXt context is 64 bit aligned */ + WARN_ON((unsigned long)frame & 7); + + /* + * Validate iWMMXt context signature. + * Also, iwmmxt_task_restore() doesn't check user permissions. + * Let's do a dummy write on the upper boundary to ensure + * access to user mem is OK all way up. + */ + __get_user_error(magic0, &frame->magic0, err); + __get_user_error(magic1, &frame->magic1, err); + if (!err && magic0 == IWMMXT_MAGIC0 && magic1 == IWMMXT_MAGIC1) + err = copy_locked(&frame->storage, current_thread_info(), + sizeof(frame->storage), 0, iwmmxt_task_restore); + return err; +} + +#endif + +/* + * Auxiliary signal frame. This saves stuff like FP state. + * The layout of this structure is not part of the user ABI. + */ +struct aux_sigframe { +#ifdef CONFIG_IWMMXT + struct iwmmxt_sigframe iwmmxt; +#endif +#ifdef CONFIG_VFP + union vfp_state vfp; +#endif +}; + +/* + * Do a signal return; undo the signal stack. These are aligned to 64-bit. + */ +struct sigframe { + struct sigcontext sc; + unsigned long extramask[_NSIG_WORDS-1]; + unsigned long retcode; + struct aux_sigframe aux __attribute__((aligned(8))); +}; + +struct rt_sigframe { + struct siginfo __user *pinfo; + void __user *puc; + struct siginfo info; + struct ucontext uc; + unsigned long retcode; + struct aux_sigframe aux __attribute__((aligned(8))); +}; + +static int +restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, + struct aux_sigframe __user *aux) +{ + int err = 0; + + __get_user_error(regs->ARM_r0, &sc->arm_r0, err); + __get_user_error(regs->ARM_r1, &sc->arm_r1, err); + __get_user_error(regs->ARM_r2, &sc->arm_r2, err); + __get_user_error(regs->ARM_r3, &sc->arm_r3, err); + __get_user_error(regs->ARM_r4, &sc->arm_r4, err); + __get_user_error(regs->ARM_r5, &sc->arm_r5, err); + __get_user_error(regs->ARM_r6, &sc->arm_r6, err); + __get_user_error(regs->ARM_r7, &sc->arm_r7, err); + __get_user_error(regs->ARM_r8, &sc->arm_r8, err); + __get_user_error(regs->ARM_r9, &sc->arm_r9, err); + __get_user_error(regs->ARM_r10, &sc->arm_r10, err); + __get_user_error(regs->ARM_fp, &sc->arm_fp, err); + __get_user_error(regs->ARM_ip, &sc->arm_ip, err); + __get_user_error(regs->ARM_sp, &sc->arm_sp, err); + __get_user_error(regs->ARM_lr, &sc->arm_lr, err); + __get_user_error(regs->ARM_pc, &sc->arm_pc, err); + __get_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); + + err |= !valid_user_regs(regs); + +#ifdef CONFIG_IWMMXT + if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) + err |= restore_iwmmxt_context(&aux->iwmmxt); +#endif +#ifdef CONFIG_VFP +// if (err == 0) +// err |= vfp_restore_state(&aux->vfp); +#endif + + return err; +} + +asmlinkage int sys_sigreturn(struct pt_regs *regs) +{ + struct sigframe __user *frame; + sigset_t set; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + /* + * Since we stacked the signal on a 64-bit boundary, + * then 'sp' should be word aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (regs->ARM_sp & 7) + goto badframe; + + frame = (struct sigframe __user *)regs->ARM_sp; + + if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) + goto badframe; + if (__get_user(set.sig[0], &frame->sc.oldmask) + || (_NSIG_WORDS > 1 + && __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->sc, &frame->aux)) + goto badframe; + + /* Send SIGTRAP if we're single-stepping */ + if (current->ptrace & PT_SINGLESTEP) { + ptrace_cancel_bpt(current); + send_sig(SIGTRAP, current, 1); + } + + return regs->ARM_r0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) +{ + struct rt_sigframe __user *frame; + sigset_t set; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + /* + * Since we stacked the signal on a 64-bit boundary, + * then 'sp' should be word aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (regs->ARM_sp & 7) + goto badframe; + + frame = (struct rt_sigframe __user *)regs->ARM_sp; + + if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &frame->aux)) + goto badframe; + + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) + goto badframe; + + /* Send SIGTRAP if we're single-stepping */ + if (current->ptrace & PT_SINGLESTEP) { + ptrace_cancel_bpt(current); + send_sig(SIGTRAP, current, 1); + } + + return regs->ARM_r0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +static int +setup_sigcontext(struct sigcontext __user *sc, struct aux_sigframe __user *aux, + struct pt_regs *regs, unsigned long mask) +{ + int err = 0; + + __put_user_error(regs->ARM_r0, &sc->arm_r0, err); + __put_user_error(regs->ARM_r1, &sc->arm_r1, err); + __put_user_error(regs->ARM_r2, &sc->arm_r2, err); + __put_user_error(regs->ARM_r3, &sc->arm_r3, err); + __put_user_error(regs->ARM_r4, &sc->arm_r4, err); + __put_user_error(regs->ARM_r5, &sc->arm_r5, err); + __put_user_error(regs->ARM_r6, &sc->arm_r6, err); + __put_user_error(regs->ARM_r7, &sc->arm_r7, err); + __put_user_error(regs->ARM_r8, &sc->arm_r8, err); + __put_user_error(regs->ARM_r9, &sc->arm_r9, err); + __put_user_error(regs->ARM_r10, &sc->arm_r10, err); + __put_user_error(regs->ARM_fp, &sc->arm_fp, err); + __put_user_error(regs->ARM_ip, &sc->arm_ip, err); + __put_user_error(regs->ARM_sp, &sc->arm_sp, err); + __put_user_error(regs->ARM_lr, &sc->arm_lr, err); + __put_user_error(regs->ARM_pc, &sc->arm_pc, err); + __put_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); + + __put_user_error(current->thread.trap_no, &sc->trap_no, err); + __put_user_error(current->thread.error_code, &sc->error_code, err); + __put_user_error(current->thread.address, &sc->fault_address, err); + __put_user_error(mask, &sc->oldmask, err); + +#ifdef CONFIG_IWMMXT + if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) + err |= preserve_iwmmxt_context(&aux->iwmmxt); +#endif +#ifdef CONFIG_VFP +// if (err == 0) +// err |= vfp_save_state(&aux->vfp); +#endif + + return err; +} + +static inline void __user * +get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize) +{ + unsigned long sp = regs->ARM_sp; + void __user *frame; + + /* + * This is the X/Open sanctioned signal stack switching. + */ + if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) + sp = current->sas_ss_sp + current->sas_ss_size; + + /* + * ATPCS B01 mandates 8-byte alignment + */ + frame = (void __user *)((sp - framesize) & ~7); + + /* + * Check that we can actually write to the signal frame. + */ + if (!access_ok(VERIFY_WRITE, frame, framesize)) + frame = NULL; + + return frame; +} + +static int +setup_return(struct pt_regs *regs, struct k_sigaction *ka, + unsigned long __user *rc, void __user *frame, int usig) +{ + unsigned long handler = (unsigned long)ka->sa.sa_handler; + unsigned long retcode; + int thumb = 0; + unsigned long cpsr = regs->ARM_cpsr & ~PSR_f; + + /* + * Maybe we need to deliver a 32-bit signal to a 26-bit task. + */ + if (ka->sa.sa_flags & SA_THIRTYTWO) + cpsr = (cpsr & ~MODE_MASK) | USR_MODE; + +#ifdef CONFIG_ARM_THUMB + if (elf_hwcap & HWCAP_THUMB) { + /* + * The LSB of the handler determines if we're going to + * be using THUMB or ARM mode for this signal handler. + */ + thumb = handler & 1; + + if (thumb) + cpsr |= PSR_T_BIT; + else + cpsr &= ~PSR_T_BIT; + } +#endif + + if (ka->sa.sa_flags & SA_RESTORER) { + retcode = (unsigned long)ka->sa.sa_restorer; + } else { + unsigned int idx = thumb; + + if (ka->sa.sa_flags & SA_SIGINFO) + idx += 2; + + if (__put_user(retcodes[idx], rc)) + return 1; + + /* + * Ensure that the instruction cache sees + * the return code written onto the stack. + */ + flush_icache_range((unsigned long)rc, + (unsigned long)(rc + 1)); + + retcode = ((unsigned long)rc) + thumb; + } + + regs->ARM_r0 = usig; + regs->ARM_sp = (unsigned long)frame; + regs->ARM_lr = retcode; + regs->ARM_pc = handler; + regs->ARM_cpsr = cpsr; + + return 0; +} + +static int +setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs) +{ + struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); + int err = 0; + + if (!frame) + return 1; + + err |= setup_sigcontext(&frame->sc, &frame->aux, regs, set->sig[0]); + + if (_NSIG_WORDS > 1) { + err |= __copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + } + + if (err == 0) + err = setup_return(regs, ka, &frame->retcode, frame, usig); + + return err; +} + +static int +setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs *regs) +{ + struct rt_sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); + stack_t stack; + int err = 0; + + if (!frame) + return 1; + + __put_user_error(&frame->info, &frame->pinfo, err); + __put_user_error(&frame->uc, &frame->puc, err); + err |= copy_siginfo_to_user(&frame->info, info); + + __put_user_error(0, &frame->uc.uc_flags, err); + __put_user_error(NULL, &frame->uc.uc_link, err); + + memset(&stack, 0, sizeof(stack)); + stack.ss_sp = (void __user *)current->sas_ss_sp; + stack.ss_flags = sas_ss_flags(regs->ARM_sp); + stack.ss_size = current->sas_ss_size; + err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack)); + + err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->aux, + regs, set->sig[0]); + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + + if (err == 0) + err = setup_return(regs, ka, &frame->retcode, frame, usig); + + if (err == 0) { + /* + * For realtime signals we must also set the second and third + * arguments for the signal handler. + * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06 + */ + regs->ARM_r1 = (unsigned long)&frame->info; + regs->ARM_r2 = (unsigned long)&frame->uc; + } + + return err; +} + +static inline void restart_syscall(struct pt_regs *regs) +{ + regs->ARM_r0 = regs->ARM_ORIG_r0; + regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; +} + +/* + * OK, we're invoking a handler + */ +static void +handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, + struct pt_regs * regs, int syscall) +{ + struct thread_info *thread = current_thread_info(); + struct task_struct *tsk = current; + int usig = sig; + int ret; + + /* + * If we were from a system call, check for system call restarting... + */ + if (syscall) { + switch (regs->ARM_r0) { + case -ERESTART_RESTARTBLOCK: + case -ERESTARTNOHAND: + regs->ARM_r0 = -EINTR; + break; + case -ERESTARTSYS: + if (!(ka->sa.sa_flags & SA_RESTART)) { + regs->ARM_r0 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + restart_syscall(regs); + } + } + + /* + * translate the signal + */ + if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) + usig = thread->exec_domain->signal_invmap[usig]; + + /* + * Set up the stack frame + */ + if (ka->sa.sa_flags & SA_SIGINFO) + ret = setup_rt_frame(usig, ka, info, oldset, regs); + else + ret = setup_frame(usig, ka, oldset, regs); + + /* + * Check that the resulting registers are actually sane. + */ + ret |= !valid_user_regs(regs); + + /* + * Block the signal if we were unsuccessful. + */ + if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(&tsk->sighand->siglock); + sigorsets(&tsk->blocked, &tsk->blocked, + &ka->sa.sa_mask); + sigaddset(&tsk->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(&tsk->sighand->siglock); + } + + if (ret == 0) + return; + + force_sigsegv(sig, tsk); +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + * + * Note that we go through the signals twice: once to check the signals that + * the kernel can handle, and then we build all the user-level signal handling + * stack-frames in one go after that. + */ +static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) +{ + struct k_sigaction ka; + siginfo_t info; + int signr; + + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (!user_mode(regs)) + return 0; + + if (try_to_freeze(0)) + goto no_signal; + + if (current->ptrace & PT_SINGLESTEP) + ptrace_cancel_bpt(current); + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { + handle_signal(signr, &ka, &info, oldset, regs, syscall); + if (current->ptrace & PT_SINGLESTEP) + ptrace_set_bpt(current); + return 1; + } + + no_signal: + /* + * No signal to deliver to the process - restart the syscall. + */ + if (syscall) { + if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) { + if (thumb_mode(regs)) { + regs->ARM_r7 = __NR_restart_syscall; + regs->ARM_pc -= 2; + } else { + u32 __user *usp; + + regs->ARM_sp -= 12; + usp = (u32 __user *)regs->ARM_sp; + + put_user(regs->ARM_pc, &usp[0]); + /* swi __NR_restart_syscall */ + put_user(0xef000000 | __NR_restart_syscall, &usp[1]); + /* ldr pc, [sp], #12 */ + put_user(0xe49df00c, &usp[2]); + + flush_icache_range((unsigned long)usp, + (unsigned long)(usp + 3)); + + regs->ARM_pc = regs->ARM_sp + 4; + } + } + if (regs->ARM_r0 == -ERESTARTNOHAND || + regs->ARM_r0 == -ERESTARTSYS || + regs->ARM_r0 == -ERESTARTNOINTR) { + restart_syscall(regs); + } + } + if (current->ptrace & PT_SINGLESTEP) + ptrace_set_bpt(current); + return 0; +} + +asmlinkage void +do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) +{ + if (thread_flags & _TIF_SIGPENDING) + do_signal(¤t->blocked, regs, syscall); +} diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c new file mode 100644 index 0000000..ecc8c33 --- /dev/null +++ b/arch/arm/kernel/smp.c @@ -0,0 +1,396 @@ +/* + * linux/arch/arm/kernel/smp.c + * + * Copyright (C) 2002 ARM Limited, All Rights Reserved. + * + * 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/delay.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/cache.h> +#include <linux/profile.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/cpu.h> +#include <linux/smp.h> +#include <linux/seq_file.h> + +#include <asm/atomic.h> +#include <asm/cacheflush.h> +#include <asm/cpu.h> +#include <asm/processor.h> +#include <asm/tlbflush.h> +#include <asm/ptrace.h> + +/* + * bitmask of present and online CPUs. + * The present bitmask indicates that the CPU is physically present. + * The online bitmask indicates that the CPU is up and running. + */ +cpumask_t cpu_present_mask; +cpumask_t cpu_online_map; + +/* + * structures for inter-processor calls + * - A collection of single bit ipi messages. + */ +struct ipi_data { + spinlock_t lock; + unsigned long ipi_count; + unsigned long bits; +}; + +static DEFINE_PER_CPU(struct ipi_data, ipi_data) = { + .lock = SPIN_LOCK_UNLOCKED, +}; + +enum ipi_msg_type { + IPI_TIMER, + IPI_RESCHEDULE, + IPI_CALL_FUNC, + IPI_CPU_STOP, +}; + +struct smp_call_struct { + void (*func)(void *info); + void *info; + int wait; + cpumask_t pending; + cpumask_t unfinished; +}; + +static struct smp_call_struct * volatile smp_call_function_data; +static DEFINE_SPINLOCK(smp_call_function_lock); + +int __init __cpu_up(unsigned int cpu) +{ + struct task_struct *idle; + int ret; + + /* + * Spawn a new process manually. Grab a pointer to + * its task struct so we can mess with it + */ + idle = fork_idle(cpu); + if (IS_ERR(idle)) { + printk(KERN_ERR "CPU%u: fork() failed\n", cpu); + return PTR_ERR(idle); + } + + /* + * Now bring the CPU into our world. + */ + ret = boot_secondary(cpu, idle); + if (ret) { + printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu); + /* + * FIXME: We need to clean up the new idle thread. --rmk + */ + } + + return ret; +} + +/* + * Called by both boot and secondaries to move global data into + * per-processor storage. + */ +void __init smp_store_cpu_info(unsigned int cpuid) +{ + struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid); + + cpu_info->loops_per_jiffy = loops_per_jiffy; +} + +void __init smp_cpus_done(unsigned int max_cpus) +{ + int cpu; + unsigned long bogosum = 0; + + for_each_online_cpu(cpu) + bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; + + printk(KERN_INFO "SMP: Total of %d processors activated " + "(%lu.%02lu BogoMIPS).\n", + num_online_cpus(), + bogosum / (500000/HZ), + (bogosum / (5000/HZ)) % 100); +} + +void __init smp_prepare_boot_cpu(void) +{ + unsigned int cpu = smp_processor_id(); + + cpu_set(cpu, cpu_present_mask); + cpu_set(cpu, cpu_online_map); +} + +static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) +{ + unsigned long flags; + unsigned int cpu; + + local_irq_save(flags); + + for_each_cpu_mask(cpu, callmap) { + struct ipi_data *ipi = &per_cpu(ipi_data, cpu); + + spin_lock(&ipi->lock); + ipi->bits |= 1 << msg; + spin_unlock(&ipi->lock); + } + + /* + * Call the platform specific cross-CPU call function. + */ + smp_cross_call(callmap); + + local_irq_restore(flags); +} + +/* + * You must not call this function with disabled interrupts, from a + * hardware interrupt handler, nor from a bottom half handler. + */ +int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry, + int wait, cpumask_t callmap) +{ + struct smp_call_struct data; + unsigned long timeout; + int ret = 0; + + data.func = func; + data.info = info; + data.wait = wait; + + cpu_clear(smp_processor_id(), callmap); + if (cpus_empty(callmap)) + goto out; + + data.pending = callmap; + if (wait) + data.unfinished = callmap; + + /* + * try to get the mutex on smp_call_function_data + */ + spin_lock(&smp_call_function_lock); + smp_call_function_data = &data; + + send_ipi_message(callmap, IPI_CALL_FUNC); + + timeout = jiffies + HZ; + while (!cpus_empty(data.pending) && time_before(jiffies, timeout)) + barrier(); + + /* + * did we time out? + */ + if (!cpus_empty(data.pending)) { + /* + * this may be causing our panic - report it + */ + printk(KERN_CRIT + "CPU%u: smp_call_function timeout for %p(%p)\n" + " callmap %lx pending %lx, %swait\n", + smp_processor_id(), func, info, callmap, data.pending, + wait ? "" : "no "); + + /* + * TRACE + */ + timeout = jiffies + (5 * HZ); + while (!cpus_empty(data.pending) && time_before(jiffies, timeout)) + barrier(); + + if (cpus_empty(data.pending)) + printk(KERN_CRIT " RESOLVED\n"); + else + printk(KERN_CRIT " STILL STUCK\n"); + } + + /* + * whatever happened, we're done with the data, so release it + */ + smp_call_function_data = NULL; + spin_unlock(&smp_call_function_lock); + + if (!cpus_empty(data.pending)) { + ret = -ETIMEDOUT; + goto out; + } + + if (wait) + while (!cpus_empty(data.unfinished)) + barrier(); + out: + + return 0; +} + +int smp_call_function(void (*func)(void *info), void *info, int retry, + int wait) +{ + return smp_call_function_on_cpu(func, info, retry, wait, + cpu_online_map); +} + +void show_ipi_list(struct seq_file *p) +{ + unsigned int cpu; + + seq_puts(p, "IPI:"); + + for_each_online_cpu(cpu) + seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count); + + seq_putc(p, '\n'); +} + +static void ipi_timer(struct pt_regs *regs) +{ + int user = user_mode(regs); + + irq_enter(); + profile_tick(CPU_PROFILING, regs); + update_process_times(user); + irq_exit(); +} + +/* + * ipi_call_function - handle IPI from smp_call_function() + * + * Note that we copy data out of the cross-call structure and then + * let the caller know that we're here and have done with their data + */ +static void ipi_call_function(unsigned int cpu) +{ + struct smp_call_struct *data = smp_call_function_data; + void (*func)(void *info) = data->func; + void *info = data->info; + int wait = data->wait; + + cpu_clear(cpu, data->pending); + + func(info); + + if (wait) + cpu_clear(cpu, data->unfinished); +} + +static DEFINE_SPINLOCK(stop_lock); + +/* + * ipi_cpu_stop - handle IPI from smp_send_stop() + */ +static void ipi_cpu_stop(unsigned int cpu) +{ + spin_lock(&stop_lock); + printk(KERN_CRIT "CPU%u: stopping\n", cpu); + dump_stack(); + spin_unlock(&stop_lock); + + cpu_clear(cpu, cpu_online_map); + + local_fiq_disable(); + local_irq_disable(); + + while (1) + cpu_relax(); +} + +/* + * Main handler for inter-processor interrupts + * + * For ARM, the ipimask now only identifies a single + * category of IPI (Bit 1 IPIs have been replaced by a + * different mechanism): + * + * Bit 0 - Inter-processor function call + */ +void do_IPI(struct pt_regs *regs) +{ + unsigned int cpu = smp_processor_id(); + struct ipi_data *ipi = &per_cpu(ipi_data, cpu); + + ipi->ipi_count++; + + for (;;) { + unsigned long msgs; + + spin_lock(&ipi->lock); + msgs = ipi->bits; + ipi->bits = 0; + spin_unlock(&ipi->lock); + + if (!msgs) + break; + + do { + unsigned nextmsg; + + nextmsg = msgs & -msgs; + msgs &= ~nextmsg; + nextmsg = ffz(~nextmsg); + + switch (nextmsg) { + case IPI_TIMER: + ipi_timer(regs); + break; + + case IPI_RESCHEDULE: + /* + * nothing more to do - eveything is + * done on the interrupt return path + */ + break; + + case IPI_CALL_FUNC: + ipi_call_function(cpu); + break; + + case IPI_CPU_STOP: + ipi_cpu_stop(cpu); + break; + + default: + printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", + cpu, nextmsg); + break; + } + } while (msgs); + } +} + +void smp_send_reschedule(int cpu) +{ + send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE); +} + +void smp_send_timer(void) +{ + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); + send_ipi_message(mask, IPI_TIMER); +} + +void smp_send_stop(void) +{ + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); + send_ipi_message(mask, IPI_CPU_STOP); +} + +/* + * not supported here + */ +int __init setup_profiling_timer(unsigned int multiplier) +{ + return -EINVAL; +} diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c new file mode 100644 index 0000000..c41dc60 --- /dev/null +++ b/arch/arm/kernel/sys_arm.c @@ -0,0 +1,332 @@ +/* + * linux/arch/arm/kernel/sys_arm.c + * + * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c + * Copyright (C) 1995, 1996 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. + * + * This file contains various random system calls that + * have a non-standard calling sequence on the Linux/arm + * platform. + */ +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/sem.h> +#include <linux/msg.h> +#include <linux/shm.h> +#include <linux/stat.h> +#include <linux/syscalls.h> +#include <linux/mman.h> +#include <linux/fs.h> +#include <linux/file.h> +#include <linux/utsname.h> + +#include <asm/uaccess.h> +#include <asm/ipc.h> + +extern unsigned long do_mremap(unsigned long addr, unsigned long old_len, + unsigned long new_len, unsigned long flags, + unsigned long new_addr); + +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long __user *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + +/* + * This is the lowest virtual address we can permit any user space + * mapping to be mapped at. This is particularly important for + * non-high vector CPUs. + */ +#define MIN_MAP_ADDR (PAGE_SIZE) + +/* common code for old and new mmaps */ +inline long do_mmap2( + unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + int error = -EINVAL; + struct file * file = NULL; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + + if (flags & MAP_FIXED && addr < MIN_MAP_ADDR) + goto out; + + error = -EBADF; + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto out; + } + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); +out: + return error; +} + +struct mmap_arg_struct { + unsigned long addr; + unsigned long len; + unsigned long prot; + unsigned long flags; + unsigned long fd; + unsigned long offset; +}; + +asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) +{ + int error = -EFAULT; + struct mmap_arg_struct a; + + if (copy_from_user(&a, arg, sizeof(a))) + goto out; + + error = -EINVAL; + if (a.offset & ~PAGE_MASK) + goto out; + + error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); +out: + return error; +} + +asmlinkage unsigned long +sys_arm_mremap(unsigned long addr, unsigned long old_len, + unsigned long new_len, unsigned long flags, + unsigned long new_addr) +{ + unsigned long ret = -EINVAL; + + if (flags & MREMAP_FIXED && new_addr < MIN_MAP_ADDR) + goto out; + + down_write(¤t->mm->mmap_sem); + ret = do_mremap(addr, old_len, new_len, flags, new_addr); + up_write(¤t->mm->mmap_sem); + +out: + return ret; +} + +/* + * Perform the select(nd, in, out, ex, tv) and mmap() system + * calls. + */ + +struct sel_arg_struct { + unsigned long n; + fd_set __user *inp, *outp, *exp; + struct timeval __user *tvp; +}; + +asmlinkage int old_select(struct sel_arg_struct __user *arg) +{ + struct sel_arg_struct a; + + if (copy_from_user(&a, arg, sizeof(a))) + return -EFAULT; + /* sys_select() does the appropriate kernel locking */ + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); +} + +/* + * sys_ipc() is the de-multiplexer for the SysV IPC calls.. + * + * This is really horribly ugly. + */ +asmlinkage int sys_ipc(uint call, int first, int second, int third, + void __user *ptr, long fifth) +{ + int version, ret; + + version = call >> 16; /* hack for backward compatibility */ + call &= 0xffff; + + switch (call) { + case SEMOP: + return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL); + case SEMTIMEDOP: + return sys_semtimedop(first, (struct sembuf __user *)ptr, second, + (const struct timespec __user *)fifth); + + case SEMGET: + return sys_semget (first, second, third); + case SEMCTL: { + union semun fourth; + if (!ptr) + return -EINVAL; + if (get_user(fourth.__pad, (void __user * __user *) ptr)) + return -EFAULT; + return sys_semctl (first, second, third, fourth); + } + + case MSGSND: + return sys_msgsnd(first, (struct msgbuf __user *) ptr, + second, third); + case MSGRCV: + switch (version) { + case 0: { + struct ipc_kludge tmp; + if (!ptr) + return -EINVAL; + if (copy_from_user(&tmp,(struct ipc_kludge __user *)ptr, + sizeof (tmp))) + return -EFAULT; + return sys_msgrcv (first, tmp.msgp, second, + tmp.msgtyp, third); + } + default: + return sys_msgrcv (first, + (struct msgbuf __user *) ptr, + second, fifth, third); + } + case MSGGET: + return sys_msgget ((key_t) first, second); + case MSGCTL: + return sys_msgctl(first, second, (struct msqid_ds __user *)ptr); + + case SHMAT: + switch (version) { + default: { + ulong raddr; + ret = do_shmat(first, (char __user *)ptr, second, &raddr); + if (ret) + return ret; + return put_user(raddr, (ulong __user *)third); + } + case 1: /* Of course, we don't support iBCS2! */ + return -EINVAL; + } + case SHMDT: + return sys_shmdt ((char __user *)ptr); + case SHMGET: + return sys_shmget (first, second, third); + case SHMCTL: + return sys_shmctl (first, second, + (struct shmid_ds __user *) ptr); + default: + return -ENOSYS; + } +} + +asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg, + unsigned long __user *addr) +{ + unsigned long ret; + long err; + + err = do_shmat(shmid, shmaddr, shmflg, &ret); + if (err == 0) + err = put_user(ret, addr); + return err; +} + +/* Fork a new task - this creates a new program thread. + * This is called indirectly via a small wrapper + */ +asmlinkage int sys_fork(struct pt_regs *regs) +{ + return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL); +} + +/* Clone a task - this clones the calling program thread. + * This is called indirectly via a small wrapper + */ +asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, + int __user *parent_tidptr, int tls_val, + int __user *child_tidptr, struct pt_regs *regs) +{ + if (!newsp) + newsp = regs->ARM_sp; + + return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); +} + +asmlinkage int sys_vfork(struct pt_regs *regs) +{ + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL); +} + +/* sys_execve() executes a new program. + * This is called indirectly via a small wrapper + */ +asmlinkage int sys_execve(char __user *filenamei, char __user * __user *argv, + char __user * __user *envp, struct pt_regs *regs) +{ + int error; + char * filename; + + filename = getname(filenamei); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = do_execve(filename, argv, envp, regs); + putname(filename); +out: + return error; +} + +long execve(const char *filename, char **argv, char **envp) +{ + struct pt_regs regs; + int ret; + + memset(®s, 0, sizeof(struct pt_regs)); + ret = do_execve((char *)filename, (char __user * __user *)argv, + (char __user * __user *)envp, ®s); + if (ret < 0) + goto out; + + /* + * Save argc to the register structure for userspace. + */ + regs.ARM_r0 = ret; + + /* + * We were successful. We won't be returning to our caller, but + * instead to user space by manipulating the kernel stack. + */ + asm( "add r0, %0, %1\n\t" + "mov r1, %2\n\t" + "mov r2, %3\n\t" + "bl memmove\n\t" /* copy regs to top of stack */ + "mov r8, #0\n\t" /* not a syscall */ + "mov r9, %0\n\t" /* thread structure */ + "mov sp, r0\n\t" /* reposition stack pointer */ + "b ret_to_user" + : + : "r" (current_thread_info()), + "Ir" (THREAD_SIZE - 8 - sizeof(regs)), + "r" (®s), + "Ir" (sizeof(regs)) + : "r0", "r1", "r2", "r3", "ip", "memory"); + + out: + return ret; +} +EXPORT_SYMBOL(execve); diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c new file mode 100644 index 0000000..c232f24 --- /dev/null +++ b/arch/arm/kernel/time.c @@ -0,0 +1,402 @@ +/* + * linux/arch/arm/kernel/time.c + * + * Copyright (C) 1991, 1992, 1995 Linus Torvalds + * Modifications for ARM (C) 1994-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. + * + * This file contains the ARM-specific time handling details: + * reading the RTC at bootup, etc... + * + * 1994-07-02 Alan Modra + * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime + * 1998-12-20 Updated NTP code according to technical memorandum Jan '96 + * "A Kernel Model for Precision Timekeeping" by Dave Mills + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/time.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/timex.h> +#include <linux/errno.h> +#include <linux/profile.h> +#include <linux/sysdev.h> +#include <linux/timer.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/leds.h> +#include <asm/thread_info.h> +#include <asm/mach/time.h> + +u64 jiffies_64 = INITIAL_JIFFIES; + +EXPORT_SYMBOL(jiffies_64); + +/* + * Our system timer. + */ +struct sys_timer *system_timer; + +extern unsigned long wall_jiffies; + +/* this needs a better home */ +DEFINE_SPINLOCK(rtc_lock); + +#ifdef CONFIG_SA1100_RTC_MODULE +EXPORT_SYMBOL(rtc_lock); +#endif + +/* change this if you have some constant time drift */ +#define USECS_PER_JIFFY (1000000/HZ) + +#ifdef CONFIG_SMP +unsigned long profile_pc(struct pt_regs *regs) +{ + unsigned long fp, pc = instruction_pointer(regs); + + if (in_lock_functions(pc)) { + fp = regs->ARM_fp; + pc = pc_pointer(((unsigned long *)fp)[-1]); + } + + return pc; +} +EXPORT_SYMBOL(profile_pc); +#endif + +/* + * hook for setting the RTC's idea of the current time. + */ +int (*set_rtc)(void); + +static unsigned long dummy_gettimeoffset(void) +{ + return 0; +} + +/* + * Scheduler clock - returns current time in nanosec units. + * This is the default implementation. Sub-architecture + * implementations can override this. + */ +unsigned long long __attribute__((weak)) sched_clock(void) +{ + return (unsigned long long)jiffies * (1000000000 / HZ); +} + +static unsigned long next_rtc_update; + +/* + * If we have an externally synchronized linux clock, then update + * CMOS clock accordingly every ~11 minutes. set_rtc() has to be + * called as close as possible to 500 ms before the new second + * starts. + */ +static inline void do_set_rtc(void) +{ + if (time_status & STA_UNSYNC || set_rtc == NULL) + return; + + if (next_rtc_update && + time_before((unsigned long)xtime.tv_sec, next_rtc_update)) + return; + + if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) && + xtime.tv_nsec >= 500000000 + ((unsigned) tick_nsec >> 1)) + return; + + if (set_rtc()) + /* + * rtc update failed. Try again in 60s + */ + next_rtc_update = xtime.tv_sec + 60; + else + next_rtc_update = xtime.tv_sec + 660; +} + +#ifdef CONFIG_LEDS + +static void dummy_leds_event(led_event_t evt) +{ +} + +void (*leds_event)(led_event_t) = dummy_leds_event; + +struct leds_evt_name { + const char name[8]; + int on; + int off; +}; + +static const struct leds_evt_name evt_names[] = { + { "amber", led_amber_on, led_amber_off }, + { "blue", led_blue_on, led_blue_off }, + { "green", led_green_on, led_green_off }, + { "red", led_red_on, led_red_off }, +}; + +static ssize_t leds_store(struct sys_device *dev, const char *buf, size_t size) +{ + int ret = -EINVAL, len = strcspn(buf, " "); + + if (len > 0 && buf[len] == '\0') + len--; + + if (strncmp(buf, "claim", len) == 0) { + leds_event(led_claim); + ret = size; + } else if (strncmp(buf, "release", len) == 0) { + leds_event(led_release); + ret = size; + } else { + int i; + + for (i = 0; i < ARRAY_SIZE(evt_names); i++) { + if (strlen(evt_names[i].name) != len || + strncmp(buf, evt_names[i].name, len) != 0) + continue; + if (strncmp(buf+len, " on", 3) == 0) { + leds_event(evt_names[i].on); + ret = size; + } else if (strncmp(buf+len, " off", 4) == 0) { + leds_event(evt_names[i].off); + ret = size; + } + break; + } + } + return ret; +} + +static SYSDEV_ATTR(event, 0200, NULL, leds_store); + +static int leds_suspend(struct sys_device *dev, pm_message_t state) +{ + leds_event(led_stop); + return 0; +} + +static int leds_resume(struct sys_device *dev) +{ + leds_event(led_start); + return 0; +} + +static int leds_shutdown(struct sys_device *dev) +{ + leds_event(led_halted); + return 0; +} + +static struct sysdev_class leds_sysclass = { + set_kset_name("leds"), + .shutdown = leds_shutdown, + .suspend = leds_suspend, + .resume = leds_resume, +}; + +static struct sys_device leds_device = { + .id = 0, + .cls = &leds_sysclass, +}; + +static int __init leds_init(void) +{ + int ret; + ret = sysdev_class_register(&leds_sysclass); + if (ret == 0) + ret = sysdev_register(&leds_device); + if (ret == 0) + ret = sysdev_create_file(&leds_device, &attr_event); + return ret; +} + +device_initcall(leds_init); + +EXPORT_SYMBOL(leds_event); +#endif + +#ifdef CONFIG_LEDS_TIMER +static inline void do_leds(void) +{ + static unsigned int count = 50; + + if (--count == 0) { + count = 50; + leds_event(led_timer); + } +} +#else +#define do_leds() +#endif + +void do_gettimeofday(struct timeval *tv) +{ + unsigned long flags; + unsigned long seq; + unsigned long usec, sec, lost; + + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + usec = system_timer->offset(); + + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * USECS_PER_JIFFY; + + sec = xtime.tv_sec; + usec += xtime.tv_nsec / 1000; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + + /* usec may have gone up a lot: be safe */ + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +EXPORT_SYMBOL(do_gettimeofday); + +int do_settimeofday(struct timespec *tv) +{ + time_t wtm_sec, sec = tv->tv_sec; + long wtm_nsec, nsec = tv->tv_nsec; + + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + write_seqlock_irq(&xtime_lock); + /* + * This is revolting. We need to set "xtime" correctly. However, the + * value in this location is the value at the most recent update of + * wall time. Discover what correction gettimeofday() would have + * done, and then undo it! + */ + nsec -= system_timer->offset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; + + wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); + wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); + + set_normalized_timespec(&xtime, sec, nsec); + set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); + + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; + write_sequnlock_irq(&xtime_lock); + clock_was_set(); + return 0; +} + +EXPORT_SYMBOL(do_settimeofday); + +/** + * save_time_delta - Save the offset between system time and RTC time + * @delta: pointer to timespec to store delta + * @rtc: pointer to timespec for current RTC time + * + * Return a delta between the system time and the RTC time, such + * that system time can be restored later with restore_time_delta() + */ +void save_time_delta(struct timespec *delta, struct timespec *rtc) +{ + set_normalized_timespec(delta, + xtime.tv_sec - rtc->tv_sec, + xtime.tv_nsec - rtc->tv_nsec); +} +EXPORT_SYMBOL(save_time_delta); + +/** + * restore_time_delta - Restore the current system time + * @delta: delta returned by save_time_delta() + * @rtc: pointer to timespec for current RTC time + */ +void restore_time_delta(struct timespec *delta, struct timespec *rtc) +{ + struct timespec ts; + + set_normalized_timespec(&ts, + delta->tv_sec + rtc->tv_sec, + delta->tv_nsec + rtc->tv_nsec); + + do_settimeofday(&ts); +} +EXPORT_SYMBOL(restore_time_delta); + +/* + * Kernel system timer support. + */ +void timer_tick(struct pt_regs *regs) +{ + profile_tick(CPU_PROFILING, regs); + do_leds(); + do_set_rtc(); + do_timer(regs); +#ifndef CONFIG_SMP + update_process_times(user_mode(regs)); +#endif +} + +#ifdef CONFIG_PM +static int timer_suspend(struct sys_device *dev, pm_message_t state) +{ + struct sys_timer *timer = container_of(dev, struct sys_timer, dev); + + if (timer->suspend != NULL) + timer->suspend(); + + return 0; +} + +static int timer_resume(struct sys_device *dev) +{ + struct sys_timer *timer = container_of(dev, struct sys_timer, dev); + + if (timer->resume != NULL) + timer->resume(); + + return 0; +} +#else +#define timer_suspend NULL +#define timer_resume NULL +#endif + +static struct sysdev_class timer_sysclass = { + set_kset_name("timer"), + .suspend = timer_suspend, + .resume = timer_resume, +}; + +static int __init timer_init_sysfs(void) +{ + int ret = sysdev_class_register(&timer_sysclass); + if (ret == 0) { + system_timer->dev.cls = &timer_sysclass; + ret = sysdev_register(&system_timer->dev); + } + return ret; +} + +device_initcall(timer_init_sysfs); + +void __init time_init(void) +{ + if (system_timer->offset == NULL) + system_timer->offset = dummy_gettimeoffset; + system_timer->init(); +} + diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c new file mode 100644 index 0000000..93dc464 --- /dev/null +++ b/arch/arm/kernel/traps.c @@ -0,0 +1,590 @@ +/* + * linux/arch/arm/kernel/traps.c + * + * Copyright (C) 1995-2002 Russell King + * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds + * + * 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. + * + * 'traps.c' handles hardware exceptions after we have saved some state in + * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably + * kill the offending process. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/spinlock.h> +#include <linux/personality.h> +#include <linux/ptrace.h> +#include <linux/kallsyms.h> +#include <linux/init.h> + +#include <asm/atomic.h> +#include <asm/cacheflush.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/uaccess.h> +#include <asm/unistd.h> +#include <asm/traps.h> + +#include "ptrace.h" + +extern void c_backtrace (unsigned long fp, int pmode); +extern void show_pte(struct mm_struct *mm, unsigned long addr); + +const char *processor_modes[]= +{ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , + "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", + "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" , + "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32" +}; + +static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; + +#ifdef CONFIG_DEBUG_USER +unsigned int user_debug; + +static int __init user_debug_setup(char *str) +{ + get_option(&str, &user_debug); + return 1; +} +__setup("user_debug=", user_debug_setup); +#endif + +void dump_backtrace_entry(unsigned long where, unsigned long from) +{ +#ifdef CONFIG_KALLSYMS + printk("[<%08lx>] ", where); + print_symbol("(%s) ", where); + printk("from [<%08lx>] ", from); + print_symbol("(%s)\n", from); +#else + printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); +#endif +} + +/* + * Stack pointers should always be within the kernels view of + * physical memory. If it is not there, then we can't dump + * out any information relating to the stack. + */ +static int verify_stack(unsigned long sp) +{ + if (sp < PAGE_OFFSET || (sp > (unsigned long)high_memory && high_memory != 0)) + return -EFAULT; + + return 0; +} + +/* + * Dump out the contents of some memory nicely... + */ +static void dump_mem(const char *str, unsigned long bottom, unsigned long top) +{ + unsigned long p = bottom & ~31; + mm_segment_t fs; + int i; + + /* + * We need to switch to kernel mode so that we can use __get_user + * to safely read from kernel space. Note that we now dump the + * code first, just in case the backtrace kills us. + */ + fs = get_fs(); + set_fs(KERNEL_DS); + + printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); + + for (p = bottom & ~31; p < top;) { + printk("%04lx: ", p & 0xffff); + + for (i = 0; i < 8; i++, p += 4) { + unsigned int val; + + if (p < bottom || p >= top) + printk(" "); + else { + __get_user(val, (unsigned long *)p); + printk("%08x ", val); + } + } + printk ("\n"); + } + + set_fs(fs); +} + +static void dump_instr(struct pt_regs *regs) +{ + unsigned long addr = instruction_pointer(regs); + const int thumb = thumb_mode(regs); + const int width = thumb ? 4 : 8; + mm_segment_t fs; + int i; + + /* + * We need to switch to kernel mode so that we can use __get_user + * to safely read from kernel space. Note that we now dump the + * code first, just in case the backtrace kills us. + */ + fs = get_fs(); + set_fs(KERNEL_DS); + + printk("Code: "); + for (i = -4; i < 1; i++) { + unsigned int val, bad; + + if (thumb) + bad = __get_user(val, &((u16 *)addr)[i]); + else + bad = __get_user(val, &((u32 *)addr)[i]); + + if (!bad) + printk(i == 0 ? "(%0*x) " : "%0*x ", width, val); + else { + printk("bad PC value."); + break; + } + } + printk("\n"); + + set_fs(fs); +} + +static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) +{ + unsigned int fp; + int ok = 1; + + printk("Backtrace: "); + fp = regs->ARM_fp; + if (!fp) { + printk("no frame pointer"); + ok = 0; + } else if (verify_stack(fp)) { + printk("invalid frame pointer 0x%08x", fp); + ok = 0; + } else if (fp < (unsigned long)(tsk->thread_info + 1)) + printk("frame pointer underflow"); + printk("\n"); + + if (ok) + c_backtrace(fp, processor_mode(regs)); +} + +void dump_stack(void) +{ +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif +} + +EXPORT_SYMBOL(dump_stack); + +void show_stack(struct task_struct *tsk, unsigned long *sp) +{ + unsigned long fp; + + if (!tsk) + tsk = current; + + if (tsk != current) + fp = thread_saved_fp(tsk); + else + asm("mov%? %0, fp" : "=r" (fp)); + + c_backtrace(fp, 0x10); + barrier(); +} + +DEFINE_SPINLOCK(die_lock); + +/* + * This function is protected against re-entrancy. + */ +NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) +{ + struct task_struct *tsk = current; + static int die_counter; + + console_verbose(); + spin_lock_irq(&die_lock); + bust_spinlocks(1); + + printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter); + print_modules(); + printk("CPU: %d\n", smp_processor_id()); + show_regs(regs); + printk("Process %s (pid: %d, stack limit = 0x%p)\n", + tsk->comm, tsk->pid, tsk->thread_info + 1); + + if (!user_mode(regs) || in_interrupt()) { + dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info); + dump_backtrace(regs, tsk); + dump_instr(regs); + } + + bust_spinlocks(0); + spin_unlock_irq(&die_lock); + do_exit(SIGSEGV); +} + +void die_if_kernel(const char *str, struct pt_regs *regs, int err) +{ + if (user_mode(regs)) + return; + + die(str, regs, err); +} + +static void notify_die(const char *str, struct pt_regs *regs, siginfo_t *info, + unsigned long err, unsigned long trap) +{ + if (user_mode(regs)) { + current->thread.error_code = err; + current->thread.trap_no = trap; + + force_sig_info(info->si_signo, info, current); + } else { + die(str, regs, err); + } +} + +static LIST_HEAD(undef_hook); +static DEFINE_SPINLOCK(undef_lock); + +void register_undef_hook(struct undef_hook *hook) +{ + spin_lock_irq(&undef_lock); + list_add(&hook->node, &undef_hook); + spin_unlock_irq(&undef_lock); +} + +void unregister_undef_hook(struct undef_hook *hook) +{ + spin_lock_irq(&undef_lock); + list_del(&hook->node); + spin_unlock_irq(&undef_lock); +} + +asmlinkage void do_undefinstr(struct pt_regs *regs) +{ + unsigned int correction = thumb_mode(regs) ? 2 : 4; + unsigned int instr; + struct undef_hook *hook; + siginfo_t info; + void __user *pc; + + /* + * According to the ARM ARM, PC is 2 or 4 bytes ahead, + * depending whether we're in Thumb mode or not. + * Correct this offset. + */ + regs->ARM_pc -= correction; + + pc = (void __user *)instruction_pointer(regs); + if (thumb_mode(regs)) { + get_user(instr, (u16 __user *)pc); + } else { + get_user(instr, (u32 __user *)pc); + } + + spin_lock_irq(&undef_lock); + list_for_each_entry(hook, &undef_hook, node) { + if ((instr & hook->instr_mask) == hook->instr_val && + (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) { + if (hook->fn(regs, instr) == 0) { + spin_unlock_irq(&undef_lock); + return; + } + } + } + spin_unlock_irq(&undef_lock); + +#ifdef CONFIG_DEBUG_USER + if (user_debug & UDBG_UNDEFINED) { + printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", + current->comm, current->pid, pc); + dump_instr(regs); + } +#endif + + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLOPC; + info.si_addr = pc; + + notify_die("Oops - undefined instruction", regs, &info, 0, 6); +} + +asmlinkage void do_unexp_fiq (struct pt_regs *regs) +{ +#ifndef CONFIG_IGNORE_FIQ + printk("Hmm. Unexpected FIQ received, but trying to continue\n"); + printk("You may have a hardware problem...\n"); +#endif +} + +/* + * bad_mode handles the impossible case in the vectors. If you see one of + * these, then it's extremely serious, and could mean you have buggy hardware. + * It never returns, and never tries to sync. We hope that we can at least + * dump out some state information... + */ +asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) +{ + console_verbose(); + + printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n", + handler[reason], processor_modes[proc_mode]); + + die("Oops - bad mode", regs, 0); + local_irq_disable(); + panic("bad mode"); +} + +static int bad_syscall(int n, struct pt_regs *regs) +{ + struct thread_info *thread = current_thread_info(); + siginfo_t info; + + if (current->personality != PER_LINUX && thread->exec_domain->handler) { + thread->exec_domain->handler(n, regs); + return regs->ARM_r0; + } + +#ifdef CONFIG_DEBUG_USER + if (user_debug & UDBG_SYSCALL) { + printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", + current->pid, current->comm, n); + dump_instr(regs); + } +#endif + + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLTRP; + info.si_addr = (void __user *)instruction_pointer(regs) - + (thumb_mode(regs) ? 2 : 4); + + notify_die("Oops - bad syscall", regs, &info, n, 0); + + return regs->ARM_r0; +} + +static inline void +do_cache_op(unsigned long start, unsigned long end, int flags) +{ + struct vm_area_struct *vma; + + if (end < start || flags) + return; + + vma = find_vma(current->active_mm, start); + if (vma && vma->vm_start < end) { + if (start < vma->vm_start) + start = vma->vm_start; + if (end > vma->vm_end) + end = vma->vm_end; + + flush_cache_user_range(vma, start, end); + } +} + +/* + * Handle all unrecognised system calls. + * 0x9f0000 - 0x9fffff are some more esoteric system calls + */ +#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE) +asmlinkage int arm_syscall(int no, struct pt_regs *regs) +{ + struct thread_info *thread = current_thread_info(); + siginfo_t info; + + if ((no >> 16) != 0x9f) + return bad_syscall(no, regs); + + switch (no & 0xffff) { + case 0: /* branch through 0 */ + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = SEGV_MAPERR; + info.si_addr = NULL; + + notify_die("branch through zero", regs, &info, 0, 0); + return 0; + + case NR(breakpoint): /* SWI BREAK_POINT */ + regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; + ptrace_break(current, regs); + return regs->ARM_r0; + + /* + * Flush a region from virtual address 'r0' to virtual address 'r1' + * _exclusive_. There is no alignment requirement on either address; + * user space does not need to know the hardware cache layout. + * + * r2 contains flags. It should ALWAYS be passed as ZERO until it + * is defined to be something else. For now we ignore it, but may + * the fires of hell burn in your belly if you break this rule. ;) + * + * (at a later date, we may want to allow this call to not flush + * various aspects of the cache. Passing '0' will guarantee that + * everything necessary gets flushed to maintain consistency in + * the specified region). + */ + case NR(cacheflush): + do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2); + return 0; + + case NR(usr26): + if (!(elf_hwcap & HWCAP_26BIT)) + break; + regs->ARM_cpsr &= ~MODE32_BIT; + return regs->ARM_r0; + + case NR(usr32): + if (!(elf_hwcap & HWCAP_26BIT)) + break; + regs->ARM_cpsr |= MODE32_BIT; + return regs->ARM_r0; + + case NR(set_tls): + thread->tp_value = regs->ARM_r0; + /* + * Our user accessible TLS ptr is located at 0xffff0ffc. + * On SMP read access to this address must raise a fault + * and be emulated from the data abort handler. + * m + */ + *((unsigned long *)0xffff0ffc) = thread->tp_value; + return 0; + + default: + /* Calls 9f00xx..9f07ff are defined to return -ENOSYS + if not implemented, rather than raising SIGILL. This + way the calling program can gracefully determine whether + a feature is supported. */ + if (no <= 0x7ff) + return -ENOSYS; + break; + } +#ifdef CONFIG_DEBUG_USER + /* + * experience shows that these seem to indicate that + * something catastrophic has happened + */ + if (user_debug & UDBG_SYSCALL) { + printk("[%d] %s: arm syscall %d\n", + current->pid, current->comm, no); + dump_instr(regs); + if (user_mode(regs)) { + show_regs(regs); + c_backtrace(regs->ARM_fp, processor_mode(regs)); + } + } +#endif + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLTRP; + info.si_addr = (void __user *)instruction_pointer(regs) - + (thumb_mode(regs) ? 2 : 4); + + notify_die("Oops - bad syscall(2)", regs, &info, no, 0); + return 0; +} + +void __bad_xchg(volatile void *ptr, int size) +{ + printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", + __builtin_return_address(0), ptr, size); + BUG(); +} +EXPORT_SYMBOL(__bad_xchg); + +/* + * A data abort trap was taken, but we did not handle the instruction. + * Try to abort the user program, or panic if it was the kernel. + */ +asmlinkage void +baddataabort(int code, unsigned long instr, struct pt_regs *regs) +{ + unsigned long addr = instruction_pointer(regs); + siginfo_t info; + +#ifdef CONFIG_DEBUG_USER + if (user_debug & UDBG_BADABORT) { + printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n", + current->pid, current->comm, code, instr); + dump_instr(regs); + show_pte(current->mm, addr); + } +#endif + + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = ILL_ILLOPC; + info.si_addr = (void __user *)addr; + + notify_die("unknown data abort code", regs, &info, instr, 0); +} + +volatile void __bug(const char *file, int line, void *data) +{ + printk(KERN_CRIT"kernel BUG at %s:%d!", file, line); + if (data) + printk(" - extra data = %p", data); + printk("\n"); + *(int *)0 = 0; +} +EXPORT_SYMBOL(__bug); + +void __readwrite_bug(const char *fn) +{ + printk("%s called, but not implemented\n", fn); + BUG(); +} +EXPORT_SYMBOL(__readwrite_bug); + +void __pte_error(const char *file, int line, unsigned long val) +{ + printk("%s:%d: bad pte %08lx.\n", file, line, val); +} + +void __pmd_error(const char *file, int line, unsigned long val) +{ + printk("%s:%d: bad pmd %08lx.\n", file, line, val); +} + +void __pgd_error(const char *file, int line, unsigned long val) +{ + printk("%s:%d: bad pgd %08lx.\n", file, line, val); +} + +asmlinkage void __div0(void) +{ + printk("Division by zero in kernel.\n"); + dump_stack(); +} +EXPORT_SYMBOL(__div0); + +void abort(void) +{ + BUG(); + + /* if that doesn't kill us, halt */ + panic("Oops failed to kill thread"); +} +EXPORT_SYMBOL(abort); + +void __init trap_init(void) +{ + extern void __trap_init(void); + + __trap_init(); + flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); + modify_domain(DOMAIN_USER, DOMAIN_CLIENT); +} diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S new file mode 100644 index 0000000..a39c6a4 --- /dev/null +++ b/arch/arm/kernel/vmlinux.lds.S @@ -0,0 +1,166 @@ +/* ld script to make ARM Linux kernel + * taken from the i386 version by Russell King + * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> + */ + +#include <asm-generic/vmlinux.lds.h> +#include <linux/config.h> + +OUTPUT_ARCH(arm) +ENTRY(stext) +#ifndef __ARMEB__ +jiffies = jiffies_64; +#else +jiffies = jiffies_64 + 4; +#endif +SECTIONS +{ + . = TEXTADDR; + .init : { /* Init code and data */ + _stext = .; + _sinittext = .; + *(.init.text) + _einittext = .; + __proc_info_begin = .; + *(.proc.info) + __proc_info_end = .; + __arch_info_begin = .; + *(.arch.info) + __arch_info_end = .; + __tagtable_begin = .; + *(.taglist) + __tagtable_end = .; + . = ALIGN(16); + __setup_start = .; + *(.init.setup) + __setup_end = .; + __early_begin = .; + *(__early_param) + __early_end = .; + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + __security_initcall_start = .; + *(.security_initcall.init) + __security_initcall_end = .; + . = ALIGN(32); + __initramfs_start = .; + usr/built-in.o(.init.ramfs) + __initramfs_end = .; + . = ALIGN(64); + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; +#ifndef CONFIG_XIP_KERNEL + __init_begin = _stext; + *(.init.data) + . = ALIGN(4096); + __init_end = .; +#endif + } + + /DISCARD/ : { /* Exit code and data */ + *(.exit.text) + *(.exit.data) + *(.exitcall.exit) + } + + .text : { /* Real text segment */ + _text = .; /* Text and read-only data */ + *(.text) + SCHED_TEXT + LOCK_TEXT + *(.fixup) + *(.gnu.warning) + *(.rodata) + *(.rodata.*) + *(.glue_7) + *(.glue_7t) + *(.got) /* Global offset table */ + } + + . = ALIGN(16); + __ex_table : { /* Exception table */ + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + RODATA + + _etext = .; /* End of text and rodata section */ + +#ifdef CONFIG_XIP_KERNEL + __data_loc = ALIGN(4); /* location in binary */ + . = DATAADDR; +#else + . = ALIGN(8192); + __data_loc = .; +#endif + + .data : AT(__data_loc) { + __data_start = .; /* address in memory */ + + /* + * first, the init task union, aligned + * to an 8192 byte boundary. + */ + *(.init.task) + +#ifdef CONFIG_XIP_KERNEL + . = ALIGN(4096); + __init_begin = .; + *(.init.data) + . = ALIGN(4096); + __init_end = .; +#endif + + . = ALIGN(4096); + __nosave_begin = .; + *(.data.nosave) + . = ALIGN(4096); + __nosave_end = .; + + /* + * then the cacheline aligned data + */ + . = ALIGN(32); + *(.data.cacheline_aligned) + + /* + * and the usual data section + */ + *(.data) + CONSTRUCTORS + + _edata = .; + } + + .bss : { + __bss_start = .; /* BSS */ + *(.bss) + *(COMMON) + _end = .; + } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} + +/* those must never be empty */ +ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") +ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile new file mode 100644 index 0000000..c0e6583 --- /dev/null +++ b/arch/arm/lib/Makefile @@ -0,0 +1,29 @@ +# +# linux/arch/arm/lib/Makefile +# +# Copyright (C) 1995-2000 Russell King +# + +lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ + csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ + copy_page.o delay.o findbit.o memchr.o memcpy.o \ + memset.o memzero.o setbit.o strncpy_from_user.o \ + strnlen_user.o strchr.o strrchr.o testchangebit.o \ + testclearbit.o testsetbit.o uaccess.o getuser.o \ + putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ + ucmpdi2.o udivdi3.o lib1funcs.o div64.o \ + io-readsb.o io-writesb.o io-readsl.o io-writesl.o + +ifeq ($(CONFIG_CPU_32v3),y) + lib-y += io-readsw-armv3.o io-writesw-armv3.o +else + lib-y += io-readsw-armv4.o io-writesw-armv4.o +endif + +lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o +lib-$(CONFIG_ARCH_CLPS7500) += io-acorn.o +lib-$(CONFIG_ARCH_L7200) += io-acorn.o +lib-$(CONFIG_ARCH_SHARK) += io-shark.o + +$(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S +$(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c new file mode 100644 index 0000000..130f5a8 --- /dev/null +++ b/arch/arm/lib/ashldi3.c @@ -0,0 +1,61 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC 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, or (at your option) +any later version. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. + */ +/* support functions required by the kernel. based on code from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#include "gcclib.h" + +DItype +__ashldi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.low = 0; + w.s.high = (USItype)uu.s.low << -bm; + } + else + { + USItype carries = (USItype)uu.s.low >> bm; + w.s.low = (USItype)uu.s.low << b; + w.s.high = ((USItype)uu.s.high << b) | carries; + } + + return w.ll; +} + diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c new file mode 100644 index 0000000..71625d2 --- /dev/null +++ b/arch/arm/lib/ashrdi3.c @@ -0,0 +1,61 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC 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, or (at your option) +any later version. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. + */ +/* support functions required by the kernel. based on code from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#include "gcclib.h" + +DItype +__ashrdi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); + w.s.low = uu.s.high >> -bm; + } + else + { + USItype carries = (USItype)uu.s.high << bm; + w.s.high = uu.s.high >> b; + w.s.low = ((USItype)uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S new file mode 100644 index 0000000..68a21c0 --- /dev/null +++ b/arch/arm/lib/backtrace.S @@ -0,0 +1,157 @@ +/* + * linux/arch/arm/lib/backtrace.S + * + * Copyright (C) 1995, 1996 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. + * + * 27/03/03 Ian Molton Clean up CONFIG_CPU + * + */ +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/assembler.h> + .text + +@ fp is 0 or stack frame + +#define frame r4 +#define next r5 +#define save r6 +#define mask r7 +#define offset r8 + +ENTRY(__backtrace) + mov r1, #0x10 + mov r0, fp + +ENTRY(c_backtrace) + +#ifndef CONFIG_FRAME_POINTER + mov pc, lr +#else + + stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... + tst r1, #0x10 @ 26 or 32-bit? + moveq mask, #0xfc000003 + movne mask, #0 + tst mask, r0 + movne r0, #0 + movs frame, r0 +1: moveq r0, #-2 + LOADREGS(eqfd, sp!, {r4 - r8, pc}) + +2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction + ldr r0, [sp], #4 + adr r1, 2b - 4 + sub offset, r0, r1 + +3: tst frame, mask @ Check for address exceptions... + bne 1b + +1001: ldr next, [frame, #-12] @ get fp +1002: ldr r2, [frame, #-4] @ get lr +1003: ldr r3, [frame, #0] @ get pc + sub save, r3, offset @ Correct PC for prefetching + bic save, save, mask +1004: ldr r1, [save, #0] @ get instruction at function + mov r1, r1, lsr #10 + ldr r3, .Ldsi+4 + teq r1, r3 + subeq save, save, #4 + mov r0, save + bic r1, r2, mask + bl dump_backtrace_entry + + ldr r0, [frame, #-8] @ get sp + sub r0, r0, #4 +1005: ldr r1, [save, #4] @ get instruction at function+4 + mov r3, r1, lsr #10 + ldr r2, .Ldsi+4 + teq r3, r2 @ Check for stmia sp!, {args} + addeq save, save, #4 @ next instruction + bleq .Ldumpstm + + sub r0, frame, #16 +1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction + mov r3, r1, lsr #10 + ldr r2, .Ldsi + teq r3, r2 + bleq .Ldumpstm + + /* + * A zero next framepointer means we're done. + */ + teq next, #0 + LOADREGS(eqfd, sp!, {r4 - r8, pc}) + + /* + * The next framepointer must be above the + * current framepointer. + */ + cmp next, frame + mov frame, next + bhi 3b + b 1007f + +/* + * Fixup for LDMDB + */ + .section .fixup,"ax" + .align 0 +1007: ldr r0, =.Lbad + mov r1, frame + bl printk + LOADREGS(fd, sp!, {r4 - r8, pc}) + .ltorg + .previous + + .section __ex_table,"a" + .align 3 + .long 1001b, 1007b + .long 1002b, 1007b + .long 1003b, 1007b + .long 1004b, 1007b + .long 1005b, 1007b + .long 1006b, 1007b + .previous + +#define instr r4 +#define reg r5 +#define stack r6 + +.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} + mov stack, r0 + mov instr, r1 + mov reg, #9 + mov r7, #0 +1: mov r3, #1 + tst instr, r3, lsl reg + beq 2f + add r7, r7, #1 + teq r7, #4 + moveq r7, #0 + moveq r3, #'\n' + movne r3, #' ' + ldr r2, [stack], #-4 + mov r1, reg + adr r0, .Lfp + bl printk +2: subs reg, reg, #1 + bpl 1b + teq r7, #0 + adrne r0, .Lcr + blne printk + mov r0, stack + LOADREGS(fd, sp!, {instr, reg, stack, r7, pc}) + +.Lfp: .asciz " r%d = %08X%c" +.Lcr: .asciz "\n" +.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" + .align +.Ldsi: .word 0x00e92dd8 >> 2 + .word 0x00e92d00 >> 2 + +#endif diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S new file mode 100644 index 0000000..3af45ca --- /dev/null +++ b/arch/arm/lib/changebit.S @@ -0,0 +1,28 @@ +/* + * linux/arch/arm/lib/changebit.S + * + * Copyright (C) 1995-1996 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/linkage.h> +#include <asm/assembler.h> + .text + +/* Purpose : Function to change a bit + * Prototype: int change_bit(int bit, void *addr) + */ +ENTRY(_change_bit_be) + eor r0, r0, #0x18 @ big endian byte ordering +ENTRY(_change_bit_le) + and r2, r0, #7 + mov r3, #1 + mov r3, r3, lsl r2 + save_and_disable_irqs ip, r2 + ldrb r2, [r1, r0, lsr #3] + eor r2, r2, r3 + strb r2, [r1, r0, lsr #3] + restore_irqs ip + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S new file mode 100644 index 0000000..069a2ce --- /dev/null +++ b/arch/arm/lib/clearbit.S @@ -0,0 +1,31 @@ +/* + * linux/arch/arm/lib/clearbit.S + * + * Copyright (C) 1995-1996 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/linkage.h> +#include <asm/assembler.h> + .text + +/* + * Purpose : Function to clear a bit + * Prototype: int clear_bit(int bit, void *addr) + */ +ENTRY(_clear_bit_be) + eor r0, r0, #0x18 @ big endian byte ordering +ENTRY(_clear_bit_le) + and r2, r0, #7 + mov r3, #1 + mov r3, r3, lsl r2 + save_and_disable_irqs ip, r2 + ldrb r2, [r1, r0, lsr #3] + bic r2, r2, r3 + strb r2, [r1, r0, lsr #3] + restore_irqs ip + RETINSTR(mov,pc,lr) + + diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S new file mode 100644 index 0000000..4c38abd --- /dev/null +++ b/arch/arm/lib/copy_page.S @@ -0,0 +1,46 @@ +/* + * linux/arch/arm/lib/copypage.S + * + * Copyright (C) 1995-1999 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/constants.h> + +#define COPY_COUNT (PAGE_SZ/64 PLD( -1 )) + + .text + .align 5 +/* + * StrongARM optimised copy_page routine + * now 1.78bytes/cycle, was 1.60 bytes/cycle (50MHz bus -> 89MB/s) + * Note that we probably achieve closer to the 100MB/s target with + * the core clock switching. + */ +ENTRY(copy_page) + stmfd sp!, {r4, lr} @ 2 + PLD( pld [r1, #0] ) + PLD( pld [r1, #32] ) + mov r2, #COPY_COUNT @ 1 + ldmia r1!, {r3, r4, ip, lr} @ 4+1 +1: PLD( pld [r1, #64] ) + PLD( pld [r1, #96] ) +2: stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4+1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4+1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4 + subs r2, r2, #1 @ 1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmgtia r1!, {r3, r4, ip, lr} @ 4 + bgt 1b @ 1 + PLD( ldmeqia r1!, {r3, r4, ip, lr} ) + PLD( beq 2b ) + LOADREGS(fd, sp!, {r4, pc}) @ 3 diff --git a/arch/arm/lib/csumipv6.S b/arch/arm/lib/csumipv6.S new file mode 100644 index 0000000..7065a20 --- /dev/null +++ b/arch/arm/lib/csumipv6.S @@ -0,0 +1,32 @@ +/* + * linux/arch/arm/lib/csumipv6.S + * + * Copyright (C) 1995-1998 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/linkage.h> +#include <asm/assembler.h> + + .text + +ENTRY(__csum_ipv6_magic) + str lr, [sp, #-4]! + adds ip, r2, r3 + ldmia r1, {r1 - r3, lr} + adcs ip, ip, r1 + adcs ip, ip, r2 + adcs ip, ip, r3 + adcs ip, ip, lr + ldmia r0, {r0 - r3} + adcs r0, ip, r0 + adcs r0, r0, r1 + adcs r0, r0, r2 + ldr r2, [sp, #4] + adcs r0, r0, r3 + adcs r0, r0, r2 + adcs r0, r0, #0 + LOADREGS(fd, sp!, {pc}) + diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S new file mode 100644 index 0000000..cb5e370 --- /dev/null +++ b/arch/arm/lib/csumpartial.S @@ -0,0 +1,137 @@ +/* + * linux/arch/arm/lib/csumpartial.S + * + * Copyright (C) 1995-1998 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/linkage.h> +#include <asm/assembler.h> + + .text + +/* + * Function: __u32 csum_partial(const char *src, int len, __u32 sum) + * Params : r0 = buffer, r1 = len, r2 = checksum + * Returns : r0 = new checksum + */ + +buf .req r0 +len .req r1 +sum .req r2 +td0 .req r3 +td1 .req r4 @ save before use +td2 .req r5 @ save before use +td3 .req lr + +.zero: mov r0, sum + add sp, sp, #4 + ldr pc, [sp], #4 + + /* + * Handle 0 to 7 bytes, with any alignment of source and + * destination pointers. Note that when we get here, C = 0 + */ +.less8: teq len, #0 @ check for zero count + beq .zero + + /* we must have at least one byte. */ + tst buf, #1 @ odd address? + ldrneb td0, [buf], #1 + subne len, len, #1 + adcnes sum, sum, td0, put_byte_1 + +.less4: tst len, #6 + beq .less8_byte + + /* we are now half-word aligned */ + +.less8_wordlp: +#if __LINUX_ARM_ARCH__ >= 4 + ldrh td0, [buf], #2 + sub len, len, #2 +#else + ldrb td0, [buf], #1 + ldrb td3, [buf], #1 + sub len, len, #2 +#ifndef __ARMEB__ + orr td0, td0, td3, lsl #8 +#else + orr td0, td3, td0, lsl #8 +#endif +#endif + adcs sum, sum, td0 + tst len, #6 + bne .less8_wordlp + +.less8_byte: tst len, #1 @ odd number of bytes + ldrneb td0, [buf], #1 @ include last byte + adcnes sum, sum, td0, put_byte_0 @ update checksum + +.done: adc r0, sum, #0 @ collect up the last carry + ldr td0, [sp], #4 + tst td0, #1 @ check buffer alignment + movne r0, r0, ror #8 @ rotate checksum by 8 bits + ldr pc, [sp], #4 @ return + +.not_aligned: tst buf, #1 @ odd address + ldrneb td0, [buf], #1 @ make even + subne len, len, #1 + adcnes sum, sum, td0, put_byte_1 @ update checksum + + tst buf, #2 @ 32-bit aligned? +#if __LINUX_ARM_ARCH__ >= 4 + ldrneh td0, [buf], #2 @ make 32-bit aligned + subne len, len, #2 +#else + ldrneb td0, [buf], #1 + ldrneb ip, [buf], #1 + subne len, len, #2 +#ifndef __ARMEB__ + orrne td0, td0, ip, lsl #8 +#else + orrne td0, ip, td0, lsl #8 +#endif +#endif + adcnes sum, sum, td0 @ update checksum + mov pc, lr + +ENTRY(csum_partial) + stmfd sp!, {buf, lr} + cmp len, #8 @ Ensure that we have at least + blo .less8 @ 8 bytes to copy. + + adds sum, sum, #0 @ C = 0 + tst buf, #3 @ Test destination alignment + blne .not_aligned @ aligh destination, return here + +1: bics ip, len, #31 + beq 3f + + stmfd sp!, {r4 - r5} +2: ldmia buf!, {td0, td1, td2, td3} + adcs sum, sum, td0 + adcs sum, sum, td1 + adcs sum, sum, td2 + adcs sum, sum, td3 + ldmia buf!, {td0, td1, td2, td3} + adcs sum, sum, td0 + adcs sum, sum, td1 + adcs sum, sum, td2 + adcs sum, sum, td3 + sub ip, ip, #32 + teq ip, #0 + bne 2b + ldmfd sp!, {r4 - r5} + +3: tst len, #0x1c @ should not change C + beq .less4 + +4: ldr td0, [buf], #4 + sub len, len, #4 + adcs sum, sum, td0 + tst len, #0x1c + bne 4b + b .less4 diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S new file mode 100644 index 0000000..990ee63 --- /dev/null +++ b/arch/arm/lib/csumpartialcopy.S @@ -0,0 +1,52 @@ +/* + * linux/arch/arm/lib/csumpartialcopy.S + * + * Copyright (C) 1995-1998 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/linkage.h> +#include <asm/assembler.h> + + .text + +/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len, __u32 sum) + * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum + * Returns : r0 = new checksum + */ + + .macro save_regs + stmfd sp!, {r1, r4 - r8, fp, ip, lr, pc} + .endm + + .macro load_regs,flags + LOADREGS(\flags,fp,{r1, r4 - r8, fp, sp, pc}) + .endm + + .macro load1b, reg1 + ldrb \reg1, [r0], #1 + .endm + + .macro load2b, reg1, reg2 + ldrb \reg1, [r0], #1 + ldrb \reg2, [r0], #1 + .endm + + .macro load1l, reg1 + ldr \reg1, [r0], #4 + .endm + + .macro load2l, reg1, reg2 + ldr \reg1, [r0], #4 + ldr \reg2, [r0], #4 + .endm + + .macro load4l, reg1, reg2, reg3, reg4 + ldmia r0!, {\reg1, \reg2, \reg3, \reg4} + .endm + +#define FN_ENTRY ENTRY(csum_partial_copy_nocheck) + +#include "csumpartialcopygeneric.S" diff --git a/arch/arm/lib/csumpartialcopygeneric.S b/arch/arm/lib/csumpartialcopygeneric.S new file mode 100644 index 0000000..d3a2f46 --- /dev/null +++ b/arch/arm/lib/csumpartialcopygeneric.S @@ -0,0 +1,331 @@ +/* + * linux/arch/arm/lib/csumpartialcopygeneric.S + * + * 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. + */ + +/* + * unsigned int + * csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, ) + * r0 = src, r1 = dst, r2 = len, r3 = sum + * Returns : r0 = checksum + * + * Note that 'tst' and 'teq' preserve the carry flag. + */ + +src .req r0 +dst .req r1 +len .req r2 +sum .req r3 + +.zero: mov r0, sum + load_regs ea + + /* + * Align an unaligned destination pointer. We know that + * we have >= 8 bytes here, so we don't need to check + * the length. Note that the source pointer hasn't been + * aligned yet. + */ +.dst_unaligned: tst dst, #1 + beq .dst_16bit + + load1b ip + sub len, len, #1 + adcs sum, sum, ip, put_byte_1 @ update checksum + strb ip, [dst], #1 + tst dst, #2 + moveq pc, lr @ dst is now 32bit aligned + +.dst_16bit: load2b r8, ip + sub len, len, #2 + adcs sum, sum, r8, put_byte_0 + strb r8, [dst], #1 + adcs sum, sum, ip, put_byte_1 + strb ip, [dst], #1 + mov pc, lr @ dst is now 32bit aligned + + /* + * Handle 0 to 7 bytes, with any alignment of source and + * destination pointers. Note that when we get here, C = 0 + */ +.less8: teq len, #0 @ check for zero count + beq .zero + + /* we must have at least one byte. */ + tst dst, #1 @ dst 16-bit aligned + beq .less8_aligned + + /* Align dst */ + load1b ip + sub len, len, #1 + adcs sum, sum, ip, put_byte_1 @ update checksum + strb ip, [dst], #1 + tst len, #6 + beq .less8_byteonly + +1: load2b r8, ip + sub len, len, #2 + adcs sum, sum, r8, put_byte_0 + strb r8, [dst], #1 + adcs sum, sum, ip, put_byte_1 + strb ip, [dst], #1 +.less8_aligned: tst len, #6 + bne 1b +.less8_byteonly: + tst len, #1 + beq .done + load1b r8 + adcs sum, sum, r8, put_byte_0 @ update checksum + strb r8, [dst], #1 + b .done + +FN_ENTRY + mov ip, sp + save_regs + sub fp, ip, #4 + + cmp len, #8 @ Ensure that we have at least + blo .less8 @ 8 bytes to copy. + + adds sum, sum, #0 @ C = 0 + tst dst, #3 @ Test destination alignment + blne .dst_unaligned @ align destination, return here + + /* + * Ok, the dst pointer is now 32bit aligned, and we know + * that we must have more than 4 bytes to copy. Note + * that C contains the carry from the dst alignment above. + */ + + tst src, #3 @ Test source alignment + bne .src_not_aligned + + /* Routine for src & dst aligned */ + + bics ip, len, #15 + beq 2f + +1: load4l r4, r5, r6, r7 + stmia dst!, {r4, r5, r6, r7} + adcs sum, sum, r4 + adcs sum, sum, r5 + adcs sum, sum, r6 + adcs sum, sum, r7 + sub ip, ip, #16 + teq ip, #0 + bne 1b + +2: ands ip, len, #12 + beq 4f + tst ip, #8 + beq 3f + load2l r4, r5 + stmia dst!, {r4, r5} + adcs sum, sum, r4 + adcs sum, sum, r5 + tst ip, #4 + beq 4f + +3: load1l r4 + str r4, [dst], #4 + adcs sum, sum, r4 + +4: ands len, len, #3 + beq .done + load1l r4 + tst len, #2 + mov r5, r4, get_byte_0 + beq .exit + adcs sum, sum, r4, push #16 + strb r5, [dst], #1 + mov r5, r4, get_byte_1 + strb r5, [dst], #1 + mov r5, r4, get_byte_2 +.exit: tst len, #1 + strneb r5, [dst], #1 + andne r5, r5, #255 + adcnes sum, sum, r5, put_byte_0 + + /* + * If the dst pointer was not 16-bit aligned, we + * need to rotate the checksum here to get around + * the inefficient byte manipulations in the + * architecture independent code. + */ +.done: adc r0, sum, #0 + ldr sum, [sp, #0] @ dst + tst sum, #1 + movne r0, r0, ror #8 + load_regs ea + +.src_not_aligned: + adc sum, sum, #0 @ include C from dst alignment + and ip, src, #3 + bic src, src, #3 + load1l r5 + cmp ip, #2 + beq .src2_aligned + bhi .src3_aligned + mov r4, r5, pull #8 @ C = 0 + bics ip, len, #15 + beq 2f +1: load4l r5, r6, r7, r8 + orr r4, r4, r5, push #24 + mov r5, r5, pull #8 + orr r5, r5, r6, push #24 + mov r6, r6, pull #8 + orr r6, r6, r7, push #24 + mov r7, r7, pull #8 + orr r7, r7, r8, push #24 + stmia dst!, {r4, r5, r6, r7} + adcs sum, sum, r4 + adcs sum, sum, r5 + adcs sum, sum, r6 + adcs sum, sum, r7 + mov r4, r8, pull #8 + sub ip, ip, #16 + teq ip, #0 + bne 1b +2: ands ip, len, #12 + beq 4f + tst ip, #8 + beq 3f + load2l r5, r6 + orr r4, r4, r5, push #24 + mov r5, r5, pull #8 + orr r5, r5, r6, push #24 + stmia dst!, {r4, r5} + adcs sum, sum, r4 + adcs sum, sum, r5 + mov r4, r6, pull #8 + tst ip, #4 + beq 4f +3: load1l r5 + orr r4, r4, r5, push #24 + str r4, [dst], #4 + adcs sum, sum, r4 + mov r4, r5, pull #8 +4: ands len, len, #3 + beq .done + mov r5, r4, get_byte_0 + tst len, #2 + beq .exit + adcs sum, sum, r4, push #16 + strb r5, [dst], #1 + mov r5, r4, get_byte_1 + strb r5, [dst], #1 + mov r5, r4, get_byte_2 + b .exit + +.src2_aligned: mov r4, r5, pull #16 + adds sum, sum, #0 + bics ip, len, #15 + beq 2f +1: load4l r5, r6, r7, r8 + orr r4, r4, r5, push #16 + mov r5, r5, pull #16 + orr r5, r5, r6, push #16 + mov r6, r6, pull #16 + orr r6, r6, r7, push #16 + mov r7, r7, pull #16 + orr r7, r7, r8, push #16 + stmia dst!, {r4, r5, r6, r7} + adcs sum, sum, r4 + adcs sum, sum, r5 + adcs sum, sum, r6 + adcs sum, sum, r7 + mov r4, r8, pull #16 + sub ip, ip, #16 + teq ip, #0 + bne 1b +2: ands ip, len, #12 + beq 4f + tst ip, #8 + beq 3f + load2l r5, r6 + orr r4, r4, r5, push #16 + mov r5, r5, pull #16 + orr r5, r5, r6, push #16 + stmia dst!, {r4, r5} + adcs sum, sum, r4 + adcs sum, sum, r5 + mov r4, r6, pull #16 + tst ip, #4 + beq 4f +3: load1l r5 + orr r4, r4, r5, push #16 + str r4, [dst], #4 + adcs sum, sum, r4 + mov r4, r5, pull #16 +4: ands len, len, #3 + beq .done + mov r5, r4, get_byte_0 + tst len, #2 + beq .exit + adcs sum, sum, r4 + strb r5, [dst], #1 + mov r5, r4, get_byte_1 + strb r5, [dst], #1 + tst len, #1 + beq .done + load1b r5 + b .exit + +.src3_aligned: mov r4, r5, pull #24 + adds sum, sum, #0 + bics ip, len, #15 + beq 2f +1: load4l r5, r6, r7, r8 + orr r4, r4, r5, push #8 + mov r5, r5, pull #24 + orr r5, r5, r6, push #8 + mov r6, r6, pull #24 + orr r6, r6, r7, push #8 + mov r7, r7, pull #24 + orr r7, r7, r8, push #8 + stmia dst!, {r4, r5, r6, r7} + adcs sum, sum, r4 + adcs sum, sum, r5 + adcs sum, sum, r6 + adcs sum, sum, r7 + mov r4, r8, pull #24 + sub ip, ip, #16 + teq ip, #0 + bne 1b +2: ands ip, len, #12 + beq 4f + tst ip, #8 + beq 3f + load2l r5, r6 + orr r4, r4, r5, push #8 + mov r5, r5, pull #24 + orr r5, r5, r6, push #8 + stmia dst!, {r4, r5} + adcs sum, sum, r4 + adcs sum, sum, r5 + mov r4, r6, pull #24 + tst ip, #4 + beq 4f +3: load1l r5 + orr r4, r4, r5, push #8 + str r4, [dst], #4 + adcs sum, sum, r4 + mov r4, r5, pull #24 +4: ands len, len, #3 + beq .done + mov r5, r4, get_byte_0 + tst len, #2 + beq .exit + strb r5, [dst], #1 + adcs sum, sum, r4 + load1l r4 + mov r5, r4, get_byte_0 + strb r5, [dst], #1 + adcs sum, sum, r4, push #24 + mov r5, r4, get_byte_1 + b .exit diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S new file mode 100644 index 0000000..46a2dc9 --- /dev/null +++ b/arch/arm/lib/csumpartialcopyuser.S @@ -0,0 +1,104 @@ +/* + * linux/arch/arm/lib/csumpartialcopyuser.S + * + * Copyright (C) 1995-1998 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. + * + * 27/03/03 Ian Molton Clean up CONFIG_CPU + * + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/errno.h> +#include <asm/constants.h> + + .text + + .macro save_regs + stmfd sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc} + .endm + + .macro load_regs,flags + ldm\flags fp, {r1, r2, r4-r8, fp, sp, pc} + .endm + + .macro load1b, reg1 +9999: ldrbt \reg1, [r0], $1 + .section __ex_table, "a" + .align 3 + .long 9999b, 6001f + .previous + .endm + + .macro load2b, reg1, reg2 +9999: ldrbt \reg1, [r0], $1 +9998: ldrbt \reg2, [r0], $1 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .previous + .endm + + .macro load1l, reg1 +9999: ldrt \reg1, [r0], $4 + .section __ex_table, "a" + .align 3 + .long 9999b, 6001f + .previous + .endm + + .macro load2l, reg1, reg2 +9999: ldrt \reg1, [r0], $4 +9998: ldrt \reg2, [r0], $4 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .previous + .endm + + .macro load4l, reg1, reg2, reg3, reg4 +9999: ldrt \reg1, [r0], $4 +9998: ldrt \reg2, [r0], $4 +9997: ldrt \reg3, [r0], $4 +9996: ldrt \reg4, [r0], $4 + .section __ex_table, "a" + .long 9999b, 6001f + .long 9998b, 6001f + .long 9997b, 6001f + .long 9996b, 6001f + .previous + .endm + +/* + * unsigned int + * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr) + * r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr + * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT + */ + +#define FN_ENTRY ENTRY(csum_partial_copy_from_user) + +#include "csumpartialcopygeneric.S" + +/* + * FIXME: minor buglet here + * We don't return the checksum for the data present in the buffer. To do + * so properly, we would have to add in whatever registers were loaded before + * the fault, which, with the current asm above is not predictable. + */ + .section .fixup,"ax" + .align 4 +6001: mov r4, #-EFAULT + ldr r5, [fp, #4] @ *err_ptr + str r4, [r5] + ldmia sp, {r1, r2} @ retrieve dst, len + add r2, r2, r1 + mov r0, #0 @ zero the buffer +6002: teq r2, r1 + strneb r0, [r1], #1 + bne 6002b + load_regs ea + .previous diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S new file mode 100644 index 0000000..3c7f7e6 --- /dev/null +++ b/arch/arm/lib/delay.S @@ -0,0 +1,58 @@ +/* + * linux/arch/arm/lib/delay.S + * + * Copyright (C) 1995, 1996 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/linkage.h> +#include <asm/assembler.h> + .text + +LC0: .word loops_per_jiffy + +/* + * 0 <= r0 <= 2000 + */ +ENTRY(__udelay) + mov r2, #0x6800 + orr r2, r2, #0x00db + mul r0, r2, r0 +ENTRY(__const_udelay) @ 0 <= r0 <= 0x01ffffff + ldr r2, LC0 + ldr r2, [r2] @ max = 0x0fffffff + mov r0, r0, lsr #11 @ max = 0x00003fff + mov r2, r2, lsr #11 @ max = 0x0003ffff + mul r0, r2, r0 @ max = 2^32-1 + movs r0, r0, lsr #6 + RETINSTR(moveq,pc,lr) + +/* + * loops = (r0 * 0x10c6 * 100 * loops_per_jiffy) / 2^32 + * + * Oh, if only we had a cycle counter... + */ + +@ Delay routine +ENTRY(__delay) + subs r0, r0, #1 +#if 0 + RETINSTR(movls,pc,lr) + subs r0, r0, #1 + RETINSTR(movls,pc,lr) + subs r0, r0, #1 + RETINSTR(movls,pc,lr) + subs r0, r0, #1 + RETINSTR(movls,pc,lr) + subs r0, r0, #1 + RETINSTR(movls,pc,lr) + subs r0, r0, #1 + RETINSTR(movls,pc,lr) + subs r0, r0, #1 + RETINSTR(movls,pc,lr) + subs r0, r0, #1 +#endif + bhi __delay + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S new file mode 100644 index 0000000..ec9a1cd --- /dev/null +++ b/arch/arm/lib/div64.S @@ -0,0 +1,200 @@ +/* + * linux/arch/arm/lib/div64.S + * + * Optimized computation of 64-bit dividend / 32-bit divisor + * + * Author: Nicolas Pitre + * Created: Oct 5, 2003 + * Copyright: Monta Vista Software, Inc. + * + * 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/linkage.h> + +#ifdef __ARMEB__ +#define xh r0 +#define xl r1 +#define yh r2 +#define yl r3 +#else +#define xl r0 +#define xh r1 +#define yl r2 +#define yh r3 +#endif + +/* + * __do_div64: perform a division with 64-bit dividend and 32-bit divisor. + * + * Note: Calling convention is totally non standard for optimal code. + * This is meant to be used by do_div() from include/asm/div64.h only. + * + * Input parameters: + * xh-xl = dividend (clobbered) + * r4 = divisor (preserved) + * + * Output values: + * yh-yl = result + * xh = remainder + * + * Clobbered regs: xl, ip + */ + +ENTRY(__do_div64) + + @ Test for easy paths first. + subs ip, r4, #1 + bls 9f @ divisor is 0 or 1 + tst ip, r4 + beq 8f @ divisor is power of 2 + + @ See if we need to handle upper 32-bit result. + cmp xh, r4 + mov yh, #0 + blo 3f + + @ Align divisor with upper part of dividend. + @ The aligned divisor is stored in yl preserving the original. + @ The bit position is stored in ip. + +#if __LINUX_ARM_ARCH__ >= 5 + + clz yl, r4 + clz ip, xh + sub yl, yl, ip + mov ip, #1 + mov ip, ip, lsl yl + mov yl, r4, lsl yl + +#else + + mov yl, r4 + mov ip, #1 +1: cmp yl, #0x80000000 + cmpcc yl, xh + movcc yl, yl, lsl #1 + movcc ip, ip, lsl #1 + bcc 1b + +#endif + + @ The division loop for needed upper bit positions. + @ Break out early if dividend reaches 0. +2: cmp xh, yl + orrcs yh, yh, ip + subcss xh, xh, yl + movnes ip, ip, lsr #1 + mov yl, yl, lsr #1 + bne 2b + + @ See if we need to handle lower 32-bit result. +3: cmp xh, #0 + mov yl, #0 + cmpeq xl, r4 + movlo xh, xl + movlo pc, lr + + @ The division loop for lower bit positions. + @ Here we shift remainer bits leftwards rather than moving the + @ divisor for comparisons, considering the carry-out bit as well. + mov ip, #0x80000000 +4: movs xl, xl, lsl #1 + adcs xh, xh, xh + beq 6f + cmpcc xh, r4 +5: orrcs yl, yl, ip + subcs xh, xh, r4 + movs ip, ip, lsr #1 + bne 4b + mov pc, lr + + @ The top part of remainder became zero. If carry is set + @ (the 33th bit) this is a false positive so resume the loop. + @ Otherwise, if lower part is also null then we are done. +6: bcs 5b + cmp xl, #0 + moveq pc, lr + + @ We still have remainer bits in the low part. Bring them up. + +#if __LINUX_ARM_ARCH__ >= 5 + + clz xh, xl @ we know xh is zero here so... + add xh, xh, #1 + mov xl, xl, lsl xh + mov ip, ip, lsr xh + +#else + +7: movs xl, xl, lsl #1 + mov ip, ip, lsr #1 + bcc 7b + +#endif + + @ Current remainder is now 1. It is worthless to compare with + @ divisor at this point since divisor can not be smaller than 3 here. + @ If possible, branch for another shift in the division loop. + @ If no bit position left then we are done. + movs ip, ip, lsr #1 + mov xh, #1 + bne 4b + mov pc, lr + +8: @ Division by a power of 2: determine what that divisor order is + @ then simply shift values around + +#if __LINUX_ARM_ARCH__ >= 5 + + clz ip, r4 + rsb ip, ip, #31 + +#else + + mov yl, r4 + cmp r4, #(1 << 16) + mov ip, #0 + movhs yl, yl, lsr #16 + movhs ip, #16 + + cmp yl, #(1 << 8) + movhs yl, yl, lsr #8 + addhs ip, ip, #8 + + cmp yl, #(1 << 4) + movhs yl, yl, lsr #4 + addhs ip, ip, #4 + + cmp yl, #(1 << 2) + addhi ip, ip, #3 + addls ip, ip, yl, lsr #1 + +#endif + + mov yh, xh, lsr ip + mov yl, xl, lsr ip + rsb ip, ip, #32 + orr yl, yl, xh, lsl ip + mov xh, xl, lsl ip + mov xh, xh, lsr ip + mov pc, lr + + @ eq -> division by 1: obvious enough... +9: moveq yl, xl + moveq yh, xh + moveq xh, #0 + moveq pc, lr + + @ Division by 0: + str lr, [sp, #-4]! + bl __div0 + + @ as wrong as it could be... + mov yl, #0 + mov yh, #0 + mov xh, #0 + ldr pc, [sp], #4 + diff --git a/arch/arm/lib/ecard.S b/arch/arm/lib/ecard.S new file mode 100644 index 0000000..fb7b602a --- /dev/null +++ b/arch/arm/lib/ecard.S @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/lib/ecard.S + * + * Copyright (C) 1995, 1996 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. + * + * 27/03/03 Ian Molton Clean up CONFIG_CPU + * + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> + +#define CPSR2SPSR(rt) \ + mrs rt, cpsr; \ + msr spsr_cxsf, rt + +@ Purpose: call an expansion card loader to read bytes. +@ Proto : char read_loader(int offset, char *card_base, char *loader); +@ Returns: byte read + +ENTRY(ecard_loader_read) + stmfd sp!, {r4 - r12, lr} + mov r11, r1 + mov r1, r0 + CPSR2SPSR(r0) + mov lr, pc + mov pc, r2 + LOADREGS(fd, sp!, {r4 - r12, pc}) + +@ Purpose: call an expansion card loader to reset the card +@ Proto : void read_loader(int card_base, char *loader); +@ Returns: byte read + +ENTRY(ecard_loader_reset) + stmfd sp!, {r4 - r12, lr} + mov r11, r0 + CPSR2SPSR(r0) + mov lr, pc + add pc, r1, #8 + LOADREGS(fd, sp!, {r4 - r12, pc}) + diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S new file mode 100644 index 0000000..f055d56 --- /dev/null +++ b/arch/arm/lib/findbit.S @@ -0,0 +1,168 @@ +/* + * linux/arch/arm/lib/findbit.S + * + * 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. + * + * 16th March 2001 - John Ripley <jripley@sonicblue.com> + * Fixed so that "size" is an exclusive not an inclusive quantity. + * All users of these functions expect exclusive sizes, and may + * also call with zero size. + * Reworked by rmk. + */ +#include <linux/linkage.h> +#include <asm/assembler.h> + .text + +/* + * Purpose : Find a 'zero' bit + * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit); + */ +ENTRY(_find_first_zero_bit_le) + teq r1, #0 + beq 3f + mov r2, #0 +1: ldrb r3, [r0, r2, lsr #3] + eors r3, r3, #0xff @ invert bits + bne .found @ any now set - found zero bit + add r2, r2, #8 @ next bit pointer +2: cmp r2, r1 @ any more? + blo 1b +3: mov r0, r1 @ no free bits + RETINSTR(mov,pc,lr) + +/* + * Purpose : Find next 'zero' bit + * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) + */ +ENTRY(_find_next_zero_bit_le) + teq r1, #0 + beq 3b + ands ip, r2, #7 + beq 1b @ If new byte, goto old routine + ldrb r3, [r0, r2, lsr #3] + eor r3, r3, #0xff @ now looking for a 1 bit + movs r3, r3, lsr ip @ shift off unused bits + bne .found + orr r2, r2, #7 @ if zero, then no bits here + add r2, r2, #1 @ align bit pointer + b 2b @ loop for next bit + +/* + * Purpose : Find a 'one' bit + * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit); + */ +ENTRY(_find_first_bit_le) + teq r1, #0 + beq 3f + mov r2, #0 +1: ldrb r3, [r0, r2, lsr #3] + movs r3, r3 + bne .found @ any now set - found zero bit + add r2, r2, #8 @ next bit pointer +2: cmp r2, r1 @ any more? + blo 1b +3: mov r0, r1 @ no free bits + RETINSTR(mov,pc,lr) + +/* + * Purpose : Find next 'one' bit + * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) + */ +ENTRY(_find_next_bit_le) + teq r1, #0 + beq 3b + ands ip, r2, #7 + beq 1b @ If new byte, goto old routine + ldrb r3, [r0, r2, lsr #3] + movs r3, r3, lsr ip @ shift off unused bits + bne .found + orr r2, r2, #7 @ if zero, then no bits here + add r2, r2, #1 @ align bit pointer + b 2b @ loop for next bit + +#ifdef __ARMEB__ + +ENTRY(_find_first_zero_bit_be) + teq r1, #0 + beq 3f + mov r2, #0 +1: eor r3, r2, #0x18 @ big endian byte ordering + ldrb r3, [r0, r3, lsr #3] + eors r3, r3, #0xff @ invert bits + bne .found @ any now set - found zero bit + add r2, r2, #8 @ next bit pointer +2: cmp r2, r1 @ any more? + blo 1b +3: mov r0, r1 @ no free bits + RETINSTR(mov,pc,lr) + +ENTRY(_find_next_zero_bit_be) + teq r1, #0 + beq 3b + ands ip, r2, #7 + beq 1b @ If new byte, goto old routine + eor r3, r2, #0x18 @ big endian byte ordering + ldrb r3, [r0, r3, lsr #3] + eor r3, r3, #0xff @ now looking for a 1 bit + movs r3, r3, lsr ip @ shift off unused bits + bne .found + orr r2, r2, #7 @ if zero, then no bits here + add r2, r2, #1 @ align bit pointer + b 2b @ loop for next bit + +ENTRY(_find_first_bit_be) + teq r1, #0 + beq 3f + mov r2, #0 +1: eor r3, r2, #0x18 @ big endian byte ordering + ldrb r3, [r0, r3, lsr #3] + movs r3, r3 + bne .found @ any now set - found zero bit + add r2, r2, #8 @ next bit pointer +2: cmp r2, r1 @ any more? + blo 1b +3: mov r0, r1 @ no free bits + RETINSTR(mov,pc,lr) + +ENTRY(_find_next_bit_be) + teq r1, #0 + beq 3b + ands ip, r2, #7 + beq 1b @ If new byte, goto old routine + eor r3, r2, #0x18 @ big endian byte ordering + ldrb r3, [r0, r3, lsr #3] + movs r3, r3, lsr ip @ shift off unused bits + bne .found + orr r2, r2, #7 @ if zero, then no bits here + add r2, r2, #1 @ align bit pointer + b 2b @ loop for next bit + +#endif + +/* + * One or more bits in the LSB of r3 are assumed to be set. + */ +.found: +#if __LINUX_ARM_ARCH__ >= 5 + rsb r1, r3, #0 + and r3, r3, r1 + clz r3, r3 + rsb r3, r3, #31 + add r0, r2, r3 +#else + tst r3, #0x0f + addeq r2, r2, #4 + movne r3, r3, lsl #4 + tst r3, #0x30 + addeq r2, r2, #2 + movne r3, r3, lsl #2 + tst r3, #0x40 + addeq r2, r2, #1 + mov r0, r2 +#endif + RETINSTR(mov,pc,lr) + diff --git a/arch/arm/lib/floppydma.S b/arch/arm/lib/floppydma.S new file mode 100644 index 0000000..617150b --- /dev/null +++ b/arch/arm/lib/floppydma.S @@ -0,0 +1,32 @@ +/* + * linux/arch/arm/lib/floppydma.S + * + * Copyright (C) 1995, 1996 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/linkage.h> +#include <asm/assembler.h> + .text + + .global floppy_fiqin_end +ENTRY(floppy_fiqin_start) + subs r9, r9, #1 + ldrgtb r12, [r11, #-4] + ldrleb r12, [r11], #0 + strb r12, [r10], #1 + subs pc, lr, #4 +floppy_fiqin_end: + + .global floppy_fiqout_end +ENTRY(floppy_fiqout_start) + subs r9, r9, #1 + ldrgeb r12, [r10], #1 + movlt r12, #0 + strleb r12, [r11], #0 + subles pc, lr, #4 + strb r12, [r11, #-4] + subs pc, lr, #4 +floppy_fiqout_end: diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h new file mode 100644 index 0000000..65314a3 --- /dev/null +++ b/arch/arm/lib/gcclib.h @@ -0,0 +1,25 @@ +/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#define BITS_PER_UNIT 8 +#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT) + +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); + +#ifdef __ARMEB__ + struct DIstruct {SItype high, low;}; +#else + struct DIstruct {SItype low, high;}; +#endif + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S new file mode 100644 index 0000000..64aa6f4 --- /dev/null +++ b/arch/arm/lib/getuser.S @@ -0,0 +1,78 @@ +/* + * linux/arch/arm/lib/getuser.S + * + * Copyright (C) 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. + * + * Idea from x86 version, (C) Copyright 1998 Linus Torvalds + * + * These functions have a non-standard call interface to make them more + * efficient, especially as they return an error value in addition to + * the "real" return value. + * + * __get_user_X + * + * Inputs: r0 contains the address + * Outputs: r0 is the error code + * r2, r3 contains the zero-extended value + * lr corrupted + * + * No other registers must be altered. (see include/asm-arm/uaccess.h + * for specific ASM register usage). + * + * Note that ADDR_LIMIT is either 0 or 0xc0000000. + * Note also that it is intended that __get_user_bad is not global. + */ +#include <asm/constants.h> +#include <asm/thread_info.h> +#include <asm/errno.h> + + .global __get_user_1 +__get_user_1: +1: ldrbt r2, [r0] + mov r0, #0 + mov pc, lr + + .global __get_user_2 +__get_user_2: +2: ldrbt r2, [r0], #1 +3: ldrbt r3, [r0] +#ifndef __ARMEB__ + orr r2, r2, r3, lsl #8 +#else + orr r2, r3, r2, lsl #8 +#endif + mov r0, #0 + mov pc, lr + + .global __get_user_4 +__get_user_4: +4: ldrt r2, [r0] + mov r0, #0 + mov pc, lr + + .global __get_user_8 +__get_user_8: +5: ldrt r2, [r0], #4 +6: ldrt r3, [r0] + mov r0, #0 + mov pc, lr + +__get_user_bad_8: + mov r3, #0 +__get_user_bad: + mov r2, #0 + mov r0, #-EFAULT + mov pc, lr + +.section __ex_table, "a" + .long 1b, __get_user_bad + .long 2b, __get_user_bad + .long 3b, __get_user_bad + .long 4b, __get_user_bad + .long 5b, __get_user_bad_8 + .long 6b, __get_user_bad_8 +.previous diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S new file mode 100644 index 0000000..3aacd01 --- /dev/null +++ b/arch/arm/lib/io-acorn.S @@ -0,0 +1,32 @@ +/* + * linux/arch/arm/lib/io-acorn.S + * + * Copyright (C) 1995, 1996 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. + * + * 27/03/03 Ian Molton Clean up CONFIG_CPU + * + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> + + .text + .align + +.iosl_warning: + .ascii "<4>insl/outsl not implemented, called from %08lX\0" + .align + +/* + * These make no sense on Acorn machines. + * Print a warning message. + */ +ENTRY(insl) +ENTRY(outsl) + adr r0, .iosl_warning + mov r1, lr + b printk diff --git a/arch/arm/lib/io-readsb.S b/arch/arm/lib/io-readsb.S new file mode 100644 index 0000000..081ef74 --- /dev/null +++ b/arch/arm/lib/io-readsb.S @@ -0,0 +1,122 @@ +/* + * linux/arch/arm/lib/io-readsb.S + * + * 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/linkage.h> +#include <asm/assembler.h> + +.insb_align: rsb ip, ip, #4 + cmp ip, r2 + movgt ip, r2 + cmp ip, #2 + ldrb r3, [r0] + strb r3, [r1], #1 + ldrgeb r3, [r0] + strgeb r3, [r1], #1 + ldrgtb r3, [r0] + strgtb r3, [r1], #1 + subs r2, r2, ip + bne .insb_aligned + +ENTRY(__raw_readsb) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + ands ip, r1, #3 + bne .insb_align + +.insb_aligned: stmfd sp!, {r4 - r6, lr} + + subs r2, r2, #16 + bmi .insb_no_16 + +.insb_16_lp: ldrb r3, [r0] + ldrb r4, [r0] + ldrb r5, [r0] + mov r3, r3, put_byte_0 + ldrb r6, [r0] + orr r3, r3, r4, put_byte_1 + ldrb r4, [r0] + orr r3, r3, r5, put_byte_2 + ldrb r5, [r0] + orr r3, r3, r6, put_byte_3 + ldrb r6, [r0] + mov r4, r4, put_byte_0 + ldrb ip, [r0] + orr r4, r4, r5, put_byte_1 + ldrb r5, [r0] + orr r4, r4, r6, put_byte_2 + ldrb r6, [r0] + orr r4, r4, ip, put_byte_3 + ldrb ip, [r0] + mov r5, r5, put_byte_0 + ldrb lr, [r0] + orr r5, r5, r6, put_byte_1 + ldrb r6, [r0] + orr r5, r5, ip, put_byte_2 + ldrb ip, [r0] + orr r5, r5, lr, put_byte_3 + ldrb lr, [r0] + mov r6, r6, put_byte_0 + orr r6, r6, ip, put_byte_1 + ldrb ip, [r0] + orr r6, r6, lr, put_byte_2 + orr r6, r6, ip, put_byte_3 + stmia r1!, {r3 - r6} + + subs r2, r2, #16 + bpl .insb_16_lp + + tst r2, #15 + LOADREGS(eqfd, sp!, {r4 - r6, pc}) + +.insb_no_16: tst r2, #8 + beq .insb_no_8 + + ldrb r3, [r0] + ldrb r4, [r0] + ldrb r5, [r0] + mov r3, r3, put_byte_0 + ldrb r6, [r0] + orr r3, r3, r4, put_byte_1 + ldrb r4, [r0] + orr r3, r3, r5, put_byte_2 + ldrb r5, [r0] + orr r3, r3, r6, put_byte_3 + ldrb r6, [r0] + mov r4, r4, put_byte_0 + ldrb ip, [r0] + orr r4, r4, r5, put_byte_1 + orr r4, r4, r6, put_byte_2 + orr r4, r4, ip, put_byte_3 + stmia r1!, {r3, r4} + +.insb_no_8: tst r2, #4 + beq .insb_no_4 + + ldrb r3, [r0] + ldrb r4, [r0] + ldrb r5, [r0] + ldrb r6, [r0] + mov r3, r3, put_byte_0 + orr r3, r3, r4, put_byte_1 + orr r3, r3, r5, put_byte_2 + orr r3, r3, r6, put_byte_3 + str r3, [r1], #4 + +.insb_no_4: ands r2, r2, #3 + LOADREGS(eqfd, sp!, {r4 - r6, pc}) + + cmp r2, #2 + ldrb r3, [r0] + strb r3, [r1], #1 + ldrgeb r3, [r0] + strgeb r3, [r1], #1 + ldrgtb r3, [r0] + strgtb r3, [r1] + + LOADREGS(fd, sp!, {r4 - r6, pc}) diff --git a/arch/arm/lib/io-readsl.S b/arch/arm/lib/io-readsl.S new file mode 100644 index 0000000..75a9121 --- /dev/null +++ b/arch/arm/lib/io-readsl.S @@ -0,0 +1,78 @@ +/* + * linux/arch/arm/lib/io-readsl.S + * + * 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/linkage.h> +#include <asm/assembler.h> + +ENTRY(__raw_readsl) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + ands ip, r1, #3 + bne 3f + + subs r2, r2, #4 + bmi 2f + stmfd sp!, {r4, lr} +1: ldr r3, [r0, #0] + ldr r4, [r0, #0] + ldr ip, [r0, #0] + ldr lr, [r0, #0] + subs r2, r2, #4 + stmia r1!, {r3, r4, ip, lr} + bpl 1b + ldmfd sp!, {r4, lr} +2: movs r2, r2, lsl #31 + ldrcs r3, [r0, #0] + ldrcs ip, [r0, #0] + stmcsia r1!, {r3, ip} + ldrne r3, [r0, #0] + strne r3, [r1, #0] + mov pc, lr + +3: ldr r3, [r0] + cmp ip, #2 + mov ip, r3, get_byte_0 + strb ip, [r1], #1 + bgt 6f + mov ip, r3, get_byte_1 + strb ip, [r1], #1 + beq 5f + mov ip, r3, get_byte_2 + strb ip, [r1], #1 + +4: subs r2, r2, #1 + mov ip, r3, pull #24 + ldrne r3, [r0] + orrne ip, ip, r3, push #8 + strne ip, [r1], #4 + bne 4b + b 8f + +5: subs r2, r2, #1 + mov ip, r3, pull #16 + ldrne r3, [r0] + orrne ip, ip, r3, push #16 + strne ip, [r1], #4 + bne 5b + b 7f + +6: subs r2, r2, #1 + mov ip, r3, pull #8 + ldrne r3, [r0] + orrne ip, ip, r3, push #24 + strne ip, [r1], #4 + bne 6b + + mov r3, ip, get_byte_2 + strb r3, [r1, #2] +7: mov r3, ip, get_byte_1 + strb r3, [r1, #1] +8: mov r3, ip, get_byte_0 + strb r3, [r1, #0] + mov pc, lr diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S new file mode 100644 index 0000000..476cf7f --- /dev/null +++ b/arch/arm/lib/io-readsw-armv3.S @@ -0,0 +1,107 @@ +/* + * linux/arch/arm/lib/io-readsw-armv3.S + * + * 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/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> + +.insw_bad_alignment: + adr r0, .insw_bad_align_msg + mov r2, lr + b panic +.insw_bad_align_msg: + .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n" + .align + +.insw_align: tst r1, #1 + bne .insw_bad_alignment + + ldr r3, [r0] + strb r3, [r1], #1 + mov r3, r3, lsr #8 + strb r3, [r1], #1 + + subs r2, r2, #1 + RETINSTR(moveq, pc, lr) + +ENTRY(__raw_readsw) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + tst r1, #3 + bne .insw_align + +.insw_aligned: mov ip, #0xff + orr ip, ip, ip, lsl #8 + stmfd sp!, {r4, r5, r6, lr} + + subs r2, r2, #8 + bmi .no_insw_8 + +.insw_8_lp: ldr r3, [r0] + and r3, r3, ip + ldr r4, [r0] + orr r3, r3, r4, lsl #16 + + ldr r4, [r0] + and r4, r4, ip + ldr r5, [r0] + orr r4, r4, r5, lsl #16 + + ldr r5, [r0] + and r5, r5, ip + ldr r6, [r0] + orr r5, r5, r6, lsl #16 + + ldr r6, [r0] + and r6, r6, ip + ldr lr, [r0] + orr r6, r6, lr, lsl #16 + + stmia r1!, {r3 - r6} + + subs r2, r2, #8 + bpl .insw_8_lp + + tst r2, #7 + LOADREGS(eqfd, sp!, {r4, r5, r6, pc}) + +.no_insw_8: tst r2, #4 + beq .no_insw_4 + + ldr r3, [r0] + and r3, r3, ip + ldr r4, [r0] + orr r3, r3, r4, lsl #16 + + ldr r4, [r0] + and r4, r4, ip + ldr r5, [r0] + orr r4, r4, r5, lsl #16 + + stmia r1!, {r3, r4} + +.no_insw_4: tst r2, #2 + beq .no_insw_2 + + ldr r3, [r0] + and r3, r3, ip + ldr r4, [r0] + orr r3, r3, r4, lsl #16 + + str r3, [r1], #4 + +.no_insw_2: tst r2, #1 + ldrne r3, [r0] + strneb r3, [r1], #1 + movne r3, r3, lsr #8 + strneb r3, [r1] + + LOADREGS(fd, sp!, {r4, r5, r6, pc}) + + diff --git a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib/io-readsw-armv4.S new file mode 100644 index 0000000..c92b66e --- /dev/null +++ b/arch/arm/lib/io-readsw-armv4.S @@ -0,0 +1,130 @@ +/* + * linux/arch/arm/lib/io-readsw-armv4.S + * + * 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/linkage.h> +#include <asm/assembler.h> + + .macro pack, rd, hw1, hw2 +#ifndef __ARMEB__ + orr \rd, \hw1, \hw2, lsl #16 +#else + orr \rd, \hw2, \hw1, lsl #16 +#endif + .endm + +.insw_align: movs ip, r1, lsl #31 + bne .insw_noalign + ldrh ip, [r0] + sub r2, r2, #1 + strh ip, [r1], #2 + +ENTRY(__raw_readsw) + teq r2, #0 + moveq pc, lr + tst r1, #3 + bne .insw_align + + stmfd sp!, {r4, r5, lr} + + subs r2, r2, #8 + bmi .no_insw_8 + +.insw_8_lp: ldrh r3, [r0] + ldrh r4, [r0] + pack r3, r3, r4 + + ldrh r4, [r0] + ldrh r5, [r0] + pack r4, r4, r5 + + ldrh r5, [r0] + ldrh ip, [r0] + pack r5, r5, ip + + ldrh ip, [r0] + ldrh lr, [r0] + pack ip, ip, lr + + subs r2, r2, #8 + stmia r1!, {r3 - r5, ip} + bpl .insw_8_lp + +.no_insw_8: tst r2, #4 + beq .no_insw_4 + + ldrh r3, [r0] + ldrh r4, [r0] + pack r3, r3, r4 + + ldrh r4, [r0] + ldrh ip, [r0] + pack r4, r4, ip + + stmia r1!, {r3, r4} + +.no_insw_4: movs r2, r2, lsl #31 + bcc .no_insw_2 + + ldrh r3, [r0] + ldrh ip, [r0] + pack r3, r3, ip + str r3, [r1], #4 + +.no_insw_2: ldrneh r3, [r0] + strneh r3, [r1] + + ldmfd sp!, {r4, r5, pc} + +#ifdef __ARMEB__ +#define _BE_ONLY_(code...) code +#define _LE_ONLY_(code...) +#define push_hbyte0 lsr #8 +#define pull_hbyte1 lsl #24 +#else +#define _BE_ONLY_(code...) +#define _LE_ONLY_(code...) code +#define push_hbyte0 lsl #24 +#define pull_hbyte1 lsr #8 +#endif + +.insw_noalign: stmfd sp!, {r4, lr} + ldrccb ip, [r1, #-1]! + bcc 1f + + ldrh ip, [r0] + sub r2, r2, #1 + _BE_ONLY_( mov ip, ip, ror #8 ) + strb ip, [r1], #1 + _LE_ONLY_( mov ip, ip, lsr #8 ) + _BE_ONLY_( mov ip, ip, lsr #24 ) + +1: subs r2, r2, #2 + bmi 3f + _BE_ONLY_( mov ip, ip, lsl #24 ) + +2: ldrh r3, [r0] + ldrh r4, [r0] + subs r2, r2, #2 + orr ip, ip, r3, lsl #8 + orr ip, ip, r4, push_hbyte0 + str ip, [r1], #4 + mov ip, r4, pull_hbyte1 + bpl 2b + + _BE_ONLY_( mov ip, ip, lsr #24 ) + +3: tst r2, #1 + strb ip, [r1], #1 + ldrneh ip, [r0] + _BE_ONLY_( movne ip, ip, ror #8 ) + strneb ip, [r1], #1 + _LE_ONLY_( movne ip, ip, lsr #8 ) + _BE_ONLY_( movne ip, ip, lsr #24 ) + strneb ip, [r1] + ldmfd sp!, {r4, pc} diff --git a/arch/arm/lib/io-shark.c b/arch/arm/lib/io-shark.c new file mode 100644 index 0000000..108d457 --- /dev/null +++ b/arch/arm/lib/io-shark.c @@ -0,0 +1,83 @@ +/* + * linux/arch/arm/lib/io-shark.c + * + * by Alexander Schulz + * + * derived from: + * linux/arch/arm/lib/io-ebsa.S + * Copyright (C) 1995, 1996 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/kernel.h> + +#include <asm/io.h> + +void print_warning(void) +{ + printk(KERN_WARNING "ins?/outs? not implemented on this architecture\n"); +} + +void insl(unsigned int port, void *to, int len) +{ + print_warning(); +} + +void insb(unsigned int port, void *to, int len) +{ + print_warning(); +} + +void outsl(unsigned int port, const void *from, int len) +{ + print_warning(); +} + +void outsb(unsigned int port, const void *from, int len) +{ + print_warning(); +} + +/* these should be in assembler again */ + +/* + * Purpose: read a block of data from a hardware register to memory. + * Proto : insw(int from_port, void *to, int len_in_words); + * Proto : inswb(int from_port, void *to, int len_in_bytes); + * Notes : increment to + */ + +void insw(unsigned int port, void *to, int len) +{ + int i; + + for (i = 0; i < len; i++) + ((unsigned short *) to)[i] = inw(port); +} + +void inswb(unsigned int port, void *to, int len) +{ + insw(port, to, len >> 2); +} + +/* + * Purpose: write a block of data from memory to a hardware register. + * Proto : outsw(int to_reg, void *from, int len_in_words); + * Proto : outswb(int to_reg, void *from, int len_in_bytes); + * Notes : increments from + */ + +void outsw(unsigned int port, const void *from, int len) +{ + int i; + + for (i = 0; i < len; i++) + outw(((unsigned short *) from)[i], port); +} + +void outswb(unsigned int port, const void *from, int len) +{ + outsw(port, from, len >> 2); +} diff --git a/arch/arm/lib/io-writesb.S b/arch/arm/lib/io-writesb.S new file mode 100644 index 0000000..70b2561 --- /dev/null +++ b/arch/arm/lib/io-writesb.S @@ -0,0 +1,92 @@ +/* + * linux/arch/arm/lib/io-writesb.S + * + * 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/linkage.h> +#include <asm/assembler.h> + + .macro outword, rd +#ifndef __ARMEB__ + strb \rd, [r0] + mov \rd, \rd, lsr #8 + strb \rd, [r0] + mov \rd, \rd, lsr #8 + strb \rd, [r0] + mov \rd, \rd, lsr #8 + strb \rd, [r0] +#else + mov lr, \rd, lsr #24 + strb lr, [r0] + mov lr, \rd, lsr #16 + strb lr, [r0] + mov lr, \rd, lsr #8 + strb lr, [r0] + strb \rd, [r0] +#endif + .endm + +.outsb_align: rsb ip, ip, #4 + cmp ip, r2 + movgt ip, r2 + cmp ip, #2 + ldrb r3, [r1], #1 + strb r3, [r0] + ldrgeb r3, [r1], #1 + strgeb r3, [r0] + ldrgtb r3, [r1], #1 + strgtb r3, [r0] + subs r2, r2, ip + bne .outsb_aligned + +ENTRY(__raw_writesb) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + ands ip, r1, #3 + bne .outsb_align + +.outsb_aligned: stmfd sp!, {r4, r5, lr} + + subs r2, r2, #16 + bmi .outsb_no_16 + +.outsb_16_lp: ldmia r1!, {r3, r4, r5, ip} + outword r3 + outword r4 + outword r5 + outword ip + subs r2, r2, #16 + bpl .outsb_16_lp + + tst r2, #15 + LOADREGS(eqfd, sp!, {r4, r5, pc}) + +.outsb_no_16: tst r2, #8 + beq .outsb_no_8 + + ldmia r1!, {r3, r4} + outword r3 + outword r4 + +.outsb_no_8: tst r2, #4 + beq .outsb_no_4 + + ldr r3, [r1], #4 + outword r3 + +.outsb_no_4: ands r2, r2, #3 + LOADREGS(eqfd, sp!, {r4, r5, pc}) + + cmp r2, #2 + ldrb r3, [r1], #1 + strb r3, [r0] + ldrgeb r3, [r1], #1 + strgeb r3, [r0] + ldrgtb r3, [r1] + strgtb r3, [r0] + + LOADREGS(fd, sp!, {r4, r5, pc}) diff --git a/arch/arm/lib/io-writesl.S b/arch/arm/lib/io-writesl.S new file mode 100644 index 0000000..f8f14dd --- /dev/null +++ b/arch/arm/lib/io-writesl.S @@ -0,0 +1,66 @@ +/* + * linux/arch/arm/lib/io-writesl.S + * + * 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/linkage.h> +#include <asm/assembler.h> + +ENTRY(__raw_writesl) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + ands ip, r1, #3 + bne 3f + + subs r2, r2, #4 + bmi 2f + stmfd sp!, {r4, lr} +1: ldmia r1!, {r3, r4, ip, lr} + subs r2, r2, #4 + str r3, [r0, #0] + str r4, [r0, #0] + str ip, [r0, #0] + str lr, [r0, #0] + bpl 1b + ldmfd sp!, {r4, lr} +2: movs r2, r2, lsl #31 + ldmcsia r1!, {r3, ip} + strcs r3, [r0, #0] + ldrne r3, [r1, #0] + strcs ip, [r0, #0] + strne r3, [r0, #0] + mov pc, lr + +3: bic r1, r1, #3 + ldr r3, [r1], #4 + cmp ip, #2 + blt 5f + bgt 6f + +4: mov ip, r3, pull #16 + ldr r3, [r1], #4 + subs r2, r2, #1 + orr ip, ip, r3, push #16 + str ip, [r0] + bne 4b + mov pc, lr + +5: mov ip, r3, pull #8 + ldr r3, [r1], #4 + subs r2, r2, #1 + orr ip, ip, r3, push #24 + str ip, [r0] + bne 5b + mov pc, lr + +6: mov ip, r3, pull #24 + ldr r3, [r1], #4 + subs r2, r2, #1 + orr ip, ip, r3, push #8 + str ip, [r0] + bne 6b + mov pc, lr diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S new file mode 100644 index 0000000..950e7e3 --- /dev/null +++ b/arch/arm/lib/io-writesw-armv3.S @@ -0,0 +1,127 @@ +/* + * linux/arch/arm/lib/io-writesw-armv3.S + * + * 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/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> + +.outsw_bad_alignment: + adr r0, .outsw_bad_align_msg + mov r2, lr + b panic +.outsw_bad_align_msg: + .asciz "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n" + .align + +.outsw_align: tst r1, #1 + bne .outsw_bad_alignment + + add r1, r1, #2 + + ldr r3, [r1, #-4] + mov r3, r3, lsr #16 + orr r3, r3, r3, lsl #16 + str r3, [r0] + subs r2, r2, #1 + RETINSTR(moveq, pc, lr) + +ENTRY(__raw_writesw) + teq r2, #0 @ do we have to check for the zero len? + moveq pc, lr + tst r1, #3 + bne .outsw_align + +.outsw_aligned: stmfd sp!, {r4, r5, r6, lr} + + subs r2, r2, #8 + bmi .no_outsw_8 + +.outsw_8_lp: ldmia r1!, {r3, r4, r5, r6} + + mov ip, r3, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r3, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + mov ip, r4, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r4, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + mov ip, r5, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r5, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + mov ip, r6, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r6, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + subs r2, r2, #8 + bpl .outsw_8_lp + + tst r2, #7 + LOADREGS(eqfd, sp!, {r4, r5, r6, pc}) + +.no_outsw_8: tst r2, #4 + beq .no_outsw_4 + + ldmia r1!, {r3, r4} + + mov ip, r3, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r3, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + + mov ip, r4, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r4, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + +.no_outsw_4: tst r2, #2 + beq .no_outsw_2 + + ldr r3, [r1], #4 + + mov ip, r3, lsl #16 + orr ip, ip, ip, lsr #16 + str ip, [r0] + + mov ip, r3, lsr #16 + orr ip, ip, ip, lsl #16 + str ip, [r0] + +.no_outsw_2: tst r2, #1 + + ldrne r3, [r1] + + movne ip, r3, lsl #16 + orrne ip, ip, ip, lsr #16 + strne ip, [r0] + + LOADREGS(fd, sp!, {r4, r5, r6, pc}) diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S new file mode 100644 index 0000000..6d1d7c2 --- /dev/null +++ b/arch/arm/lib/io-writesw-armv4.S @@ -0,0 +1,95 @@ +/* + * linux/arch/arm/lib/io-writesw-armv4.S + * + * 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/linkage.h> +#include <asm/assembler.h> + + .macro outword, rd +#ifndef __ARMEB__ + strh \rd, [r0] + mov \rd, \rd, lsr #16 + strh \rd, [r0] +#else + mov lr, \rd, lsr #16 + strh lr, [r0] + strh \rd, [r0] +#endif + .endm + +.outsw_align: movs ip, r1, lsl #31 + bne .outsw_noalign + + ldrh r3, [r1], #2 + sub r2, r2, #1 + strh r3, [r0] + +ENTRY(__raw_writesw) + teq r2, #0 + moveq pc, lr + ands r3, r1, #3 + bne .outsw_align + + stmfd sp!, {r4, r5, lr} + + subs r2, r2, #8 + bmi .no_outsw_8 + +.outsw_8_lp: ldmia r1!, {r3, r4, r5, ip} + subs r2, r2, #8 + outword r3 + outword r4 + outword r5 + outword ip + bpl .outsw_8_lp + +.no_outsw_8: tst r2, #4 + beq .no_outsw_4 + + ldmia r1!, {r3, ip} + outword r3 + outword ip + +.no_outsw_4: movs r2, r2, lsl #31 + bcc .no_outsw_2 + + ldr r3, [r1], #4 + outword r3 + +.no_outsw_2: ldrneh r3, [r1] + strneh r3, [r0] + + ldmfd sp!, {r4, r5, pc} + +#ifdef __ARMEB__ +#define pull_hbyte0 lsl #8 +#define push_hbyte1 lsr #24 +#else +#define pull_hbyte0 lsr #24 +#define push_hbyte1 lsl #8 +#endif + +.outsw_noalign: ldr r3, [r1, -r3]! + subcs r2, r2, #1 + bcs 2f + subs r2, r2, #2 + bmi 3f + +1: mov ip, r3, lsr #8 + strh ip, [r0] +2: mov ip, r3, pull_hbyte0 + ldr r3, [r1, #4]! + subs r2, r2, #2 + orr ip, ip, r3, push_hbyte1 + strh ip, [r0] + bpl 2b + +3: tst r2, #1 +2: movne ip, r3, lsr #8 + strneh ip, [r0] + mov pc, lr diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S new file mode 100644 index 0000000..5902602 --- /dev/null +++ b/arch/arm/lib/lib1funcs.S @@ -0,0 +1,314 @@ +/* + * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines + * + * Author: Nicolas Pitre <nico@cam.org> + * - contributed to gcc-3.4 on Sep 30, 2003 + * - adapted for the Linux kernel on Oct 2, 2003 + */ + +/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. + +This file 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, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +This file 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; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#include <linux/linkage.h> +#include <asm/assembler.h> + + +.macro ARM_DIV_BODY dividend, divisor, result, curbit + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \curbit, \divisor + clz \result, \dividend + sub \result, \curbit, \result + mov \curbit, #1 + mov \divisor, \divisor, lsl \result + mov \curbit, \curbit, lsl \result + mov \result, #0 + +#else + + @ Initially shift the divisor left 3 bits if possible, + @ set curbit accordingly. This allows for curbit to be located + @ at the left end of each 4 bit nibbles in the division loop + @ to save one loop in most cases. + tst \divisor, #0xe0000000 + moveq \divisor, \divisor, lsl #3 + moveq \curbit, #8 + movne \curbit, #1 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + movlo \curbit, \curbit, lsl #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + movlo \curbit, \curbit, lsl #1 + blo 1b + + mov \result, #0 + +#endif + + @ Division loop +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + orrhs \result, \result, \curbit + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + orrhs \result, \result, \curbit, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + orrhs \result, \result, \curbit, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + orrhs \result, \result, \curbit, lsr #3 + cmp \dividend, #0 @ Early termination? + movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? + movne \divisor, \divisor, lsr #4 + bne 1b + +.endm + + +.macro ARM_DIV2_ORDER divisor, order + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \order, \divisor + rsb \order, \order, #31 + +#else + + cmp \divisor, #(1 << 16) + movhs \divisor, \divisor, lsr #16 + movhs \order, #16 + movlo \order, #0 + + cmp \divisor, #(1 << 8) + movhs \divisor, \divisor, lsr #8 + addhs \order, \order, #8 + + cmp \divisor, #(1 << 4) + movhs \divisor, \divisor, lsr #4 + addhs \order, \order, #4 + + cmp \divisor, #(1 << 2) + addhi \order, \order, #3 + addls \order, \order, \divisor, lsr #1 + +#endif + +.endm + + +.macro ARM_MOD_BODY dividend, divisor, order, spare + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \order, \divisor + clz \spare, \dividend + sub \order, \order, \spare + mov \divisor, \divisor, lsl \order + +#else + + mov \order, #0 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + addlo \order, \order, #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + addlo \order, \order, #1 + blo 1b + +#endif + + @ Perform all needed substractions to keep only the reminder. + @ Do comparisons in batch of 4 first. + subs \order, \order, #3 @ yes, 3 is intended here + blt 2f + +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + cmp \dividend, #1 + mov \divisor, \divisor, lsr #4 + subges \order, \order, #4 + bge 1b + + tst \order, #3 + teqne \dividend, #0 + beq 5f + + @ Either 1, 2 or 3 comparison/substractions are left. +2: cmn \order, #2 + blt 4f + beq 3f + cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +3: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +4: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor +5: +.endm + + +ENTRY(__udivsi3) + + subs r2, r1, #1 + moveq pc, lr + bcc Ldiv0 + cmp r0, r1 + bls 11f + tst r1, r2 + beq 12f + + ARM_DIV_BODY r0, r1, r2, r3 + + mov r0, r2 + mov pc, lr + +11: moveq r0, #1 + movne r0, #0 + mov pc, lr + +12: ARM_DIV2_ORDER r1, r2 + + mov r0, r0, lsr r2 + mov pc, lr + + +ENTRY(__umodsi3) + + subs r2, r1, #1 @ compare divisor with 1 + bcc Ldiv0 + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + movls pc, lr + + ARM_MOD_BODY r0, r1, r2, r3 + + mov pc, lr + + +ENTRY(__divsi3) + + cmp r1, #0 + eor ip, r0, r1 @ save the sign of the result. + beq Ldiv0 + rsbmi r1, r1, #0 @ loops below use unsigned. + subs r2, r1, #1 @ division by 1 or -1 ? + beq 10f + movs r3, r0 + rsbmi r3, r0, #0 @ positive dividend value + cmp r3, r1 + bls 11f + tst r1, r2 @ divisor is power of 2 ? + beq 12f + + ARM_DIV_BODY r3, r1, r0, r2 + + cmp ip, #0 + rsbmi r0, r0, #0 + mov pc, lr + +10: teq ip, r0 @ same sign ? + rsbmi r0, r0, #0 + mov pc, lr + +11: movlo r0, #0 + moveq r0, ip, asr #31 + orreq r0, r0, #1 + mov pc, lr + +12: ARM_DIV2_ORDER r1, r2 + + cmp ip, #0 + mov r0, r3, lsr r2 + rsbmi r0, r0, #0 + mov pc, lr + + +ENTRY(__modsi3) + + cmp r1, #0 + beq Ldiv0 + rsbmi r1, r1, #0 @ loops below use unsigned. + movs ip, r0 @ preserve sign of dividend + rsbmi r0, r0, #0 @ if negative make positive + subs r2, r1, #1 @ compare divisor with 1 + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + bls 10f + + ARM_MOD_BODY r0, r1, r2, r3 + +10: cmp ip, #0 + rsbmi r0, r0, #0 + mov pc, lr + + +Ldiv0: + + str lr, [sp, #-4]! + bl __div0 + mov r0, #0 @ About as wrong as it could be. + ldr pc, [sp], #4 + + diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h new file mode 100644 index 0000000..179eea4 --- /dev/null +++ b/arch/arm/lib/longlong.h @@ -0,0 +1,183 @@ +/* longlong.h -- based on code from gcc-2.95.3 + + definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + + This definition file 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, or (at your option) any later version. + + This definition file 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. */ + +/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */ + +#ifndef SI_TYPE_SIZE +#define SI_TYPE_SIZE 32 +#endif + +#define __BITS4 (SI_TYPE_SIZE / 4) +#define __ll_B (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((USItype) (t) % __ll_B) +#define __ll_highpart(t) ((USItype) (t) / __ll_B) + +/* Define auxiliary asm macros. + + 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) + multiplies two USItype integers MULTIPLER and MULTIPLICAND, + and generates a two-part USItype product in HIGH_PROD and + LOW_PROD. + + 2) __umulsidi3(a,b) multiplies two USItype integers A and B, + and returns a UDItype product. This is just a variant of umul_ppmm. + + 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator) divides a two-word unsigned integer, composed by the + integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and + places the quotient in QUOTIENT and the remainder in REMAINDER. + HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. + If, in addition, the most significant bit of DENOMINATOR must be 1, + then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. + + 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator). Like udiv_qrnnd but the numbers are signed. The + quotient is rounded towards 0. + + 5) count_leading_zeros(count, x) counts the number of zero-bits from + the msb to the first non-zero bit. This is the number of steps X + needs to be shifted left to set the msb. Undefined for X == 0. + + 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) adds two two-word unsigned integers, + composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and + LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and + LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is + lost. + + 7) sub_ddmmss(high_difference, low_difference, high_minuend, + low_minuend, high_subtrahend, low_subtrahend) subtracts two + two-word unsigned integers, composed by HIGH_MINUEND_1 and + LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 + respectively. The result is placed in HIGH_DIFFERENCE and + LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, + and is lost. + + If any of these macros are left undefined for a particular CPU, + C macros are used. */ + +#if defined (__arm__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1, %4, %5 \n\ + adc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rI" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1, %4, %5 \n\ + sbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rI" ((USItype) (bl))) +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm \n\ + mov %2, %5, lsr #16 \n\ + mov %0, %6, lsr #16 \n\ + bic %3, %5, %2, lsl #16 \n\ + bic %4, %6, %0, lsl #16 \n\ + mul %1, %3, %4 \n\ + mul %4, %2, %4 \n\ + mul %3, %0, %3 \n\ + mul %0, %2, %0 \n\ + adds %3, %4, %3 \n\ + addcs %0, %0, #65536 \n\ + adds %1, %1, %3, lsl #16 \n\ + adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype) (xh)), \ + "=r" ((USItype) (xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype) (a)), \ + "r" ((USItype) (b)));} +#define UMUL_TIME 20 +#define UDIV_TIME 100 +#endif /* __arm__ */ + +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) + +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + USItype __d1, __d0, __q1, __q0; \ + USItype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (USItype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (USItype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (USItype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c + +#define count_leading_zeros(count, x) \ + do { \ + USItype __xr = (x); \ + USItype __a; \ + \ + if (SI_TYPE_SIZE <= 32) \ + { \ + __a = __xr < ((USItype)1<<2*__BITS4) \ + ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \ + : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ + } \ + else \ + { \ + for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + } \ + \ + (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ + } while (0) diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c new file mode 100644 index 0000000..b666f1b --- /dev/null +++ b/arch/arm/lib/lshrdi3.c @@ -0,0 +1,61 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC 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, or (at your option) +any later version. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. + */ +/* support functions required by the kernel. based on code from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#include "gcclib.h" + +DItype +__lshrdi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (USItype)uu.s.high >> -bm; + } + else + { + USItype carries = (USItype)uu.s.high << bm; + w.s.high = (USItype)uu.s.high >> b; + w.s.low = ((USItype)uu.s.low >> b) | carries; + } + + return w.ll; +} + diff --git a/arch/arm/lib/memchr.S b/arch/arm/lib/memchr.S new file mode 100644 index 0000000..ac34fe5 --- /dev/null +++ b/arch/arm/lib/memchr.S @@ -0,0 +1,25 @@ +/* + * linux/arch/arm/lib/memchr.S + * + * 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <asm/assembler.h> + + .text + .align 5 +ENTRY(memchr) +1: subs r2, r2, #1 + bmi 2f + ldrb r3, [r0], #1 + teq r3, r1 + bne 1b + sub r0, r0, #1 +2: movne r0, #0 + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S new file mode 100644 index 0000000..f5a593c --- /dev/null +++ b/arch/arm/lib/memcpy.S @@ -0,0 +1,393 @@ +/* + * linux/arch/arm/lib/memcpy.S + * + * Copyright (C) 1995-1999 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <asm/assembler.h> + + .text + +#define ENTER \ + mov ip,sp ;\ + stmfd sp!,{r0,r4-r9,fp,ip,lr,pc} ;\ + sub fp,ip,#4 + +#define EXIT \ + LOADREGS(ea, fp, {r0, r4 - r9, fp, sp, pc}) + +#define EXITEQ \ + LOADREGS(eqea, fp, {r0, r4 - r9, fp, sp, pc}) + +/* + * Prototype: void memcpy(void *to,const void *from,unsigned long n); + */ +ENTRY(memcpy) +ENTRY(memmove) + ENTER + cmp r1, r0 + bcc 23f + subs r2, r2, #4 + blt 6f + PLD( pld [r1, #0] ) + ands ip, r0, #3 + bne 7f + ands ip, r1, #3 + bne 8f + +1: subs r2, r2, #8 + blt 5f + subs r2, r2, #20 + blt 4f + PLD( pld [r1, #28] ) + PLD( subs r2, r2, #64 ) + PLD( blt 3f ) +2: PLD( pld [r1, #60] ) + PLD( pld [r1, #92] ) + ldmia r1!, {r3 - r9, ip} + subs r2, r2, #32 + stmgeia r0!, {r3 - r9, ip} + ldmgeia r1!, {r3 - r9, ip} + subges r2, r2, #32 + stmia r0!, {r3 - r9, ip} + bge 2b +3: PLD( ldmia r1!, {r3 - r9, ip} ) + PLD( adds r2, r2, #32 ) + PLD( stmgeia r0!, {r3 - r9, ip} ) + PLD( ldmgeia r1!, {r3 - r9, ip} ) + PLD( subges r2, r2, #32 ) + PLD( stmia r0!, {r3 - r9, ip} ) +4: cmn r2, #16 + ldmgeia r1!, {r3 - r6} + subge r2, r2, #16 + stmgeia r0!, {r3 - r6} + adds r2, r2, #20 + ldmgeia r1!, {r3 - r5} + subge r2, r2, #12 + stmgeia r0!, {r3 - r5} +5: adds r2, r2, #8 + blt 6f + subs r2, r2, #4 + ldrlt r3, [r1], #4 + ldmgeia r1!, {r4, r5} + subge r2, r2, #4 + strlt r3, [r0], #4 + stmgeia r0!, {r4, r5} + +6: adds r2, r2, #4 + EXITEQ + cmp r2, #2 + ldrb r3, [r1], #1 + ldrgeb r4, [r1], #1 + ldrgtb r5, [r1], #1 + strb r3, [r0], #1 + strgeb r4, [r0], #1 + strgtb r5, [r0], #1 + EXIT + +7: rsb ip, ip, #4 + cmp ip, #2 + ldrb r3, [r1], #1 + ldrgeb r4, [r1], #1 + ldrgtb r5, [r1], #1 + strb r3, [r0], #1 + strgeb r4, [r0], #1 + strgtb r5, [r0], #1 + subs r2, r2, ip + blt 6b + ands ip, r1, #3 + beq 1b + +8: bic r1, r1, #3 + ldr r7, [r1], #4 + cmp ip, #2 + bgt 18f + beq 13f + cmp r2, #12 + blt 11f + PLD( pld [r1, #12] ) + sub r2, r2, #12 + PLD( subs r2, r2, #32 ) + PLD( blt 10f ) + PLD( pld [r1, #28] ) +9: PLD( pld [r1, #44] ) +10: mov r3, r7, pull #8 + ldmia r1!, {r4 - r7} + subs r2, r2, #16 + orr r3, r3, r4, push #24 + mov r4, r4, pull #8 + orr r4, r4, r5, push #24 + mov r5, r5, pull #8 + orr r5, r5, r6, push #24 + mov r6, r6, pull #8 + orr r6, r6, r7, push #24 + stmia r0!, {r3 - r6} + bge 9b + PLD( cmn r2, #32 ) + PLD( bge 10b ) + PLD( add r2, r2, #32 ) + adds r2, r2, #12 + blt 12f +11: mov r3, r7, pull #8 + ldr r7, [r1], #4 + subs r2, r2, #4 + orr r3, r3, r7, push #24 + str r3, [r0], #4 + bge 11b +12: sub r1, r1, #3 + b 6b + +13: cmp r2, #12 + blt 16f + PLD( pld [r1, #12] ) + sub r2, r2, #12 + PLD( subs r2, r2, #32 ) + PLD( blt 15f ) + PLD( pld [r1, #28] ) +14: PLD( pld [r1, #44] ) +15: mov r3, r7, pull #16 + ldmia r1!, {r4 - r7} + subs r2, r2, #16 + orr r3, r3, r4, push #16 + mov r4, r4, pull #16 + orr r4, r4, r5, push #16 + mov r5, r5, pull #16 + orr r5, r5, r6, push #16 + mov r6, r6, pull #16 + orr r6, r6, r7, push #16 + stmia r0!, {r3 - r6} + bge 14b + PLD( cmn r2, #32 ) + PLD( bge 15b ) + PLD( add r2, r2, #32 ) + adds r2, r2, #12 + blt 17f +16: mov r3, r7, pull #16 + ldr r7, [r1], #4 + subs r2, r2, #4 + orr r3, r3, r7, push #16 + str r3, [r0], #4 + bge 16b +17: sub r1, r1, #2 + b 6b + +18: cmp r2, #12 + blt 21f + PLD( pld [r1, #12] ) + sub r2, r2, #12 + PLD( subs r2, r2, #32 ) + PLD( blt 20f ) + PLD( pld [r1, #28] ) +19: PLD( pld [r1, #44] ) +20: mov r3, r7, pull #24 + ldmia r1!, {r4 - r7} + subs r2, r2, #16 + orr r3, r3, r4, push #8 + mov r4, r4, pull #24 + orr r4, r4, r5, push #8 + mov r5, r5, pull #24 + orr r5, r5, r6, push #8 + mov r6, r6, pull #24 + orr r6, r6, r7, push #8 + stmia r0!, {r3 - r6} + bge 19b + PLD( cmn r2, #32 ) + PLD( bge 20b ) + PLD( add r2, r2, #32 ) + adds r2, r2, #12 + blt 22f +21: mov r3, r7, pull #24 + ldr r7, [r1], #4 + subs r2, r2, #4 + orr r3, r3, r7, push #8 + str r3, [r0], #4 + bge 21b +22: sub r1, r1, #1 + b 6b + + +23: add r1, r1, r2 + add r0, r0, r2 + subs r2, r2, #4 + blt 29f + PLD( pld [r1, #-4] ) + ands ip, r0, #3 + bne 30f + ands ip, r1, #3 + bne 31f + +24: subs r2, r2, #8 + blt 28f + subs r2, r2, #20 + blt 27f + PLD( pld [r1, #-32] ) + PLD( subs r2, r2, #64 ) + PLD( blt 26f ) +25: PLD( pld [r1, #-64] ) + PLD( pld [r1, #-96] ) + ldmdb r1!, {r3 - r9, ip} + subs r2, r2, #32 + stmgedb r0!, {r3 - r9, ip} + ldmgedb r1!, {r3 - r9, ip} + subges r2, r2, #32 + stmdb r0!, {r3 - r9, ip} + bge 25b +26: PLD( ldmdb r1!, {r3 - r9, ip} ) + PLD( adds r2, r2, #32 ) + PLD( stmgedb r0!, {r3 - r9, ip} ) + PLD( ldmgedb r1!, {r3 - r9, ip} ) + PLD( subges r2, r2, #32 ) + PLD( stmdb r0!, {r3 - r9, ip} ) +27: cmn r2, #16 + ldmgedb r1!, {r3 - r6} + subge r2, r2, #16 + stmgedb r0!, {r3 - r6} + adds r2, r2, #20 + ldmgedb r1!, {r3 - r5} + subge r2, r2, #12 + stmgedb r0!, {r3 - r5} +28: adds r2, r2, #8 + blt 29f + subs r2, r2, #4 + ldrlt r3, [r1, #-4]! + ldmgedb r1!, {r4, r5} + subge r2, r2, #4 + strlt r3, [r0, #-4]! + stmgedb r0!, {r4, r5} + +29: adds r2, r2, #4 + EXITEQ + cmp r2, #2 + ldrb r3, [r1, #-1]! + ldrgeb r4, [r1, #-1]! + ldrgtb r5, [r1, #-1]! + strb r3, [r0, #-1]! + strgeb r4, [r0, #-1]! + strgtb r5, [r0, #-1]! + EXIT + +30: cmp ip, #2 + ldrb r3, [r1, #-1]! + ldrgeb r4, [r1, #-1]! + ldrgtb r5, [r1, #-1]! + strb r3, [r0, #-1]! + strgeb r4, [r0, #-1]! + strgtb r5, [r0, #-1]! + subs r2, r2, ip + blt 29b + ands ip, r1, #3 + beq 24b + +31: bic r1, r1, #3 + ldr r3, [r1], #0 + cmp ip, #2 + blt 41f + beq 36f + cmp r2, #12 + blt 34f + PLD( pld [r1, #-16] ) + sub r2, r2, #12 + PLD( subs r2, r2, #32 ) + PLD( blt 33f ) + PLD( pld [r1, #-32] ) +32: PLD( pld [r1, #-48] ) +33: mov r7, r3, push #8 + ldmdb r1!, {r3, r4, r5, r6} + subs r2, r2, #16 + orr r7, r7, r6, pull #24 + mov r6, r6, push #8 + orr r6, r6, r5, pull #24 + mov r5, r5, push #8 + orr r5, r5, r4, pull #24 + mov r4, r4, push #8 + orr r4, r4, r3, pull #24 + stmdb r0!, {r4, r5, r6, r7} + bge 32b + PLD( cmn r2, #32 ) + PLD( bge 33b ) + PLD( add r2, r2, #32 ) + adds r2, r2, #12 + blt 35f +34: mov ip, r3, push #8 + ldr r3, [r1, #-4]! + subs r2, r2, #4 + orr ip, ip, r3, pull #24 + str ip, [r0, #-4]! + bge 34b +35: add r1, r1, #3 + b 29b + +36: cmp r2, #12 + blt 39f + PLD( pld [r1, #-16] ) + sub r2, r2, #12 + PLD( subs r2, r2, #32 ) + PLD( blt 38f ) + PLD( pld [r1, #-32] ) +37: PLD( pld [r1, #-48] ) +38: mov r7, r3, push #16 + ldmdb r1!, {r3, r4, r5, r6} + subs r2, r2, #16 + orr r7, r7, r6, pull #16 + mov r6, r6, push #16 + orr r6, r6, r5, pull #16 + mov r5, r5, push #16 + orr r5, r5, r4, pull #16 + mov r4, r4, push #16 + orr r4, r4, r3, pull #16 + stmdb r0!, {r4, r5, r6, r7} + bge 37b + PLD( cmn r2, #32 ) + PLD( bge 38b ) + PLD( add r2, r2, #32 ) + adds r2, r2, #12 + blt 40f +39: mov ip, r3, push #16 + ldr r3, [r1, #-4]! + subs r2, r2, #4 + orr ip, ip, r3, pull #16 + str ip, [r0, #-4]! + bge 39b +40: add r1, r1, #2 + b 29b + +41: cmp r2, #12 + blt 44f + PLD( pld [r1, #-16] ) + sub r2, r2, #12 + PLD( subs r2, r2, #32 ) + PLD( blt 43f ) + PLD( pld [r1, #-32] ) +42: PLD( pld [r1, #-48] ) +43: mov r7, r3, push #24 + ldmdb r1!, {r3, r4, r5, r6} + subs r2, r2, #16 + orr r7, r7, r6, pull #8 + mov r6, r6, push #24 + orr r6, r6, r5, pull #8 + mov r5, r5, push #24 + orr r5, r5, r4, pull #8 + mov r4, r4, push #24 + orr r4, r4, r3, pull #8 + stmdb r0!, {r4, r5, r6, r7} + bge 42b + PLD( cmn r2, #32 ) + PLD( bge 43b ) + PLD( add r2, r2, #32 ) + adds r2, r2, #12 + blt 45f +44: mov ip, r3, push #24 + ldr r3, [r1, #-4]! + subs r2, r2, #4 + orr ip, ip, r3, pull #8 + str ip, [r0, #-4]! + bge 44b +45: add r1, r1, #1 + b 29b + diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S new file mode 100644 index 0000000..a1795f59 --- /dev/null +++ b/arch/arm/lib/memset.S @@ -0,0 +1,80 @@ +/* + * linux/arch/arm/lib/memset.S + * + * 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <asm/assembler.h> + + .text + .align 5 + .word 0 + +1: subs r2, r2, #4 @ 1 do we have enough + blt 5f @ 1 bytes to align with? + cmp r3, #2 @ 1 + strltb r1, [r0], #1 @ 1 + strleb r1, [r0], #1 @ 1 + strb r1, [r0], #1 @ 1 + add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) +/* + * The pointer is now aligned and the length is adjusted. Try doing the + * memzero again. + */ + +ENTRY(memset) + ands r3, r0, #3 @ 1 unaligned? + bne 1b @ 1 +/* + * we know that the pointer in r0 is aligned to a word boundary. + */ + orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #16 + mov r3, r1 + cmp r2, #16 + blt 4f +/* + * We need an extra register for this loop - save the return address and + * use the LR + */ + str lr, [sp, #-4]! + mov ip, r1 + mov lr, r1 + +2: subs r2, r2, #64 + stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time. + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + bgt 2b + LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go. +/* + * No need to correct the count; we're only testing bits from now on + */ + tst r2, #32 + stmneia r0!, {r1, r3, ip, lr} + stmneia r0!, {r1, r3, ip, lr} + tst r2, #16 + stmneia r0!, {r1, r3, ip, lr} + ldr lr, [sp], #4 + +4: tst r2, #8 + stmneia r0!, {r1, r3} + tst r2, #4 + strne r1, [r0], #4 +/* + * When we get here, we've got less than 4 bytes to zero. We + * may have an unaligned pointer as well. + */ +5: tst r2, #2 + strneb r1, [r0], #1 + strneb r1, [r0], #1 + tst r2, #1 + strneb r1, [r0], #1 + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S new file mode 100644 index 0000000..51ccc60 --- /dev/null +++ b/arch/arm/lib/memzero.S @@ -0,0 +1,80 @@ +/* + * linux/arch/arm/lib/memzero.S + * + * 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/linkage.h> +#include <asm/assembler.h> + + .text + .align 5 + .word 0 +/* + * Align the pointer in r0. r3 contains the number of bytes that we are + * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we + * don't bother; we use byte stores instead. + */ +1: subs r1, r1, #4 @ 1 do we have enough + blt 5f @ 1 bytes to align with? + cmp r3, #2 @ 1 + strltb r2, [r0], #1 @ 1 + strleb r2, [r0], #1 @ 1 + strb r2, [r0], #1 @ 1 + add r1, r1, r3 @ 1 (r1 = r1 - (4 - r3)) +/* + * The pointer is now aligned and the length is adjusted. Try doing the + * memzero again. + */ + +ENTRY(__memzero) + mov r2, #0 @ 1 + ands r3, r0, #3 @ 1 unaligned? + bne 1b @ 1 +/* + * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary. + */ + cmp r1, #16 @ 1 we can skip this chunk if we + blt 4f @ 1 have < 16 bytes +/* + * We need an extra register for this loop - save the return address and + * use the LR + */ + str lr, [sp, #-4]! @ 1 + mov ip, r2 @ 1 + mov lr, r2 @ 1 + +3: subs r1, r1, #64 @ 1 write 32 bytes out per loop + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + bgt 3b @ 1 + LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit +/* + * No need to correct the count; we're only testing bits from now on + */ + tst r1, #32 @ 1 + stmneia r0!, {r2, r3, ip, lr} @ 4 + stmneia r0!, {r2, r3, ip, lr} @ 4 + tst r1, #16 @ 1 16 bytes or more? + stmneia r0!, {r2, r3, ip, lr} @ 4 + ldr lr, [sp], #4 @ 1 + +4: tst r1, #8 @ 1 8 bytes or more? + stmneia r0!, {r2, r3} @ 2 + tst r1, #4 @ 1 4 bytes or more? + strne r2, [r0], #4 @ 1 +/* + * When we get here, we've got less than 4 bytes to zero. We + * may have an unaligned pointer as well. + */ +5: tst r1, #2 @ 1 2 bytes or more? + strneb r2, [r0], #1 @ 1 + strneb r2, [r0], #1 @ 1 + tst r1, #1 @ 1 a byte left over + strneb r2, [r0], #1 @ 1 + RETINSTR(mov,pc,lr) @ 1 diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c new file mode 100644 index 0000000..44d611b --- /dev/null +++ b/arch/arm/lib/muldi3.c @@ -0,0 +1,77 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC 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, or (at your option) +any later version. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. + */ +/* support functions required by the kernel. based on code from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#include "gcclib.h" + +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm \n\ + mov %2, %5, lsr #16 \n\ + mov %0, %6, lsr #16 \n\ + bic %3, %5, %2, lsl #16 \n\ + bic %4, %6, %0, lsl #16 \n\ + mul %1, %3, %4 \n\ + mul %4, %2, %4 \n\ + mul %3, %0, %3 \n\ + mul %0, %2, %0 \n\ + adds %3, %4, %3 \n\ + addcs %0, %0, #65536 \n\ + adds %1, %1, %3, lsl #16 \n\ + adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype) (xh)), \ + "=r" ((USItype) (xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype) (a)), \ + "r" ((USItype) (b)));} + + +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) + + +DItype +__muldi3 (DItype u, DItype v) +{ + DIunion w; + DIunion uu, vv; + + uu.ll = u, + vv.ll = v; + + w.ll = __umulsidi3 (uu.s.low, vv.s.low); + w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high + + (USItype) uu.s.high * (USItype) vv.s.low); + + return w.ll; +} + diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S new file mode 100644 index 0000000..b09398d --- /dev/null +++ b/arch/arm/lib/putuser.S @@ -0,0 +1,76 @@ +/* + * linux/arch/arm/lib/putuser.S + * + * Copyright (C) 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. + * + * Idea from x86 version, (C) Copyright 1998 Linus Torvalds + * + * These functions have a non-standard call interface to make + * them more efficient, especially as they return an error + * value in addition to the "real" return value. + * + * __put_user_X + * + * Inputs: r0 contains the address + * r2, r3 contains the value + * Outputs: r0 is the error code + * lr corrupted + * + * No other registers must be altered. (see include/asm-arm/uaccess.h + * for specific ASM register usage). + * + * Note that ADDR_LIMIT is either 0 or 0xc0000000 + * Note also that it is intended that __put_user_bad is not global. + */ +#include <asm/constants.h> +#include <asm/thread_info.h> +#include <asm/errno.h> + + .global __put_user_1 +__put_user_1: +1: strbt r2, [r0] + mov r0, #0 + mov pc, lr + + .global __put_user_2 +__put_user_2: + mov ip, r2, lsr #8 +#ifndef __ARMEB__ +2: strbt r2, [r0], #1 +3: strbt ip, [r0] +#else +2: strbt ip, [r0], #1 +3: strbt r2, [r0] +#endif + mov r0, #0 + mov pc, lr + + .global __put_user_4 +__put_user_4: +4: strt r2, [r0] + mov r0, #0 + mov pc, lr + + .global __put_user_8 +__put_user_8: +5: strt r2, [r0], #4 +6: strt r3, [r0] + mov r0, #0 + mov pc, lr + +__put_user_bad: + mov r0, #-EFAULT + mov pc, lr + +.section __ex_table, "a" + .long 1b, __put_user_bad + .long 2b, __put_user_bad + .long 3b, __put_user_bad + .long 4b, __put_user_bad + .long 5b, __put_user_bad + .long 6b, __put_user_bad +.previous diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S new file mode 100644 index 0000000..8f337df --- /dev/null +++ b/arch/arm/lib/setbit.S @@ -0,0 +1,29 @@ +/* + * linux/arch/arm/lib/setbit.S + * + * Copyright (C) 1995-1996 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/linkage.h> +#include <asm/assembler.h> + .text + +/* + * Purpose : Function to set a bit + * Prototype: int set_bit(int bit, void *addr) + */ +ENTRY(_set_bit_be) + eor r0, r0, #0x18 @ big endian byte ordering +ENTRY(_set_bit_le) + and r2, r0, #7 + mov r3, #1 + mov r3, r3, lsl r2 + save_and_disable_irqs ip, r2 + ldrb r2, [r1, r0, lsr #3] + orr r2, r2, r3 + strb r2, [r1, r0, lsr #3] + restore_irqs ip + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S new file mode 100644 index 0000000..5b9b493 --- /dev/null +++ b/arch/arm/lib/strchr.S @@ -0,0 +1,26 @@ +/* + * linux/arch/arm/lib/strchr.S + * + * 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <asm/assembler.h> + + .text + .align 5 +ENTRY(strchr) + and r1, r1, #0xff +1: ldrb r2, [r0], #1 + teq r2, r1 + teqne r2, #0 + bne 1b + teq r2, r1 + movne r0, #0 + subeq r0, r0, #1 + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S new file mode 100644 index 0000000..629cc87 --- /dev/null +++ b/arch/arm/lib/strncpy_from_user.S @@ -0,0 +1,43 @@ +/* + * linux/arch/arm/lib/strncpy_from_user.S + * + * 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/linkage.h> +#include <asm/assembler.h> +#include <asm/errno.h> + + .text + .align 5 + +/* + * Copy a string from user space to kernel space. + * r0 = dst, r1 = src, r2 = byte length + * returns the number of characters copied (strlen of copied string), + * -EFAULT on exception, or "len" if we fill the whole buffer + */ +ENTRY(__arch_strncpy_from_user) + save_lr + mov ip, r1 +1: subs r2, r2, #1 +USER( ldrplbt r3, [r1], #1) + bmi 2f + strb r3, [r0], #1 + teq r3, #0 + bne 1b + sub r1, r1, #1 @ take NUL character out of count +2: sub r0, r1, ip + restore_pc + + .section .fixup,"ax" + .align 0 +9001: mov r3, #0 + strb r3, [r0, #0] @ null terminate + mov r0, #-EFAULT + restore_pc + .previous + diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S new file mode 100644 index 0000000..67bcd82 --- /dev/null +++ b/arch/arm/lib/strnlen_user.S @@ -0,0 +1,40 @@ +/* + * linux/arch/arm/lib/strnlen_user.S + * + * 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/linkage.h> +#include <asm/assembler.h> +#include <asm/errno.h> + + .text + .align 5 + +/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) + * Purpose : get length of a string in user memory + * Params : str - address of string in user memory + * Returns : length of string *including terminator* + * or zero on exception, or n + 1 if too long + */ +ENTRY(__arch_strnlen_user) + save_lr + mov r2, r0 +1: +USER( ldrbt r3, [r0], #1) + teq r3, #0 + beq 2f + subs r1, r1, #1 + bne 1b + add r0, r0, #1 +2: sub r0, r0, r2 + restore_pc + + .section .fixup,"ax" + .align 0 +9001: mov r0, #0 + restore_pc + .previous diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S new file mode 100644 index 0000000..fa923f0 --- /dev/null +++ b/arch/arm/lib/strrchr.S @@ -0,0 +1,25 @@ +/* + * linux/arch/arm/lib/strrchr.S + * + * 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <asm/assembler.h> + + .text + .align 5 +ENTRY(strrchr) + mov r3, #0 +1: ldrb r2, [r0], #1 + teq r2, r1 + subeq r3, r0, #1 + teq r2, #0 + bne 1b + mov r0, r3 + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S new file mode 100644 index 0000000..4aba467 --- /dev/null +++ b/arch/arm/lib/testchangebit.S @@ -0,0 +1,29 @@ +/* + * linux/arch/arm/lib/testchangebit.S + * + * Copyright (C) 1995-1996 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/linkage.h> +#include <asm/assembler.h> + .text + +ENTRY(_test_and_change_bit_be) + eor r0, r0, #0x18 @ big endian byte ordering +ENTRY(_test_and_change_bit_le) + add r1, r1, r0, lsr #3 + and r3, r0, #7 + mov r0, #1 + save_and_disable_irqs ip, r2 + ldrb r2, [r1] + tst r2, r0, lsl r3 + eor r2, r2, r0, lsl r3 + strb r2, [r1] + restore_irqs ip + moveq r0, #0 + RETINSTR(mov,pc,lr) + + diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S new file mode 100644 index 0000000..e07c5bd --- /dev/null +++ b/arch/arm/lib/testclearbit.S @@ -0,0 +1,29 @@ +/* + * linux/arch/arm/lib/testclearbit.S + * + * Copyright (C) 1995-1996 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/linkage.h> +#include <asm/assembler.h> + .text + +ENTRY(_test_and_clear_bit_be) + eor r0, r0, #0x18 @ big endian byte ordering +ENTRY(_test_and_clear_bit_le) + add r1, r1, r0, lsr #3 @ Get byte offset + and r3, r0, #7 @ Get bit offset + mov r0, #1 + save_and_disable_irqs ip, r2 + ldrb r2, [r1] + tst r2, r0, lsl r3 + bic r2, r2, r0, lsl r3 + strb r2, [r1] + restore_irqs ip + moveq r0, #0 + RETINSTR(mov,pc,lr) + + diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S new file mode 100644 index 0000000..a570fc7 --- /dev/null +++ b/arch/arm/lib/testsetbit.S @@ -0,0 +1,29 @@ +/* + * linux/arch/arm/lib/testsetbit.S + * + * Copyright (C) 1995-1996 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/linkage.h> +#include <asm/assembler.h> + .text + +ENTRY(_test_and_set_bit_be) + eor r0, r0, #0x18 @ big endian byte ordering +ENTRY(_test_and_set_bit_le) + add r1, r1, r0, lsr #3 @ Get byte offset + and r3, r0, #7 @ Get bit offset + mov r0, #1 + save_and_disable_irqs ip, r2 + ldrb r2, [r1] + tst r2, r0, lsl r3 + orr r2, r2, r0, lsl r3 + strb r2, [r1] + restore_irqs ip + moveq r0, #0 + RETINSTR(mov,pc,lr) + + diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S new file mode 100644 index 0000000..d3ed063 --- /dev/null +++ b/arch/arm/lib/uaccess.S @@ -0,0 +1,697 @@ +/* + * linux/arch/arm/lib/uaccess.S + * + * Copyright (C) 1995, 1996,1997,1998 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. + * + * Routines to block copy data to/from user memory + * These are highly optimised both for the 4k page size + * and for various alignments. + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/errno.h> + + .text + +#define PAGE_SHIFT 12 + +/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) + * Purpose : copy a block to user memory from kernel memory + * Params : to - user memory + * : from - kernel memory + * : n - number of bytes to copy + * Returns : Number of bytes NOT copied. + */ + +.c2u_dest_not_aligned: + rsb ip, ip, #4 + cmp ip, #2 + ldrb r3, [r1], #1 +USER( strbt r3, [r0], #1) @ May fault + ldrgeb r3, [r1], #1 +USER( strgebt r3, [r0], #1) @ May fault + ldrgtb r3, [r1], #1 +USER( strgtbt r3, [r0], #1) @ May fault + sub r2, r2, ip + b .c2u_dest_aligned + +ENTRY(__arch_copy_to_user) + stmfd sp!, {r2, r4 - r7, lr} + cmp r2, #4 + blt .c2u_not_enough + PLD( pld [r1, #0] ) + PLD( pld [r0, #0] ) + ands ip, r0, #3 + bne .c2u_dest_not_aligned +.c2u_dest_aligned: + + ands ip, r1, #3 + bne .c2u_src_not_aligned +/* + * Seeing as there has to be at least 8 bytes to copy, we can + * copy one word, and force a user-mode page fault... + */ + +.c2u_0fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .c2u_0nowords + ldr r3, [r1], #4 +USER( strt r3, [r0], #4) @ May fault + mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .c2u_0fupi +/* + * ip = max no. of bytes to copy before needing another "strt" insn + */ + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #32 + blt .c2u_0rem8lp + PLD( pld [r1, #28] ) + PLD( pld [r0, #28] ) + PLD( subs ip, ip, #64 ) + PLD( blt .c2u_0cpynopld ) + PLD( pld [r1, #60] ) + PLD( pld [r0, #60] ) + +.c2u_0cpy8lp: + PLD( pld [r1, #92] ) + PLD( pld [r0, #92] ) +.c2u_0cpynopld: ldmia r1!, {r3 - r6} + stmia r0!, {r3 - r6} @ Shouldnt fault + ldmia r1!, {r3 - r6} + subs ip, ip, #32 + stmia r0!, {r3 - r6} @ Shouldnt fault + bpl .c2u_0cpy8lp + PLD( cmn ip, #64 ) + PLD( bge .c2u_0cpynopld ) + PLD( add ip, ip, #64 ) + +.c2u_0rem8lp: cmn ip, #16 + ldmgeia r1!, {r3 - r6} + stmgeia r0!, {r3 - r6} @ Shouldnt fault + tst ip, #8 + ldmneia r1!, {r3 - r4} + stmneia r0!, {r3 - r4} @ Shouldnt fault + tst ip, #4 + ldrne r3, [r1], #4 + strnet r3, [r0], #4 @ Shouldnt fault + ands ip, ip, #3 + beq .c2u_0fupi +.c2u_0nowords: teq ip, #0 + beq .c2u_finished +.c2u_nowords: cmp ip, #2 + ldrb r3, [r1], #1 +USER( strbt r3, [r0], #1) @ May fault + ldrgeb r3, [r1], #1 +USER( strgebt r3, [r0], #1) @ May fault + ldrgtb r3, [r1], #1 +USER( strgtbt r3, [r0], #1) @ May fault + b .c2u_finished + +.c2u_not_enough: + movs ip, r2 + bne .c2u_nowords +.c2u_finished: mov r0, #0 + LOADREGS(fd,sp!,{r2, r4 - r7, pc}) + +.c2u_src_not_aligned: + bic r1, r1, #3 + ldr r7, [r1], #4 + cmp ip, #2 + bgt .c2u_3fupi + beq .c2u_2fupi +.c2u_1fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .c2u_1nowords + mov r3, r7, pull #8 + ldr r7, [r1], #4 + orr r3, r3, r7, push #24 +USER( strt r3, [r0], #4) @ May fault + mov ip, r0, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .c2u_1fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .c2u_1rem8lp + PLD( pld [r1, #12] ) + PLD( pld [r0, #12] ) + PLD( subs ip, ip, #32 ) + PLD( blt .c2u_1cpynopld ) + PLD( pld [r1, #28] ) + PLD( pld [r0, #28] ) + +.c2u_1cpy8lp: + PLD( pld [r1, #44] ) + PLD( pld [r0, #44] ) +.c2u_1cpynopld: mov r3, r7, pull #8 + ldmia r1!, {r4 - r7} + subs ip, ip, #16 + orr r3, r3, r4, push #24 + mov r4, r4, pull #8 + orr r4, r4, r5, push #24 + mov r5, r5, pull #8 + orr r5, r5, r6, push #24 + mov r6, r6, pull #8 + orr r6, r6, r7, push #24 + stmia r0!, {r3 - r6} @ Shouldnt fault + bpl .c2u_1cpy8lp + PLD( cmn ip, #32 ) + PLD( bge .c2u_1cpynopld ) + PLD( add ip, ip, #32 ) + +.c2u_1rem8lp: tst ip, #8 + movne r3, r7, pull #8 + ldmneia r1!, {r4, r7} + orrne r3, r3, r4, push #24 + movne r4, r4, pull #8 + orrne r4, r4, r7, push #24 + stmneia r0!, {r3 - r4} @ Shouldnt fault + tst ip, #4 + movne r3, r7, pull #8 + ldrne r7, [r1], #4 + orrne r3, r3, r7, push #24 + strnet r3, [r0], #4 @ Shouldnt fault + ands ip, ip, #3 + beq .c2u_1fupi +.c2u_1nowords: mov r3, r7, get_byte_1 + teq ip, #0 + beq .c2u_finished + cmp ip, #2 +USER( strbt r3, [r0], #1) @ May fault + movge r3, r7, get_byte_2 +USER( strgebt r3, [r0], #1) @ May fault + movgt r3, r7, get_byte_3 +USER( strgtbt r3, [r0], #1) @ May fault + b .c2u_finished + +.c2u_2fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .c2u_2nowords + mov r3, r7, pull #16 + ldr r7, [r1], #4 + orr r3, r3, r7, push #16 +USER( strt r3, [r0], #4) @ May fault + mov ip, r0, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .c2u_2fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .c2u_2rem8lp + PLD( pld [r1, #12] ) + PLD( pld [r0, #12] ) + PLD( subs ip, ip, #32 ) + PLD( blt .c2u_2cpynopld ) + PLD( pld [r1, #28] ) + PLD( pld [r0, #28] ) + +.c2u_2cpy8lp: + PLD( pld [r1, #44] ) + PLD( pld [r0, #44] ) +.c2u_2cpynopld: mov r3, r7, pull #16 + ldmia r1!, {r4 - r7} + subs ip, ip, #16 + orr r3, r3, r4, push #16 + mov r4, r4, pull #16 + orr r4, r4, r5, push #16 + mov r5, r5, pull #16 + orr r5, r5, r6, push #16 + mov r6, r6, pull #16 + orr r6, r6, r7, push #16 + stmia r0!, {r3 - r6} @ Shouldnt fault + bpl .c2u_2cpy8lp + PLD( cmn ip, #32 ) + PLD( bge .c2u_2cpynopld ) + PLD( add ip, ip, #32 ) + +.c2u_2rem8lp: tst ip, #8 + movne r3, r7, pull #16 + ldmneia r1!, {r4, r7} + orrne r3, r3, r4, push #16 + movne r4, r4, pull #16 + orrne r4, r4, r7, push #16 + stmneia r0!, {r3 - r4} @ Shouldnt fault + tst ip, #4 + movne r3, r7, pull #16 + ldrne r7, [r1], #4 + orrne r3, r3, r7, push #16 + strnet r3, [r0], #4 @ Shouldnt fault + ands ip, ip, #3 + beq .c2u_2fupi +.c2u_2nowords: mov r3, r7, get_byte_2 + teq ip, #0 + beq .c2u_finished + cmp ip, #2 +USER( strbt r3, [r0], #1) @ May fault + movge r3, r7, get_byte_3 +USER( strgebt r3, [r0], #1) @ May fault + ldrgtb r3, [r1], #0 +USER( strgtbt r3, [r0], #1) @ May fault + b .c2u_finished + +.c2u_3fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .c2u_3nowords + mov r3, r7, pull #24 + ldr r7, [r1], #4 + orr r3, r3, r7, push #8 +USER( strt r3, [r0], #4) @ May fault + mov ip, r0, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .c2u_3fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .c2u_3rem8lp + PLD( pld [r1, #12] ) + PLD( pld [r0, #12] ) + PLD( subs ip, ip, #32 ) + PLD( blt .c2u_3cpynopld ) + PLD( pld [r1, #28] ) + PLD( pld [r0, #28] ) + +.c2u_3cpy8lp: + PLD( pld [r1, #44] ) + PLD( pld [r0, #44] ) +.c2u_3cpynopld: mov r3, r7, pull #24 + ldmia r1!, {r4 - r7} + subs ip, ip, #16 + orr r3, r3, r4, push #8 + mov r4, r4, pull #24 + orr r4, r4, r5, push #8 + mov r5, r5, pull #24 + orr r5, r5, r6, push #8 + mov r6, r6, pull #24 + orr r6, r6, r7, push #8 + stmia r0!, {r3 - r6} @ Shouldnt fault + bpl .c2u_3cpy8lp + PLD( cmn ip, #32 ) + PLD( bge .c2u_3cpynopld ) + PLD( add ip, ip, #32 ) + +.c2u_3rem8lp: tst ip, #8 + movne r3, r7, pull #24 + ldmneia r1!, {r4, r7} + orrne r3, r3, r4, push #8 + movne r4, r4, pull #24 + orrne r4, r4, r7, push #8 + stmneia r0!, {r3 - r4} @ Shouldnt fault + tst ip, #4 + movne r3, r7, pull #24 + ldrne r7, [r1], #4 + orrne r3, r3, r7, push #8 + strnet r3, [r0], #4 @ Shouldnt fault + ands ip, ip, #3 + beq .c2u_3fupi +.c2u_3nowords: mov r3, r7, get_byte_3 + teq ip, #0 + beq .c2u_finished + cmp ip, #2 +USER( strbt r3, [r0], #1) @ May fault + ldrgeb r3, [r1], #1 +USER( strgebt r3, [r0], #1) @ May fault + ldrgtb r3, [r1], #0 +USER( strgtbt r3, [r0], #1) @ May fault + b .c2u_finished + + .section .fixup,"ax" + .align 0 +9001: LOADREGS(fd,sp!, {r0, r4 - r7, pc}) + .previous + +/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); + * Purpose : copy a block from user memory to kernel memory + * Params : to - kernel memory + * : from - user memory + * : n - number of bytes to copy + * Returns : Number of bytes NOT copied. + */ +.cfu_dest_not_aligned: + rsb ip, ip, #4 + cmp ip, #2 +USER( ldrbt r3, [r1], #1) @ May fault + strb r3, [r0], #1 +USER( ldrgebt r3, [r1], #1) @ May fault + strgeb r3, [r0], #1 +USER( ldrgtbt r3, [r1], #1) @ May fault + strgtb r3, [r0], #1 + sub r2, r2, ip + b .cfu_dest_aligned + +ENTRY(__arch_copy_from_user) + stmfd sp!, {r0, r2, r4 - r7, lr} + cmp r2, #4 + blt .cfu_not_enough + PLD( pld [r1, #0] ) + PLD( pld [r0, #0] ) + ands ip, r0, #3 + bne .cfu_dest_not_aligned +.cfu_dest_aligned: + ands ip, r1, #3 + bne .cfu_src_not_aligned +/* + * Seeing as there has to be at least 8 bytes to copy, we can + * copy one word, and force a user-mode page fault... + */ + +.cfu_0fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .cfu_0nowords +USER( ldrt r3, [r1], #4) + str r3, [r0], #4 + mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .cfu_0fupi +/* + * ip = max no. of bytes to copy before needing another "strt" insn + */ + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #32 + blt .cfu_0rem8lp + PLD( pld [r1, #28] ) + PLD( pld [r0, #28] ) + PLD( subs ip, ip, #64 ) + PLD( blt .cfu_0cpynopld ) + PLD( pld [r1, #60] ) + PLD( pld [r0, #60] ) + +.cfu_0cpy8lp: + PLD( pld [r1, #92] ) + PLD( pld [r0, #92] ) +.cfu_0cpynopld: ldmia r1!, {r3 - r6} @ Shouldnt fault + stmia r0!, {r3 - r6} + ldmia r1!, {r3 - r6} @ Shouldnt fault + subs ip, ip, #32 + stmia r0!, {r3 - r6} + bpl .cfu_0cpy8lp + PLD( cmn ip, #64 ) + PLD( bge .cfu_0cpynopld ) + PLD( add ip, ip, #64 ) + +.cfu_0rem8lp: cmn ip, #16 + ldmgeia r1!, {r3 - r6} @ Shouldnt fault + stmgeia r0!, {r3 - r6} + tst ip, #8 + ldmneia r1!, {r3 - r4} @ Shouldnt fault + stmneia r0!, {r3 - r4} + tst ip, #4 + ldrnet r3, [r1], #4 @ Shouldnt fault + strne r3, [r0], #4 + ands ip, ip, #3 + beq .cfu_0fupi +.cfu_0nowords: teq ip, #0 + beq .cfu_finished +.cfu_nowords: cmp ip, #2 +USER( ldrbt r3, [r1], #1) @ May fault + strb r3, [r0], #1 +USER( ldrgebt r3, [r1], #1) @ May fault + strgeb r3, [r0], #1 +USER( ldrgtbt r3, [r1], #1) @ May fault + strgtb r3, [r0], #1 + b .cfu_finished + +.cfu_not_enough: + movs ip, r2 + bne .cfu_nowords +.cfu_finished: mov r0, #0 + add sp, sp, #8 + LOADREGS(fd,sp!,{r4 - r7, pc}) + +.cfu_src_not_aligned: + bic r1, r1, #3 +USER( ldrt r7, [r1], #4) @ May fault + cmp ip, #2 + bgt .cfu_3fupi + beq .cfu_2fupi +.cfu_1fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .cfu_1nowords + mov r3, r7, pull #8 +USER( ldrt r7, [r1], #4) @ May fault + orr r3, r3, r7, push #24 + str r3, [r0], #4 + mov ip, r1, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .cfu_1fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .cfu_1rem8lp + PLD( pld [r1, #12] ) + PLD( pld [r0, #12] ) + PLD( subs ip, ip, #32 ) + PLD( blt .cfu_1cpynopld ) + PLD( pld [r1, #28] ) + PLD( pld [r0, #28] ) + +.cfu_1cpy8lp: + PLD( pld [r1, #44] ) + PLD( pld [r0, #44] ) +.cfu_1cpynopld: mov r3, r7, pull #8 + ldmia r1!, {r4 - r7} @ Shouldnt fault + subs ip, ip, #16 + orr r3, r3, r4, push #24 + mov r4, r4, pull #8 + orr r4, r4, r5, push #24 + mov r5, r5, pull #8 + orr r5, r5, r6, push #24 + mov r6, r6, pull #8 + orr r6, r6, r7, push #24 + stmia r0!, {r3 - r6} + bpl .cfu_1cpy8lp + PLD( cmn ip, #32 ) + PLD( bge .cfu_1cpynopld ) + PLD( add ip, ip, #32 ) + +.cfu_1rem8lp: tst ip, #8 + movne r3, r7, pull #8 + ldmneia r1!, {r4, r7} @ Shouldnt fault + orrne r3, r3, r4, push #24 + movne r4, r4, pull #8 + orrne r4, r4, r7, push #24 + stmneia r0!, {r3 - r4} + tst ip, #4 + movne r3, r7, pull #8 +USER( ldrnet r7, [r1], #4) @ May fault + orrne r3, r3, r7, push #24 + strne r3, [r0], #4 + ands ip, ip, #3 + beq .cfu_1fupi +.cfu_1nowords: mov r3, r7, get_byte_1 + teq ip, #0 + beq .cfu_finished + cmp ip, #2 + strb r3, [r0], #1 + movge r3, r7, get_byte_2 + strgeb r3, [r0], #1 + movgt r3, r7, get_byte_3 + strgtb r3, [r0], #1 + b .cfu_finished + +.cfu_2fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .cfu_2nowords + mov r3, r7, pull #16 +USER( ldrt r7, [r1], #4) @ May fault + orr r3, r3, r7, push #16 + str r3, [r0], #4 + mov ip, r1, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .cfu_2fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .cfu_2rem8lp + PLD( pld [r1, #12] ) + PLD( pld [r0, #12] ) + PLD( subs ip, ip, #32 ) + PLD( blt .cfu_2cpynopld ) + PLD( pld [r1, #28] ) + PLD( pld [r0, #28] ) + +.cfu_2cpy8lp: + PLD( pld [r1, #44] ) + PLD( pld [r0, #44] ) +.cfu_2cpynopld: mov r3, r7, pull #16 + ldmia r1!, {r4 - r7} @ Shouldnt fault + subs ip, ip, #16 + orr r3, r3, r4, push #16 + mov r4, r4, pull #16 + orr r4, r4, r5, push #16 + mov r5, r5, pull #16 + orr r5, r5, r6, push #16 + mov r6, r6, pull #16 + orr r6, r6, r7, push #16 + stmia r0!, {r3 - r6} + bpl .cfu_2cpy8lp + PLD( cmn ip, #32 ) + PLD( bge .cfu_2cpynopld ) + PLD( add ip, ip, #32 ) + +.cfu_2rem8lp: tst ip, #8 + movne r3, r7, pull #16 + ldmneia r1!, {r4, r7} @ Shouldnt fault + orrne r3, r3, r4, push #16 + movne r4, r4, pull #16 + orrne r4, r4, r7, push #16 + stmneia r0!, {r3 - r4} + tst ip, #4 + movne r3, r7, pull #16 +USER( ldrnet r7, [r1], #4) @ May fault + orrne r3, r3, r7, push #16 + strne r3, [r0], #4 + ands ip, ip, #3 + beq .cfu_2fupi +.cfu_2nowords: mov r3, r7, get_byte_2 + teq ip, #0 + beq .cfu_finished + cmp ip, #2 + strb r3, [r0], #1 + movge r3, r7, get_byte_3 + strgeb r3, [r0], #1 +USER( ldrgtbt r3, [r1], #0) @ May fault + strgtb r3, [r0], #1 + b .cfu_finished + +.cfu_3fupi: subs r2, r2, #4 + addmi ip, r2, #4 + bmi .cfu_3nowords + mov r3, r7, pull #24 +USER( ldrt r7, [r1], #4) @ May fault + orr r3, r3, r7, push #8 + str r3, [r0], #4 + mov ip, r1, lsl #32 - PAGE_SHIFT + rsb ip, ip, #0 + movs ip, ip, lsr #32 - PAGE_SHIFT + beq .cfu_3fupi + cmp r2, ip + movlt ip, r2 + sub r2, r2, ip + subs ip, ip, #16 + blt .cfu_3rem8lp + PLD( pld [r1, #12] ) + PLD( pld [r0, #12] ) + PLD( subs ip, ip, #32 ) + PLD( blt .cfu_3cpynopld ) + PLD( pld [r1, #28] ) + PLD( pld [r0, #28] ) + +.cfu_3cpy8lp: + PLD( pld [r1, #44] ) + PLD( pld [r0, #44] ) +.cfu_3cpynopld: mov r3, r7, pull #24 + ldmia r1!, {r4 - r7} @ Shouldnt fault + orr r3, r3, r4, push #8 + mov r4, r4, pull #24 + orr r4, r4, r5, push #8 + mov r5, r5, pull #24 + orr r5, r5, r6, push #8 + mov r6, r6, pull #24 + orr r6, r6, r7, push #8 + stmia r0!, {r3 - r6} + subs ip, ip, #16 + bpl .cfu_3cpy8lp + PLD( cmn ip, #32 ) + PLD( bge .cfu_3cpynopld ) + PLD( add ip, ip, #32 ) + +.cfu_3rem8lp: tst ip, #8 + movne r3, r7, pull #24 + ldmneia r1!, {r4, r7} @ Shouldnt fault + orrne r3, r3, r4, push #8 + movne r4, r4, pull #24 + orrne r4, r4, r7, push #8 + stmneia r0!, {r3 - r4} + tst ip, #4 + movne r3, r7, pull #24 +USER( ldrnet r7, [r1], #4) @ May fault + orrne r3, r3, r7, push #8 + strne r3, [r0], #4 + ands ip, ip, #3 + beq .cfu_3fupi +.cfu_3nowords: mov r3, r7, get_byte_3 + teq ip, #0 + beq .cfu_finished + cmp ip, #2 + strb r3, [r0], #1 +USER( ldrgebt r3, [r1], #1) @ May fault + strgeb r3, [r0], #1 +USER( ldrgtbt r3, [r1], #1) @ May fault + strgtb r3, [r0], #1 + b .cfu_finished + + .section .fixup,"ax" + .align 0 + /* + * We took an exception. r0 contains a pointer to + * the byte not copied. + */ +9001: ldr r2, [sp], #4 @ void *to + sub r2, r0, r2 @ bytes copied + ldr r1, [sp], #4 @ unsigned long count + subs r4, r1, r2 @ bytes left to copy + movne r1, r4 + blne __memzero + mov r0, r4 + LOADREGS(fd,sp!, {r4 - r7, pc}) + .previous + +/* Prototype: int __arch_clear_user(void *addr, size_t sz) + * Purpose : clear some user memory + * Params : addr - user memory address to clear + * : sz - number of bytes to clear + * Returns : number of bytes NOT cleared + */ +ENTRY(__arch_clear_user) + stmfd sp!, {r1, lr} + mov r2, #0 + cmp r1, #4 + blt 2f + ands ip, r0, #3 + beq 1f + cmp ip, #2 +USER( strbt r2, [r0], #1) +USER( strlebt r2, [r0], #1) +USER( strltbt r2, [r0], #1) + rsb ip, ip, #4 + sub r1, r1, ip @ 7 6 5 4 3 2 1 +1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 +USER( strplt r2, [r0], #4) +USER( strplt r2, [r0], #4) + bpl 1b + adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3 +USER( strplt r2, [r0], #4) +2: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x +USER( strnebt r2, [r0], #1) +USER( strnebt r2, [r0], #1) + tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 +USER( strnebt r2, [r0], #1) + mov r0, #0 + LOADREGS(fd,sp!, {r1, pc}) + + .section .fixup,"ax" + .align 0 +9001: LOADREGS(fd,sp!, {r0, pc}) + .previous + diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c new file mode 100644 index 0000000..6c6ae63 --- /dev/null +++ b/arch/arm/lib/ucmpdi2.c @@ -0,0 +1,51 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC 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, or (at your option) +any later version. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. + */ +/* support functions required by the kernel. based on code from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#include "gcclib.h" + +word_type +__ucmpdi2 (DItype a, DItype b) +{ + DIunion au, bu; + + au.ll = a, bu.ll = b; + + if ((USItype) au.s.high < (USItype) bu.s.high) + return 0; + else if ((USItype) au.s.high > (USItype) bu.s.high) + return 2; + if ((USItype) au.s.low < (USItype) bu.s.low) + return 0; + else if ((USItype) au.s.low > (USItype) bu.s.low) + return 2; + return 1; +} + diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c new file mode 100644 index 0000000..d25195f --- /dev/null +++ b/arch/arm/lib/udivdi3.c @@ -0,0 +1,242 @@ +/* More subroutines needed by GCC output code on some machines. */ +/* Compile this one with gcc. */ +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC 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, or (at your option) +any later version. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. + */ +/* support functions required by the kernel. based on code from gcc-2.95.3 */ +/* I Molton 29/07/01 */ + +#include "gcclib.h" +#include "longlong.h" + +static const UQItype __clz_tab[] = +{ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +}; + +UDItype +__udivmoddi4 (UDItype n, UDItype d, UDItype *rp) +{ + DIunion ww; + DIunion nn, dd; + DIunion rr; + USItype d0, d1, n0, n1, n2; + USItype q0, q1; + USItype b, bm; + + nn.ll = n; + dd.ll = d; + + d0 = dd.s.low; + d1 = dd.s.high; + n0 = nn.s.low; + n1 = nn.s.high; + + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + count_leading_zeros (bm, d0); + + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ + + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); + n0 = n0 << bm; + } + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0 >> bm. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + count_leading_zeros (bm, d0); + + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). + + This special case is necessary, not an optimization. + (Shifts counts of SI_TYPE_SIZE are undefined.) */ + + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ + + b = SI_TYPE_SIZE - bm; + + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q1, n1, n2, n1, d0); + } + + /* n1 != d0... */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0 >> bm. */ + } + + if (rp != 0) + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } + } + else + { + if (d1 > n1) + { + /* 00 = nn / DD */ + + q0 = 0; + q1 = 0; + + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + /* 0q = NN / dd */ + + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). + + This special case is necessary, not an optimization. */ + + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; + + q1 = 0; + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + USItype m1, m0; + /* Normalize. */ + + b = SI_TYPE_SIZE - bm; + + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); + + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } + + q1 = 0; + + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } + } + + ww.s.low = q0; + ww.s.high = q1; + return ww.ll; +} + +UDItype +__udivdi3 (UDItype n, UDItype d) +{ + return __udivmoddi4 (n, d, (UDItype *) 0); +} + +UDItype +__umoddi3 (UDItype u, UDItype v) +{ + UDItype w; + + (void) __udivmoddi4 (u ,v, &w); + + return w; +} + diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig new file mode 100644 index 0000000..f6e6763 --- /dev/null +++ b/arch/arm/mach-clps711x/Kconfig @@ -0,0 +1,71 @@ +if ARCH_CLPS711X + +menu "CLPS711X/EP721X Implementations" + +config ARCH_AUTCPU12 + bool "AUTCPU12" + help + Say Y if you intend to run the kernel on the autronix autcpu12 + board. This board is based on a Cirrus Logic CS89712. + +config ARCH_CDB89712 + bool "CDB89712" + help + This is an evaluation board from Cirrus for the CS89712 processor. + The board includes 2 serial ports, Ethernet, IRDA, and expansion + headers. It comes with 16 MB SDRAM and 8 MB flash ROM. + +config ARCH_CEIVA + bool "CEIVA" + help + Say Y here if you intend to run this kernel on the Ceiva/Polaroid + PhotoMax Digital Picture Frame. + +config ARCH_CLEP7312 + bool "CLEP7312" + +config ARCH_EDB7211 + bool "EDB7211" + help + Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 + evaluation board. + +config ARCH_P720T + bool "P720T" + help + Say Y here if you intend to run this kernel on the ARM Prospector + 720T. + +config ARCH_FORTUNET + bool "FORTUNET" + +# XXX Maybe these should indicate register compatibility +# instead of being mutually exclusive. +config ARCH_EP7211 + bool + depends on ARCH_EDB7211 + default y + +config ARCH_EP7212 + bool + depends on ARCH_P720T || ARCH_CEIVA + default y + +config EP72XX_ROM_BOOT + bool "EP72xx ROM boot" + depends on ARCH_EP7211 || ARCH_EP7212 + ---help--- + If you say Y here, your CLPS711x-based kernel will use the bootstrap + mode memory map instead of the normal memory map. + + Processors derived from the Cirrus CLPS-711X core support two boot + modes. Normal mode boots from the external memory device at CS0. + Bootstrap mode rearranges parts of the memory map, placing an + internal 128 byte bootstrap ROM at CS0. This option performs the + address map changes required to support booting in this mode. + + You almost surely want to say N here. + +endmenu + +endif diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile new file mode 100644 index 0000000..4a19731 --- /dev/null +++ b/arch/arm/mach-clps711x/Makefile @@ -0,0 +1,20 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := irq.o mm.o time.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_CEIVA) += ceiva.o +obj-$(CONFIG_ARCH_AUTCPU12) += autcpu12.o +obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o +obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o +obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o +obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o +obj-$(CONFIG_ARCH_P720T) += p720t.o +leds-$(CONFIG_ARCH_P720T) += p720t-leds.o +obj-$(CONFIG_LEDS) += $(leds-y) diff --git a/arch/arm/mach-clps711x/Makefile.boot b/arch/arm/mach-clps711x/Makefile.boot new file mode 100644 index 0000000..d3d2933 --- /dev/null +++ b/arch/arm/mach-clps711x/Makefile.boot @@ -0,0 +1,7 @@ +# The standard locations for stuff on CLPS711x type processors + zreladdr-y := 0xc0028000 +params_phys-y := 0xc0000100 +# Should probably have some agreement on these... +initrd_phys-$(CONFIG_ARCH_P720T) := 0xc0400000 +initrd_phys-$(CONFIG_ARCH_CDB89712) := 0x00700000 + diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c new file mode 100644 index 0000000..c106704 --- /dev/null +++ b/arch/arm/mach-clps711x/autcpu12.c @@ -0,0 +1,69 @@ +/* + * linux/arch/arm/mach-clps711x/autcpu12.c + * + * (c) 2001 Thomas Gleixner, autronix automation <gleixner@autronix.de> + * + * 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 <linux/types.h> +#include <linux/string.h> +#include <linux/mm.h> + +#include <asm/hardware.h> +#include <asm/sizes.h> +#include <asm/io.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/pgtable.h> +#include <asm/page.h> + +#include <asm/mach/map.h> +#include <asm/arch/autcpu12.h> + +#include "common.h" + +/* + * The on-chip registers are given a size of 1MB so that a section can + * be used to map them; this saves a page table. This is the place to + * add mappings for ROM, expansion memory, PCMCIA, etc. (if static + * mappings are chosen for those areas). + * +*/ + +static struct map_desc autcpu12_io_desc[] __initdata = { + /* virtual, physical, length, type */ + /* memory-mapped extra io and CS8900A Ethernet chip */ + /* ethernet chip */ + { AUTCPU12_VIRT_CS8900A, AUTCPU12_PHYS_CS8900A, SZ_1M, MT_DEVICE } +}; + +void __init autcpu12_map_io(void) +{ + clps711x_map_io(); + iotable_init(autcpu12_io_desc, ARRAY_SIZE(autcpu12_io_desc)); +} + +MACHINE_START(AUTCPU12, "autronix autcpu12") + MAINTAINER("Thomas Gleixner") + BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) + BOOT_PARAMS(0xc0020000) + MAPIO(autcpu12_map_io) + INITIRQ(clps711x_init_irq) + .timer = &clps711x_timer, +MACHINE_END + diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c new file mode 100644 index 0000000..7664f9c --- /dev/null +++ b/arch/arm/mach-clps711x/cdb89712.c @@ -0,0 +1,58 @@ +/* + * linux/arch/arm/mach-clps711x/cdb89712.c + * + * Copyright (C) 2000-2001 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 <linux/types.h> +#include <linux/string.h> +#include <linux/mm.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "common.h" + +/* + * Map the CS89712 Ethernet port. That should be moved to the + * ethernet driver, perhaps. + */ +static struct map_desc cdb89712_io_desc[] __initdata = { + { ETHER_BASE, ETHER_START, ETHER_SIZE, MT_DEVICE } +}; + +static void __init cdb89712_map_io(void) +{ + clps711x_map_io(); + iotable_init(cdb89712_io_desc, ARRAY_SIZE(cdb89712_io_desc)); +} + +MACHINE_START(CDB89712, "Cirrus-CDB89712") + MAINTAINER("Ray Lehtiniemi") + BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) + BOOT_PARAMS(0xc0000100) + MAPIO(cdb89712_map_io) + INITIRQ(clps711x_init_irq) + .timer = &clps711x_timer, +MACHINE_END diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c new file mode 100644 index 0000000..e4093be --- /dev/null +++ b/arch/arm/mach-clps711x/ceiva.c @@ -0,0 +1,62 @@ +/* + * linux/arch/arm/mach-clps711x/arch-ceiva.c + * + * Copyright (C) 2002, Rob Scott <rscott@mtrob.fdns.net> + * + * 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 <linux/types.h> +#include <linux/string.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <linux/kernel.h> + +#include <asm/hardware.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/sizes.h> + +#include <asm/mach/map.h> + +#include "common.h" + +static struct map_desc ceiva_io_desc[] __initdata = { + /* virtual, physical, length, type */ + + /* SED1355 controlled video RAM & registers */ + { CEIVA_VIRT_SED1355, CEIVA_PHYS_SED1355, SZ_2M, MT_DEVICE } + +}; + + +static void __init ceiva_map_io(void) +{ + clps711x_map_io(); + iotable_init(ceiva_io_desc, ARRAY_SIZE(ceiva_io_desc)); +} + + +MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame") + MAINTAINER("Rob Scott") + BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) + BOOT_PARAMS(0xc0000100) + MAPIO(ceiva_map_io) + INITIRQ(clps711x_init_irq) + .timer = &clps711x_timer, +MACHINE_END diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c new file mode 100644 index 0000000..9ca21cb --- /dev/null +++ b/arch/arm/mach-clps711x/clep7312.c @@ -0,0 +1,48 @@ +/* + * linux/arch/arm/mach-clps711x/clep7312.c + * + * 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 <linux/types.h> +#include <linux/string.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include "common.h" + +static void __init +fixup_clep7312(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mi->nr_banks=1; + mi->bank[0].start = 0xc0000000; + mi->bank[0].size = 0x01000000; + mi->bank[0].node = 0; +} + + +MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") + MAINTAINER("Nobody") + BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_clep7312) + MAPIO(clps711x_map_io) + INITIRQ(clps711x_init_irq) + .timer = &clps711x_timer, +MACHINE_END + diff --git a/arch/arm/mach-clps711x/common.h b/arch/arm/mach-clps711x/common.h new file mode 100644 index 0000000..2b8b801 --- /dev/null +++ b/arch/arm/mach-clps711x/common.h @@ -0,0 +1,11 @@ +/* + * linux/arch/arm/mach-clps711x/common.h + * + * Common bits. + */ + +struct sys_timer; + +extern void clps711x_map_io(void); +extern void clps711x_init_irq(void); +extern struct sys_timer clps711x_timer; diff --git a/arch/arm/mach-clps711x/dma.c b/arch/arm/mach-clps711x/dma.c new file mode 100644 index 0000000..af5a4de --- /dev/null +++ b/arch/arm/mach-clps711x/dma.c @@ -0,0 +1,27 @@ +/* + * linux/arch/arm/mach-clps711x/dma.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/init.h> + +#include <asm/dma.h> +#include <asm/mach/dma.h> + +void __init arch_dma_init(dma_t *dma) +{ +} diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c new file mode 100644 index 0000000..c6c4632 --- /dev/null +++ b/arch/arm/mach-clps711x/edb7211-arch.c @@ -0,0 +1,61 @@ +/* + * linux/arch/arm/mach-clps711x/arch-edb7211.c + * + * Copyright (C) 2000, 2001 Blue Mug, Inc. All Rights Reserved. + * + * 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 <linux/types.h> +#include <linux/string.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include "common.h" + +extern void edb7211_map_io(void); + +static void __init +fixup_edb7211(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + /* + * Bank start addresses are not present in the information + * passed in from the boot loader. We could potentially + * detect them, but instead we hard-code them. + * + * Banks sizes _are_ present in the param block, but we're + * not using that information yet. + */ + mi->bank[0].start = 0xc0000000; + mi->bank[0].size = 8*1024*1024; + mi->bank[0].node = 0; + mi->bank[1].start = 0xc1000000; + mi->bank[1].size = 8*1024*1024; + mi->bank[1].node = 1; + mi->nr_banks = 2; +} + +MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") + MAINTAINER("Jon McClintock") + BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) + BOOT_PARAMS(0xc0020100) /* 0xc0000000 - 0xc001ffff can be video RAM */ + FIXUP(fixup_edb7211) + MAPIO(edb7211_map_io) + INITIRQ(clps711x_init_irq) + .timer = &clps711x_timer, +MACHINE_END diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c new file mode 100644 index 0000000..7fd7b01 --- /dev/null +++ b/arch/arm/mach-clps711x/edb7211-mm.c @@ -0,0 +1,70 @@ +/* + * linux/arch/arm/mach-clps711x/mm.c + * + * Extra MM routines for the EDB7211 board + * + * Copyright (C) 2000, 2001 Blue Mug, Inc. All Rights Reserved. + * + * 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/page.h> +#include <asm/pgtable.h> +#include <asm/sizes.h> + +#include <asm/mach/map.h> + +extern void clps711x_map_io(void); + +/* + * The on-chip registers are given a size of 1MB so that a section can + * be used to map them; this saves a page table. This is the place to + * add mappings for ROM, expansion memory, PCMCIA, etc. (if static + * mappings are chosen for those areas). + * + * Here is a physical memory map (to be fleshed out later): + * + * Physical Address Size Description + * ----------------- ----- --------------------------------- + * c0000000-c001ffff 128KB reserved for video RAM [1] + * c0020000-c0023fff 16KB parameters (see Documentation/arm/Setup) + * c0024000-c0027fff 16KB swapper_pg_dir (task 0 page directory) + * c0028000-... kernel image (TEXTADDR) + * + * [1] Unused pages should be given back to the VM; they are not yet. + * The parameter block should also be released (not sure if this + * happens). + */ +static struct map_desc edb7211_io_desc[] __initdata = { + /* virtual, physical, length, type */ + + /* memory-mapped extra keyboard row and CS8900A Ethernet chip */ + { EP7211_VIRT_EXTKBD, EP7211_PHYS_EXTKBD, SZ_1M, MT_DEVICE }, + { EP7211_VIRT_CS8900A, EP7211_PHYS_CS8900A, SZ_1M, MT_DEVICE }, + + /* flash banks */ + { EP7211_VIRT_FLASH1, EP7211_PHYS_FLASH1, SZ_8M, MT_DEVICE }, + { EP7211_VIRT_FLASH2, EP7211_PHYS_FLASH2, SZ_8M, MT_DEVICE } +}; + +void __init edb7211_map_io(void) +{ + clps711x_map_io(); + iotable_init(edb7211_io_desc, ARRAY_SIZE(edb7211_io_desc)); +} + diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c new file mode 100644 index 0000000..c1c5b8e --- /dev/null +++ b/arch/arm/mach-clps711x/fortunet.c @@ -0,0 +1,85 @@ +/* + * linux/arch/arm/mach-clps711x/fortunet.c + * + * Derived from 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/init.h> +#include <linux/initrd.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> + +#include "common.h" + +struct meminfo memmap = { + .nr_banks = 1, + .bank = { + { + .start = 0xC0000000, + .size = 0x01000000, + .node = 0 + }, + }, +}; + +typedef struct tag_IMAGE_PARAMS +{ + int ramdisk_ok; + int ramdisk_address; + int ramdisk_size; + int ram_size; + int extra_param_type; + int extra_param_ptr; + int command_line; +} IMAGE_PARAMS; + +#define IMAGE_PARAMS_PHYS 0xC01F0000 + +static void __init +fortunet_fixup(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + IMAGE_PARAMS *ip = phys_to_virt(IMAGE_PARAMS_PHYS); + *cmdline = phys_to_virt(ip->command_line); +#ifdef CONFIG_BLK_DEV_INITRD + if(ip->ramdisk_ok) + { + initrd_start = __phys_to_virt(ip->ramdisk_address); + initrd_end = initrd_start + ip->ramdisk_size; + } +#endif + memmap.bank[0].size = ip->ram_size; + *mi = memmap; +} + +MACHINE_START(FORTUNET, "ARM-FortuNet") + MAINTAINER("FortuNet Inc.") + BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000) + BOOT_PARAMS(0x00000000) + FIXUP(fortunet_fixup) + MAPIO(clps711x_map_io) + INITIRQ(clps711x_init_irq) + .timer = &clps711x_timer, +MACHINE_END diff --git a/arch/arm/mach-clps711x/irq.c b/arch/arm/mach-clps711x/irq.c new file mode 100644 index 0000000..7ee926e --- /dev/null +++ b/arch/arm/mach-clps711x/irq.c @@ -0,0 +1,143 @@ +/* + * linux/arch/arm/mach-clps711x/irq.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/init.h> +#include <linux/list.h> + +#include <asm/mach/irq.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> + +#include <asm/hardware/clps7111.h> + +static void int1_mask(unsigned int irq) +{ + u32 intmr1; + + intmr1 = clps_readl(INTMR1); + intmr1 &= ~(1 << irq); + clps_writel(intmr1, INTMR1); +} + +static void int1_ack(unsigned int irq) +{ + u32 intmr1; + + intmr1 = clps_readl(INTMR1); + intmr1 &= ~(1 << irq); + clps_writel(intmr1, INTMR1); + + switch (irq) { + case IRQ_CSINT: clps_writel(0, COEOI); break; + case IRQ_TC1OI: clps_writel(0, TC1EOI); break; + case IRQ_TC2OI: clps_writel(0, TC2EOI); break; + case IRQ_RTCMI: clps_writel(0, RTCEOI); break; + case IRQ_TINT: clps_writel(0, TEOI); break; + case IRQ_UMSINT: clps_writel(0, UMSEOI); break; + } +} + +static void int1_unmask(unsigned int irq) +{ + u32 intmr1; + + intmr1 = clps_readl(INTMR1); + intmr1 |= 1 << irq; + clps_writel(intmr1, INTMR1); +} + +static struct irqchip int1_chip = { + .ack = int1_ack, + .mask = int1_mask, + .unmask = int1_unmask, +}; + +static void int2_mask(unsigned int irq) +{ + u32 intmr2; + + intmr2 = clps_readl(INTMR2); + intmr2 &= ~(1 << (irq - 16)); + clps_writel(intmr2, INTMR2); +} + +static void int2_ack(unsigned int irq) +{ + u32 intmr2; + + intmr2 = clps_readl(INTMR2); + intmr2 &= ~(1 << (irq - 16)); + clps_writel(intmr2, INTMR2); + + switch (irq) { + case IRQ_KBDINT: clps_writel(0, KBDEOI); break; + } +} + +static void int2_unmask(unsigned int irq) +{ + u32 intmr2; + + intmr2 = clps_readl(INTMR2); + intmr2 |= 1 << (irq - 16); + clps_writel(intmr2, INTMR2); +} + +static struct irqchip int2_chip = { + .ack = int2_ack, + .mask = int2_mask, + .unmask = int2_unmask, +}; + +void __init clps711x_init_irq(void) +{ + unsigned int i; + + for (i = 0; i < NR_IRQS; i++) { + if (INT1_IRQS & (1 << i)) { + set_irq_handler(i, do_level_IRQ); + set_irq_chip(i, &int1_chip); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + if (INT2_IRQS & (1 << i)) { + set_irq_handler(i, do_level_IRQ); + set_irq_chip(i, &int2_chip); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + } + + /* + * Disable interrupts + */ + clps_writel(0, INTMR1); + clps_writel(0, INTMR2); + + /* + * Clear down any pending interrupts + */ + clps_writel(0, COEOI); + clps_writel(0, TC1EOI); + clps_writel(0, TC2EOI); + clps_writel(0, RTCEOI); + clps_writel(0, TEOI); + clps_writel(0, UMSEOI); + clps_writel(0, SYNCIO); + clps_writel(0, KBDEOI); +} diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c new file mode 100644 index 0000000..120b7ca --- /dev/null +++ b/arch/arm/mach-clps711x/mm.c @@ -0,0 +1,43 @@ +/* + * linux/arch/arm/mach-clps711x/mm.c + * + * Generic MM setup for the CLPS711x-based machines. + * + * Copyright (C) 2001 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/mm.h> +#include <linux/init.h> +#include <linux/bootmem.h> + +#include <asm/hardware.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/mach/map.h> +#include <asm/hardware/clps7111.h> + +/* + * This maps the generic CLPS711x registers + */ +static struct map_desc clps711x_io_desc[] __initdata = { + { CLPS7111_VIRT_BASE, CLPS7111_PHYS_BASE, 1048576, MT_DEVICE } +}; + +void __init clps711x_map_io(void) +{ + iotable_init(clps711x_io_desc, ARRAY_SIZE(clps711x_io_desc)); +} diff --git a/arch/arm/mach-clps711x/p720t-leds.c b/arch/arm/mach-clps711x/p720t-leds.c new file mode 100644 index 0000000..4915b35 --- /dev/null +++ b/arch/arm/mach-clps711x/p720t-leds.c @@ -0,0 +1,67 @@ +/* + * linux/arch/arm/mach-clps711x/leds.c + * + * Integrator LED control routines + * + * 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> + +#include <asm/hardware/clps7111.h> +#include <asm/hardware/ep7212.h> + +static void p720t_leds_event(led_event_t ledevt) +{ + unsigned long flags; + u32 pddr; + + local_irq_save(flags); + switch(ledevt) { + case led_idle_start: + break; + + case led_idle_end: + break; + + case led_timer: + pddr = clps_readb(PDDR); + clps_writeb(pddr ^ 1, PDDR); + break; + + default: + break; + } + + local_irq_restore(flags); +} + +static int __init leds_init(void) +{ + if (machine_is_p720t()) + leds_event = p720t_leds_event; + + return 0; +} + +arch_initcall(leds_init); diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c new file mode 100644 index 0000000..29269df --- /dev/null +++ b/arch/arm/mach-clps711x/p720t.c @@ -0,0 +1,115 @@ +/* + * linux/arch/arm/mach-clps711x/p720t.c + * + * Copyright (C) 2000-2001 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/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/mm.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/arch/syspld.h> + +#include "common.h" + +/* + * Map the P720T system PLD. It occupies two address spaces: + * SYSPLD_PHYS_BASE and SYSPLD_PHYS_BASE + 0x00400000 + * We map both here. + */ +static struct map_desc p720t_io_desc[] __initdata = { + { SYSPLD_VIRT_BASE, SYSPLD_PHYS_BASE, 1048576, MT_DEVICE }, + { 0xfe400000, 0x10400000, 1048576, MT_DEVICE } +}; + +static void __init +fixup_p720t(struct machine_desc *desc, struct tag *tag, + char **cmdline, struct meminfo *mi) +{ + /* + * Our bootloader doesn't setup any tags (yet). + */ + if (tag->hdr.tag != ATAG_CORE) { + tag->hdr.tag = ATAG_CORE; + tag->hdr.size = tag_size(tag_core); + tag->u.core.flags = 0; + tag->u.core.pagesize = PAGE_SIZE; + tag->u.core.rootdev = 0x0100; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_MEM; + tag->hdr.size = tag_size(tag_mem32); + tag->u.mem.size = 4096; + tag->u.mem.start = PHYS_OFFSET; + + tag = tag_next(tag); + tag->hdr.tag = ATAG_NONE; + tag->hdr.size = 0; + } +} + +static void __init p720t_map_io(void) +{ + clps711x_map_io(); + iotable_init(p720t_io_desc, ARRAY_SIZE(p720t_io_desc)); +} + +MACHINE_START(P720T, "ARM-Prospector720T") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_p720t) + MAPIO(p720t_map_io) + INITIRQ(clps711x_init_irq) + .timer = &clps711x_timer, +MACHINE_END + +static int p720t_hw_init(void) +{ + /* + * Power down as much as possible in case we don't + * have the drivers loaded. + */ + PLD_LCDEN = 0; + PLD_PWR &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON); + + PLD_KBD = 0; + PLD_IO = 0; + PLD_IRDA = 0; + PLD_CODEC = 0; + PLD_TCH = 0; + PLD_SPI = 0; +#ifndef CONFIG_DEBUG_LL + PLD_COM2 = 0; + PLD_COM1 = 0; +#endif + + return 0; +} + +__initcall(p720t_hw_init); + diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c new file mode 100644 index 0000000..383d4e0 --- /dev/null +++ b/arch/arm/mach-clps711x/time.c @@ -0,0 +1,85 @@ +/* + * linux/arch/arm/mach-clps711x/time.c + * + * Copyright (C) 2001 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 version 2 as + * published by the Free Software Foundation. + * + * 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/timex.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/sched.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/leds.h> +#include <asm/io.h> +#include <asm/hardware/clps7111.h> + +#include <asm/mach/time.h> + + +/* + * gettimeoffset() returns time since last timer tick, in usecs. + * + * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. + * 'tick' is usecs per jiffy. + */ +static unsigned long clps711x_gettimeoffset(void) +{ + unsigned long hwticks; + hwticks = LATCH - (clps_readl(TC2D) & 0xffff); /* since last underflow */ + return (hwticks * (tick_nsec / 1000)) / LATCH; +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t +p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + timer_tick(regs); + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +static struct irqaction clps711x_timer_irq = { + .name = "CLPS711x Timer Tick", + .flags = SA_INTERRUPT, + .handler = p720t_timer_interrupt +}; + +static void __init clps711x_timer_init(void) +{ + struct timespec tv; + unsigned int syscon; + + syscon = clps_readl(SYSCON1); + syscon |= SYSCON1_TC2S | SYSCON1_TC2M; + clps_writel(syscon, SYSCON1); + + clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */ + + setup_irq(IRQ_TC2OI, &clps711x_timer_irq); + + tv.tv_nsec = 0; + tv.tv_sec = clps_readl(RTCDR); + do_settimeofday(&tv); +} + +struct sys_timer clps711x_timer = { + .init = clps711x_timer_init, + .offset = clps711x_gettimeoffset, +}; diff --git a/arch/arm/mach-clps7500/Makefile b/arch/arm/mach-clps7500/Makefile new file mode 100644 index 0000000..4bd8ebd --- /dev/null +++ b/arch/arm/mach-clps7500/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := core.o +obj-m := +obj-n := +obj- := + diff --git a/arch/arm/mach-clps7500/Makefile.boot b/arch/arm/mach-clps7500/Makefile.boot new file mode 100644 index 0000000..fe16506 --- /dev/null +++ b/arch/arm/mach-clps7500/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y := 0x10008000 + diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c new file mode 100644 index 0000000..fdfeded --- /dev/null +++ b/arch/arm/mach-clps7500/core.c @@ -0,0 +1,374 @@ +/* + * linux/arch/arm/mach-clps7500/core.c + * + * Copyright (C) 1998 Russell King + * Copyright (C) 1999 Nexus Electronics Ltd + * + * Extra MM routines for CL7500 architecture + */ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/serial_8250.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> + +#include <asm/hardware.h> +#include <asm/hardware/iomd.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +static void cl7500_ack_irq_a(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << irq; + val = iomd_readb(IOMD_IRQMASKA); + iomd_writeb(val & ~mask, IOMD_IRQMASKA); + iomd_writeb(mask, IOMD_IRQCLRA); +} + +static void cl7500_mask_irq_a(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << irq; + val = iomd_readb(IOMD_IRQMASKA); + iomd_writeb(val & ~mask, IOMD_IRQMASKA); +} + +static void cl7500_unmask_irq_a(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << irq; + val = iomd_readb(IOMD_IRQMASKA); + iomd_writeb(val | mask, IOMD_IRQMASKA); +} + +static struct irqchip clps7500_a_chip = { + .ack = cl7500_ack_irq_a, + .mask = cl7500_mask_irq_a, + .unmask = cl7500_unmask_irq_a, +}; + +static void cl7500_mask_irq_b(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_IRQMASKB); + iomd_writeb(val & ~mask, IOMD_IRQMASKB); +} + +static void cl7500_unmask_irq_b(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_IRQMASKB); + iomd_writeb(val | mask, IOMD_IRQMASKB); +} + +static struct irqchip clps7500_b_chip = { + .ack = cl7500_mask_irq_b, + .mask = cl7500_mask_irq_b, + .unmask = cl7500_unmask_irq_b, +}; + +static void cl7500_mask_irq_c(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_IRQMASKC); + iomd_writeb(val & ~mask, IOMD_IRQMASKC); +} + +static void cl7500_unmask_irq_c(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_IRQMASKC); + iomd_writeb(val | mask, IOMD_IRQMASKC); +} + +static struct irqchip clps7500_c_chip = { + .ack = cl7500_mask_irq_c, + .mask = cl7500_mask_irq_c, + .unmask = cl7500_unmask_irq_c, +}; + +static void cl7500_mask_irq_d(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_IRQMASKD); + iomd_writeb(val & ~mask, IOMD_IRQMASKD); +} + +static void cl7500_unmask_irq_d(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_IRQMASKD); + iomd_writeb(val | mask, IOMD_IRQMASKD); +} + +static struct irqchip clps7500_d_chip = { + .ack = cl7500_mask_irq_d, + .mask = cl7500_mask_irq_d, + .unmask = cl7500_unmask_irq_d, +}; + +static void cl7500_mask_irq_dma(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_DMAMASK); + iomd_writeb(val & ~mask, IOMD_DMAMASK); +} + +static void cl7500_unmask_irq_dma(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_DMAMASK); + iomd_writeb(val | mask, IOMD_DMAMASK); +} + +static struct irqchip clps7500_dma_chip = { + .ack = cl7500_mask_irq_dma, + .mask = cl7500_mask_irq_dma, + .unmask = cl7500_unmask_irq_dma, +}; + +static void cl7500_mask_irq_fiq(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_FIQMASK); + iomd_writeb(val & ~mask, IOMD_FIQMASK); +} + +static void cl7500_unmask_irq_fiq(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_FIQMASK); + iomd_writeb(val | mask, IOMD_FIQMASK); +} + +static struct irqchip clps7500_fiq_chip = { + .ack = cl7500_mask_irq_fiq, + .mask = cl7500_mask_irq_fiq, + .unmask = cl7500_unmask_irq_fiq, +}; + +static void cl7500_no_action(unsigned int irq) +{ +} + +static struct irqchip clps7500_no_chip = { + .ack = cl7500_no_action, + .mask = cl7500_no_action, + .unmask = cl7500_no_action, +}; + +static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL }; + +static void __init clps7500_init_irq(void) +{ + unsigned int irq, flags; + + iomd_writeb(0, IOMD_IRQMASKA); + iomd_writeb(0, IOMD_IRQMASKB); + iomd_writeb(0, IOMD_FIQMASK); + iomd_writeb(0, IOMD_DMAMASK); + + for (irq = 0; irq < NR_IRQS; irq++) { + flags = IRQF_VALID; + + if (irq <= 6 || (irq >= 9 && irq <= 15) || + (irq >= 48 && irq <= 55)) + flags |= IRQF_PROBE; + + switch (irq) { + case 0 ... 7: + set_irq_chip(irq, &clps7500_a_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 8 ... 15: + set_irq_chip(irq, &clps7500_b_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 16 ... 22: + set_irq_chip(irq, &clps7500_dma_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 24 ... 31: + set_irq_chip(irq, &clps7500_c_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 40 ... 47: + set_irq_chip(irq, &clps7500_d_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 48 ... 55: + set_irq_chip(irq, &clps7500_no_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 64 ... 72: + set_irq_chip(irq, &clps7500_fiq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + } + } + + setup_irq(IRQ_ISA, &irq_isa); +} + +static struct map_desc cl7500_io_desc[] __initdata = { + { IO_BASE, IO_START, IO_SIZE, MT_DEVICE }, /* IO space */ + { ISA_BASE, ISA_START, ISA_SIZE, MT_DEVICE }, /* ISA space */ + { FLASH_BASE, FLASH_START, FLASH_SIZE, MT_DEVICE }, /* Flash */ + { LED_BASE, LED_START, LED_SIZE, MT_DEVICE } /* LED */ +}; + +static void __init clps7500_map_io(void) +{ + iotable_init(cl7500_io_desc, ARRAY_SIZE(cl7500_io_desc)); +} + +extern void ioctime_init(void); +extern unsigned long ioc_timer_gettimeoffset(void); + +static irqreturn_t +clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + timer_tick(regs); + + /* Why not using do_leds interface?? */ + { + /* Twinkle the lights. */ + static int count, state = 0xff00; + if (count-- == 0) { + state ^= 0x100; + count = 25; + *((volatile unsigned int *)LED_ADDRESS) = state; + } + } + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction clps7500_timer_irq = { + .name = "CLPS7500 Timer Tick", + .flags = SA_INTERRUPT, + .handler = clps7500_timer_interrupt +}; + +/* + * Set up timer interrupt. + */ +static void __init clps7500_timer_init(void) +{ + ioctime_init(); + setup_irq(IRQ_TIMER, &clps7500_timer_irq); +} + +static struct sys_timer clps7500_timer = { + .init = clps7500_timer_init, + .offset = ioc_timer_gettimeoffset, +}; + +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = 0x03010fe0, + .irq = 10, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST, + }, + { + .mapbase = 0x03010be0, + .irq = 0, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST, + }, + { + .iobase = ISASLOT_IO + 0x2e8, + .irq = 41, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = ISASLOT_IO + 0x3e8, + .irq = 40, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static void __init clps7500_init(void) +{ + platform_device_register(&serial_device); +} + +MACHINE_START(CLPS7500, "CL-PS7500") + MAINTAINER("Philip Blundell") + BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) + MAPIO(clps7500_map_io) + INITIRQ(clps7500_init_irq) + .init_machine = clps7500_init, + .timer = &clps7500_timer, +MACHINE_END + diff --git a/arch/arm/mach-ebsa110/Makefile b/arch/arm/mach-ebsa110/Makefile new file mode 100644 index 0000000..6520ac8 --- /dev/null +++ b/arch/arm/mach-ebsa110/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := core.o io.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_LEDS) += leds.o diff --git a/arch/arm/mach-ebsa110/Makefile.boot b/arch/arm/mach-ebsa110/Makefile.boot new file mode 100644 index 0000000..2321260 --- /dev/null +++ b/arch/arm/mach-ebsa110/Makefile.boot @@ -0,0 +1,4 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000400 +initrd_phys-y := 0x00800000 + diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c new file mode 100644 index 0000000..ef362d4 --- /dev/null +++ b/arch/arm/mach-ebsa110/core.c @@ -0,0 +1,245 @@ +/* + * linux/arch/arm/mach-ebsa110/core.c + * + * Copyright (C) 1998-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. + * + * Extra MM routines for the EBSA-110 architecture + */ +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/interrupt.h> +#include <linux/serial_8250.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/system.h> + +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <asm/mach/map.h> + +#include <asm/mach/time.h> + +#define IRQ_MASK 0xfe000000 /* read */ +#define IRQ_MSET 0xfe000000 /* write */ +#define IRQ_STAT 0xff000000 /* read */ +#define IRQ_MCLR 0xff000000 /* write */ + +static void ebsa110_mask_irq(unsigned int irq) +{ + __raw_writeb(1 << irq, IRQ_MCLR); +} + +static void ebsa110_unmask_irq(unsigned int irq) +{ + __raw_writeb(1 << irq, IRQ_MSET); +} + +static struct irqchip ebsa110_irq_chip = { + .ack = ebsa110_mask_irq, + .mask = ebsa110_mask_irq, + .unmask = ebsa110_unmask_irq, +}; + +static void __init ebsa110_init_irq(void) +{ + unsigned long flags; + unsigned int irq; + + local_irq_save(flags); + __raw_writeb(0xff, IRQ_MCLR); + __raw_writeb(0x55, IRQ_MSET); + __raw_writeb(0x00, IRQ_MSET); + if (__raw_readb(IRQ_MASK) != 0x55) + while (1); + __raw_writeb(0xff, IRQ_MCLR); /* clear all interrupt enables */ + local_irq_restore(flags); + + for (irq = 0; irq < NR_IRQS; irq++) { + set_irq_chip(irq, &ebsa110_irq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } +} + +static struct map_desc ebsa110_io_desc[] __initdata = { + /* + * sparse external-decode ISAIO space + */ + { IRQ_STAT, TRICK4_PHYS, PGDIR_SIZE, MT_DEVICE }, /* IRQ_STAT/IRQ_MCLR */ + { IRQ_MASK, TRICK3_PHYS, PGDIR_SIZE, MT_DEVICE }, /* IRQ_MASK/IRQ_MSET */ + { SOFT_BASE, TRICK1_PHYS, PGDIR_SIZE, MT_DEVICE }, /* SOFT_BASE */ + { PIT_BASE, TRICK0_PHYS, PGDIR_SIZE, MT_DEVICE }, /* PIT_BASE */ + + /* + * self-decode ISAIO space + */ + { ISAIO_BASE, ISAIO_PHYS, ISAIO_SIZE, MT_DEVICE }, + { ISAMEM_BASE, ISAMEM_PHYS, ISAMEM_SIZE, MT_DEVICE } +}; + +static void __init ebsa110_map_io(void) +{ + iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc)); +} + + +#define PIT_CTRL (PIT_BASE + 0x0d) +#define PIT_T2 (PIT_BASE + 0x09) +#define PIT_T1 (PIT_BASE + 0x05) +#define PIT_T0 (PIT_BASE + 0x01) + +/* + * This is the rate at which your MCLK signal toggles (in Hz) + * This was measured on a 10 digit frequency counter sampling + * over 1 second. + */ +#define MCLK 47894000 + +/* + * This is the rate at which the PIT timers get clocked + */ +#define CLKBY7 (MCLK / 7) + +/* + * This is the counter value. We tick at 200Hz on this platform. + */ +#define COUNT ((CLKBY7 + (HZ / 2)) / HZ) + +/* + * Get the time offset from the system PIT. Note that if we have missed an + * interrupt, then the PIT counter will roll over (ie, be negative). + * This actually works out to be convenient. + */ +static unsigned long ebsa110_gettimeoffset(void) +{ + unsigned long offset, count; + + __raw_writeb(0x40, PIT_CTRL); + count = __raw_readb(PIT_T1); + count |= __raw_readb(PIT_T1) << 8; + + /* + * If count > COUNT, make the number negative. + */ + if (count > COUNT) + count |= 0xffff0000; + + offset = COUNT; + offset -= count; + + /* + * `offset' is in units of timer counts. Convert + * offset to units of microseconds. + */ + offset = offset * (1000000 / HZ) / COUNT; + + return offset; +} + +static irqreturn_t +ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 count; + + write_seqlock(&xtime_lock); + + /* latch and read timer 1 */ + __raw_writeb(0x40, PIT_CTRL); + count = __raw_readb(PIT_T1); + count |= __raw_readb(PIT_T1) << 8; + + count += COUNT; + + __raw_writeb(count & 0xff, PIT_T1); + __raw_writeb(count >> 8, PIT_T1); + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction ebsa110_timer_irq = { + .name = "EBSA110 Timer Tick", + .flags = SA_INTERRUPT, + .handler = ebsa110_timer_interrupt +}; + +/* + * Set up timer interrupt. + */ +static void __init ebsa110_timer_init(void) +{ + /* + * Timer 1, mode 2, LSB/MSB + */ + __raw_writeb(0x70, PIT_CTRL); + __raw_writeb(COUNT & 0xff, PIT_T1); + __raw_writeb(COUNT >> 8, PIT_T1); + + setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq); +} + +static struct sys_timer ebsa110_timer = { + .init = ebsa110_timer_init, + .offset = ebsa110_gettimeoffset, +}; + +static struct plat_serial8250_port serial_platform_data[] = { + { + .iobase = 0x3f8, + .irq = 1, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = 0x2f8, + .irq = 2, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static int __init ebsa110_init(void) +{ + return platform_device_register(&serial_device); +} + +arch_initcall(ebsa110_init); + +MACHINE_START(EBSA110, "EBSA110") + MAINTAINER("Russell King") + BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000) + BOOT_PARAMS(0x00000400) + DISABLE_PARPORT(0) + DISABLE_PARPORT(2) + SOFT_REBOOT + MAPIO(ebsa110_map_io) + INITIRQ(ebsa110_init_irq) + .timer = &ebsa110_timer, +MACHINE_END diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c new file mode 100644 index 0000000..ef7eb5d --- /dev/null +++ b/arch/arm/mach-ebsa110/io.c @@ -0,0 +1,378 @@ +/* + * linux/arch/arm/mach-ebsa110/isamem.c + * + * Copyright (C) 2001 Russell King + * + * Perform "ISA" memory and IO accesses. The EBSA110 has some "peculiarities" + * in the way it handles accesses to odd IO ports on 16-bit devices. These + * devices have their D0-D15 lines connected to the processors D0-D15 lines. + * Since they expect all byte IO operations to be performed on D0-D7, and the + * StrongARM expects to transfer the byte to these odd addresses on D8-D15, + * we must use a trick to get the required behaviour. + * + * The trick employed here is to use long word stores to odd address -1. The + * glue logic picks this up as a "trick" access, and asserts the LSB of the + * peripherals address bus, thereby accessing the odd IO port. Meanwhile, the + * StrongARM transfers its data on D0-D7 as expected. + * + * Things get more interesting on the pass-1 EBSA110 - the PCMCIA controller + * wiring was screwed in such a way that it had limited memory space access. + * Luckily, the work-around for this is not too horrible. See + * __isamem_convert_addr for the details. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include <asm/io.h> +#include <asm/page.h> + +static void __iomem *__isamem_convert_addr(void __iomem *addr) +{ + u32 ret, a = (u32 __force) addr; + + /* + * The PCMCIA controller is wired up as follows: + * +---------+---------+---------+---------+---------+---------+ + * PCMCIA | 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 | + * +---------+---------+---------+---------+---------+---------+ + * CPU | 2 2 2 2 | 2 1 1 1 | 1 1 1 1 | 1 1 1 | | | + * | 4 3 2 1 | 0 9 9 8 | 7 6 5 4 | 3 2 0 9 | 8 7 6 5 | 4 3 2 x | + * +---------+---------+---------+---------+---------+---------+ + * + * This means that we can access PCMCIA regions as follows: + * 0x*10000 -> 0x*1ffff + * 0x*70000 -> 0x*7ffff + * 0x*90000 -> 0x*9ffff + * 0x*f0000 -> 0x*fffff + */ + ret = (a & 0xf803fe) << 1; + ret |= (a & 0x03fc00) << 2; + + ret += 0xe8000000; + + if ((a & 0x20000) == (a & 0x40000) >> 1) + return (void __iomem *)ret; + + BUG(); + return NULL; +} + +/* + * read[bwl] and write[bwl] + */ +u8 __readb(void __iomem *addr) +{ + void __iomem *a = __isamem_convert_addr(addr); + u32 ret; + + if ((unsigned long)addr & 1) + ret = __raw_readl(a); + else + ret = __raw_readb(a); + return ret; +} + +u16 __readw(void __iomem *addr) +{ + void __iomem *a = __isamem_convert_addr(addr); + + if ((unsigned long)addr & 1) + BUG(); + + return __raw_readw(a); +} + +u32 __readl(void __iomem *addr) +{ + void __iomem *a = __isamem_convert_addr(addr); + u32 ret; + + if ((unsigned long)addr & 3) + BUG(); + + ret = __raw_readw(a); + ret |= __raw_readw(a + 4) << 16; + return ret; +} + +EXPORT_SYMBOL(__readb); +EXPORT_SYMBOL(__readw); +EXPORT_SYMBOL(__readl); + +void __writeb(u8 val, void __iomem *addr) +{ + void __iomem *a = __isamem_convert_addr(addr); + + if ((unsigned long)addr & 1) + __raw_writel(val, a); + else + __raw_writeb(val, a); +} + +void __writew(u16 val, void __iomem *addr) +{ + void __iomem *a = __isamem_convert_addr(addr); + + if ((unsigned long)addr & 1) + BUG(); + + __raw_writew(val, a); +} + +void __writel(u32 val, void __iomem *addr) +{ + void __iomem *a = __isamem_convert_addr(addr); + + if ((unsigned long)addr & 3) + BUG(); + + __raw_writew(val, a); + __raw_writew(val >> 16, a + 4); +} + +EXPORT_SYMBOL(__writeb); +EXPORT_SYMBOL(__writew); +EXPORT_SYMBOL(__writel); + +#define SUPERIO_PORT(p) \ + (((p) >> 3) == (0x3f8 >> 3) || \ + ((p) >> 3) == (0x2f8 >> 3) || \ + ((p) >> 3) == (0x378 >> 3)) + +/* + * We're addressing an 8 or 16-bit peripheral which tranfers + * odd addresses on the low ISA byte lane. + */ +u8 __inb8(unsigned int port) +{ + u32 ret; + + /* + * The SuperIO registers use sane addressing techniques... + */ + if (SUPERIO_PORT(port)) + ret = __raw_readb((void __iomem *)ISAIO_BASE + (port << 2)); + else { + void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1); + + /* + * Shame nothing else does + */ + if (port & 1) + ret = __raw_readl(a); + else + ret = __raw_readb(a); + } + return ret; +} + +/* + * We're addressing a 16-bit peripheral which transfers odd + * addresses on the high ISA byte lane. + */ +u8 __inb16(unsigned int port) +{ + unsigned int offset; + + /* + * The SuperIO registers use sane addressing techniques... + */ + if (SUPERIO_PORT(port)) + offset = port << 2; + else + offset = (port & ~1) << 1 | (port & 1); + + return __raw_readb((void __iomem *)ISAIO_BASE + offset); +} + +u16 __inw(unsigned int port) +{ + unsigned int offset; + + /* + * The SuperIO registers use sane addressing techniques... + */ + if (SUPERIO_PORT(port)) + offset = port << 2; + else { + offset = port << 1; + BUG_ON(port & 1); + } + return __raw_readw((void __iomem *)ISAIO_BASE + offset); +} + +/* + * Fake a 32-bit read with two 16-bit reads. Needed for 3c589. + */ +u32 __inl(unsigned int port) +{ + void __iomem *a; + + if (SUPERIO_PORT(port) || port & 3) + BUG(); + + a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1); + + return __raw_readw(a) | __raw_readw(a + 4) << 16; +} + +EXPORT_SYMBOL(__inb8); +EXPORT_SYMBOL(__inb16); +EXPORT_SYMBOL(__inw); +EXPORT_SYMBOL(__inl); + +void __outb8(u8 val, unsigned int port) +{ + /* + * The SuperIO registers use sane addressing techniques... + */ + if (SUPERIO_PORT(port)) + __raw_writeb(val, (void __iomem *)ISAIO_BASE + (port << 2)); + else { + void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1); + + /* + * Shame nothing else does + */ + if (port & 1) + __raw_writel(val, a); + else + __raw_writeb(val, a); + } +} + +void __outb16(u8 val, unsigned int port) +{ + unsigned int offset; + + /* + * The SuperIO registers use sane addressing techniques... + */ + if (SUPERIO_PORT(port)) + offset = port << 2; + else + offset = (port & ~1) << 1 | (port & 1); + + __raw_writeb(val, (void __iomem *)ISAIO_BASE + offset); +} + +void __outw(u16 val, unsigned int port) +{ + unsigned int offset; + + /* + * The SuperIO registers use sane addressing techniques... + */ + if (SUPERIO_PORT(port)) + offset = port << 2; + else { + offset = port << 1; + BUG_ON(port & 1); + } + __raw_writew(val, (void __iomem *)ISAIO_BASE + offset); +} + +void __outl(u32 val, unsigned int port) +{ + BUG(); +} + +EXPORT_SYMBOL(__outb8); +EXPORT_SYMBOL(__outb16); +EXPORT_SYMBOL(__outw); +EXPORT_SYMBOL(__outl); + +void outsb(unsigned int port, const void *from, int len) +{ + u32 off; + + if (SUPERIO_PORT(port)) + off = port << 2; + else { + off = (port & ~1) << 1; + if (port & 1) + BUG(); + } + + __raw_writesb((void __iomem *)ISAIO_BASE + off, from, len); +} + +void insb(unsigned int port, void *from, int len) +{ + u32 off; + + if (SUPERIO_PORT(port)) + off = port << 2; + else { + off = (port & ~1) << 1; + if (port & 1) + BUG(); + } + + __raw_readsb((void __iomem *)ISAIO_BASE + off, from, len); +} + +EXPORT_SYMBOL(outsb); +EXPORT_SYMBOL(insb); + +void outsw(unsigned int port, const void *from, int len) +{ + u32 off; + + if (SUPERIO_PORT(port)) + off = port << 2; + else { + off = (port & ~1) << 1; + if (port & 1) + BUG(); + } + + __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len); +} + +void insw(unsigned int port, void *from, int len) +{ + u32 off; + + if (SUPERIO_PORT(port)) + off = port << 2; + else { + off = (port & ~1) << 1; + if (port & 1) + BUG(); + } + + __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len); +} + +EXPORT_SYMBOL(outsw); +EXPORT_SYMBOL(insw); + +/* + * We implement these as 16-bit insw/outsw, mainly for + * 3c589 cards. + */ +void outsl(unsigned int port, const void *from, int len) +{ + u32 off = port << 1; + + if (SUPERIO_PORT(port) || port & 3) + BUG(); + + __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len << 1); +} + +void insl(unsigned int port, void *from, int len) +{ + u32 off = port << 1; + + if (SUPERIO_PORT(port) || port & 3) + BUG(); + + __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len << 1); +} + +EXPORT_SYMBOL(outsl); +EXPORT_SYMBOL(insl); diff --git a/arch/arm/mach-ebsa110/leds.c b/arch/arm/mach-ebsa110/leds.c new file mode 100644 index 0000000..3bc8c5e --- /dev/null +++ b/arch/arm/mach-ebsa110/leds.c @@ -0,0 +1,51 @@ +/* + * linux/arch/arm/mach-ebsa110/leds.c + * + * Copyright (C) 1998 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. + * + * EBSA-110 LED control routines. We use the led as follows: + * + * - Red - toggles state every 50 timer interrupts + */ +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> +#include <asm/mach-types.h> + +static spinlock_t leds_lock; + +static void ebsa110_leds_event(led_event_t ledevt) +{ + unsigned long flags; + + spin_lock_irqsave(&leds_lock, flags); + + switch(ledevt) { + case led_timer: + *(volatile unsigned char *)SOFT_BASE ^= 128; + break; + + default: + break; + } + + spin_unlock_irqrestore(&leds_lock, flags); +} + +static int __init leds_init(void) +{ + if (machine_is_ebsa110()) + leds_event = ebsa110_leds_event; + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-epxa10db/Kconfig b/arch/arm/mach-epxa10db/Kconfig new file mode 100644 index 0000000..55d896d --- /dev/null +++ b/arch/arm/mach-epxa10db/Kconfig @@ -0,0 +1,23 @@ +if ARCH_CAMELOT + +menu "Epxa10db" + +comment "PLD hotswap support" + +config PLD + bool + default y + +config PLD_HOTSWAP + bool "Support for PLD device hotplugging (experimental)" + depends on EXPERIMENTAL + help + This enables support for the dynamic loading and configuration of + compatible drivers when the contents of the PLD are changed. This + is still experimental and requires configuration tools which are + not yet generally available. Say N here. You must enable the kernel + module loader for this feature to work. + +endmenu + +endif diff --git a/arch/arm/mach-epxa10db/Makefile b/arch/arm/mach-epxa10db/Makefile new file mode 100644 index 0000000..24fbd7d --- /dev/null +++ b/arch/arm/mach-epxa10db/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := arch.o irq.o mm.o time.o +obj-m := +obj-n := +obj- := + diff --git a/arch/arm/mach-epxa10db/Makefile.boot b/arch/arm/mach-epxa10db/Makefile.boot new file mode 100644 index 0000000..28bec7d --- /dev/null +++ b/arch/arm/mach-epxa10db/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y := 0x00008000 + diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c new file mode 100644 index 0000000..1b40340 --- /dev/null +++ b/arch/arm/mach-epxa10db/arch.c @@ -0,0 +1,72 @@ +/* + * linux/arch/arm/mach-epxa10db/arch.c + * + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright (C) 2001 Altera Corporation + * + * 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/types.h> +#include <linux/init.h> +#include <linux/serial_8250.h> + +#include <asm/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> + +static struct plat_serial8250_port serial_platform_data[] = { + { + .iobase = 0x3f8, + .irq = IRQ_UARTINT0, +#error FIXME + .uartclk = 0, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = 0x2f8, + .irq = IRQ_UARTINT1, +#error FIXME + .uartclk = 0, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +extern void epxa10db_map_io(void); +extern void epxa10db_init_irq(void); +extern struct sys_timer epxa10db_timer; + +MACHINE_START(CAMELOT, "Altera Epxa10db") + MAINTAINER("Altera Corporation") + BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000) + MAPIO(epxa10db_map_io) + INITIRQ(epxa10db_init_irq) + .timer = &epxa10db_timer, +MACHINE_END + diff --git a/arch/arm/mach-epxa10db/dma.c b/arch/arm/mach-epxa10db/dma.c new file mode 100644 index 0000000..0151e9f --- /dev/null +++ b/arch/arm/mach-epxa10db/dma.c @@ -0,0 +1,28 @@ +/* + * linux/arch/arm/mach-epxa10db/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/init.h> + +#include <asm/dma.h> +#include <asm/mach/dma.h> + +void __init arch_dma_init(dma_t *dma) +{ +} diff --git a/arch/arm/mach-epxa10db/irq.c b/arch/arm/mach-epxa10db/irq.c new file mode 100644 index 0000000..9bf927e --- /dev/null +++ b/arch/arm/mach-epxa10db/irq.c @@ -0,0 +1,82 @@ +/* + * linux/arch/arm/mach-epxa10db/irq.c + * + * Copyright (C) 2001 Altera Corporation + * + * 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 <linux/ioport.h> +#include <linux/stddef.h> +#include <linux/timer.h> +#include <linux/list.h> +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/arch/platform.h> +#include <asm/arch/int_ctrl00.h> + + +static void epxa_mask_irq(unsigned int irq) +{ + writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); +} + +static void epxa_unmask_irq(unsigned int irq) +{ + writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE))); +} + + +static struct irqchip epxa_irq_chip = { + .ack = epxa_mask_irq, + .mask = epxa_mask_irq, + .unmask = epxa_unmask_irq, +}; + +static struct resource irq_resource = { + .name = "irq_handler", + .start = IO_ADDRESS(EXC_INT_CTRL00_BASE), + .end = IO_ADDRESS(INT_PRIORITY_FC(EXC_INT_CTRL00_BASE))+4, +}; + +void __init epxa10db_init_irq(void) +{ + unsigned int i; + + request_resource(&iomem_resource, &irq_resource); + + /* + * This bit sets up the interrupt controller using + * the 6 PLD interrupts mode (the default) each + * irqs is assigned a priority which is the same + * as its interrupt number. This scheme is used because + * its easy, but you may want to change it depending + * on the contents of your PLD + */ + + writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE))); + for (i = 0; i < NR_IRQS; i++){ + writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i)); + set_irq_chip(i,&epxa_irq_chip); + set_irq_handler(i,do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + + /* Disable all interrupts */ + writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); + +} diff --git a/arch/arm/mach-epxa10db/mm.c b/arch/arm/mach-epxa10db/mm.c new file mode 100644 index 0000000..2aa57fa --- /dev/null +++ b/arch/arm/mach-epxa10db/mm.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mach-epxa10db/mm.c + * + * MM routines for Altera'a Epxa10db board + * + * Copyright (C) 2001 Altera Corporation + * + * 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/sizes.h> + +#include <asm/mach/map.h> + +/* Page table mapping for I/O region */ + +static struct map_desc epxa10db_io_desc[] __initdata = { + { IO_ADDRESS(EXC_REGISTERS_BASE), EXC_REGISTERS_BASE, SZ_16K, MT_DEVICE }, + { IO_ADDRESS(EXC_PLD_BLOCK0_BASE), EXC_PLD_BLOCK0_BASE, SZ_16K, MT_DEVICE }, + { IO_ADDRESS(EXC_PLD_BLOCK1_BASE), EXC_PLD_BLOCK1_BASE, SZ_16K, MT_DEVICE }, + { IO_ADDRESS(EXC_PLD_BLOCK2_BASE), EXC_PLD_BLOCK2_BASE, SZ_16K, MT_DEVICE }, + { IO_ADDRESS(EXC_PLD_BLOCK3_BASE), EXC_PLD_BLOCK3_BASE, SZ_16K, MT_DEVICE }, + { FLASH_VADDR(EXC_EBI_BLOCK0_BASE), EXC_EBI_BLOCK0_BASE, SZ_16M, MT_DEVICE } +}; + +void __init epxa10db_map_io(void) +{ + iotable_init(epxa10db_io_desc, ARRAY_SIZE(epxa10db_io_desc)); +} diff --git a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c new file mode 100644 index 0000000..1b991f3 --- /dev/null +++ b/arch/arm/mach-epxa10db/time.c @@ -0,0 +1,78 @@ +/* + * linux/arch/arm/mach-epxa10db/time.c + * + * Copyright (C) 2000 Deep Blue Solutions + * Copyright (C) 2001 Altera Corporation + * + * 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/init.h> +#include <linux/interrupt.h> +#include <linux/sched.h> + +#include <asm/hardware.h> +#include <asm/system.h> +#include <asm/leds.h> + +#include <asm/mach/time.h> + +#define TIMER00_TYPE (volatile unsigned int*) +#include <asm/arch/timer00.h> + +static int epxa10db_set_rtc(void) +{ + return 1; +} + +static int epxa10db_rtc_init(void) +{ + set_rtc = epxa10db_set_rtc; + + return 0; +} + +__initcall(epxa10db_rtc_init); + + +/* + * IRQ handler for the timer + */ +static irqreturn_t +epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + // ...clear the interrupt + *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK; + + timer_tick(regs); + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction epxa10db_timer_irq = { + .name = "Excalibur Timer Tick", + .flags = SA_INTERRUPT, + .handler = epxa10db_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +static void __init epxa10db_timer_init(void) +{ + /* Start the timer */ + *TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200); + *TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1; + *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK; + + setup_irq(IRQ_TIMER0, &epxa10db_timer_irq); +} + +struct sys_timer epxa10db_timer = { + .init = epxa10db_timer_init, +}; diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig new file mode 100644 index 0000000..1090c68 --- /dev/null +++ b/arch/arm/mach-footbridge/Kconfig @@ -0,0 +1,80 @@ +if ARCH_FOOTBRIDGE + +menu "Footbridge Implementations" + +config ARCH_CATS + bool "CATS" + select FOOTBRIDGE_HOST + help + Say Y here if you intend to run this kernel on the CATS. + + Saying N will reduce the size of the Footbridge kernel. + +config ARCH_PERSONAL_SERVER + bool "Compaq Personal Server" + select FOOTBRIDGE_HOST + ---help--- + Say Y here if you intend to run this kernel on the Compaq + Personal Server. + + Saying N will reduce the size of the Footbridge kernel. + + The Compaq Personal Server is not available for purchase. + There are no product plans beyond the current research + prototypes at this time. Information is available at: + + <http://www.crl.hpl.hp.com/projects/personalserver/> + + If you have any questions or comments about the Compaq Personal + Server, send e-mail to <skiff@crl.dec.com>. + +config ARCH_EBSA285_ADDIN + bool "EBSA285 (addin mode)" + select ARCH_EBSA285 + select FOOTBRIDGE_ADDIN + help + Say Y here if you intend to run this kernel on the EBSA285 card + in addin mode. + + Saying N will reduce the size of the Footbridge kernel. + +config ARCH_EBSA285_HOST + bool "EBSA285 (host mode)" + select ARCH_EBSA285 + select FOOTBRIDGE_HOST + help + Say Y here if you intend to run this kernel on the EBSA285 card + in host ("central function") mode. + + Saying N will reduce the size of the Footbridge kernel. + +config ARCH_NETWINDER + bool "NetWinder" + select FOOTBRIDGE_HOST + help + Say Y here if you intend to run this kernel on the Rebel.COM + NetWinder. Information about this machine can be found at: + + <http://www.netwinder.org/> + + Saying N will reduce the size of the Footbridge kernel. + +endmenu + +# Footbridge support +config FOOTBRIDGE + bool + +# Footbridge in host mode +config FOOTBRIDGE_HOST + bool + +# Footbridge in addin mode +config FOOTBRIDGE_ADDIN + bool + +# EBSA285 board in either host or addin mode +config ARCH_EBSA285 + bool + +endif diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile new file mode 100644 index 0000000..0694ad6 --- /dev/null +++ b/arch/arm/mach-footbridge/Makefile @@ -0,0 +1,30 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := common.o dc21285.o dma.o isa-irq.o time.o +obj-m := +obj-n := +obj- := + +pci-$(CONFIG_ARCH_CATS) += cats-pci.o +pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o +pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o +pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o + +leds-$(CONFIG_ARCH_CO285) += ebsa285-leds.o +leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o +leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o + +obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o +obj-$(CONFIG_ARCH_CO285) += co285.o dc21285-timer.o +obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o +obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o +obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o + +obj-$(CONFIG_PCI) +=$(pci-y) +obj-$(CONFIG_LEDS) +=$(leds-y) + +obj-$(CONFIG_ISA) += isa.o diff --git a/arch/arm/mach-footbridge/Makefile.boot b/arch/arm/mach-footbridge/Makefile.boot new file mode 100644 index 0000000..c7e75ac --- /dev/null +++ b/arch/arm/mach-footbridge/Makefile.boot @@ -0,0 +1,4 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 + diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c new file mode 100644 index 0000000..d1ced86 --- /dev/null +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -0,0 +1,95 @@ +/* + * linux/arch/arm/mach-footbridge/cats-hw.c + * + * CATS machine fixup + * + * Copyright (C) 1998, 1999 Russell King, Phil Blundell + */ +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/tty.h> + +#include <asm/hardware/dec21285.h> +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/setup.h> + +#include <asm/mach/arch.h> + +#include "common.h" + +#define CFG_PORT 0x370 +#define INDEX_PORT (CFG_PORT) +#define DATA_PORT (CFG_PORT + 1) + +static int __init cats_hw_init(void) +{ + if (machine_is_cats()) { + /* Set Aladdin to CONFIGURE mode */ + outb(0x51, CFG_PORT); + outb(0x23, CFG_PORT); + + /* Select logical device 3 */ + outb(0x07, INDEX_PORT); + outb(0x03, DATA_PORT); + + /* Set parallel port to DMA channel 3, ECP+EPP1.9, + enable EPP timeout */ + outb(0x74, INDEX_PORT); + outb(0x03, DATA_PORT); + + outb(0xf0, INDEX_PORT); + outb(0x0f, DATA_PORT); + + outb(0xf1, INDEX_PORT); + outb(0x07, DATA_PORT); + + /* Select logical device 4 */ + outb(0x07, INDEX_PORT); + outb(0x04, DATA_PORT); + + /* UART1 high speed mode */ + outb(0xf0, INDEX_PORT); + outb(0x02, DATA_PORT); + + /* Select logical device 5 */ + outb(0x07, INDEX_PORT); + outb(0x05, DATA_PORT); + + /* UART2 high speed mode */ + outb(0xf0, INDEX_PORT); + outb(0x02, DATA_PORT); + + /* Set Aladdin to RUN mode */ + outb(0xbb, CFG_PORT); + } + + return 0; +} + +__initcall(cats_hw_init); + +/* + * CATS uses soft-reboot by default, since + * hard reboots fail on early boards. + */ +static void __init +fixup_cats(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + ORIG_VIDEO_LINES = 25; + ORIG_VIDEO_POINTS = 16; + ORIG_Y = 24; +} + +MACHINE_START(CATS, "Chalice-CATS") + MAINTAINER("Philip Blundell") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + SOFT_REBOOT + FIXUP(fixup_cats) + MAPIO(footbridge_map_io) + INITIRQ(footbridge_init_irq) + .timer = &isa_timer, +MACHINE_END diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c new file mode 100644 index 0000000..4f984fd --- /dev/null +++ b/arch/arm/mach-footbridge/cats-pci.c @@ -0,0 +1,55 @@ +/* + * linux/arch/arm/mach-footbridge/cats-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +/* cats host-specific stuff */ +static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; + +static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->irq >= 128) + return dev->irq & 0x1f; + + if (dev->irq >= 1 && dev->irq <= 4) + return irqmap_cats[dev->irq - 1]; + + if (dev->irq != 0) + printk("PCI: device %02x:%02x has unknown irq line %x\n", + dev->bus->number, dev->devfn, dev->irq); + + return -1; +} + +/* + * why not the standard PCI swizzle? does this prevent 4-port tulip + * cards being used (ie, pci-pci bridge based cards)? + */ +static struct hw_pci cats_pci __initdata = { + .swizzle = NULL, + .map_irq = cats_map_irq, + .nr_controllers = 1, + .setup = dc21285_setup, + .scan = dc21285_scan_bus, + .preinit = dc21285_preinit, + .postinit = dc21285_postinit, +}; + +static int cats_pci_init(void) +{ + if (machine_is_cats()) + pci_common_init(&cats_pci); + return 0; +} + +subsys_initcall(cats_pci_init); diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c new file mode 100644 index 0000000..e154191 --- /dev/null +++ b/arch/arm/mach-footbridge/co285.c @@ -0,0 +1,38 @@ +/* + * linux/arch/arm/mach-footbridge/co285.c + * + * CO285 machine fixup + */ +#include <linux/init.h> + +#include <asm/hardware/dec21285.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> + +#include "common.h" + +static void __init +fixup_coebsa285(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + extern unsigned long boot_memory_end; + extern char boot_command_line[]; + + mi->nr_banks = 1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].size = boot_memory_end; + mi->bank[0].node = 0; + + *cmdline = boot_command_line; +} + +MACHINE_START(CO285, "co-EBSA285") + MAINTAINER("Mark van Doesburg") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000) + FIXUP(fixup_coebsa285) + MAPIO(footbridge_map_io) + INITIRQ(footbridge_init_irq) + .timer = &footbridge_timer, +MACHINE_END + diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c new file mode 100644 index 0000000..eb8238c --- /dev/null +++ b/arch/arm/mach-footbridge/common.c @@ -0,0 +1,205 @@ +/* + * linux/arch/arm/mach-footbridge/common.c + * + * Copyright (C) 1998-2000 Russell King, Dave Gilbert. + * + * 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/module.h> +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/ioport.h> +#include <linux/list.h> +#include <linux/init.h> + +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/setup.h> +#include <asm/hardware/dec21285.h> + +#include <asm/mach/irq.h> +#include <asm/mach/map.h> + +#include "common.h" + +extern void __init isa_init_irq(unsigned int irq); + +unsigned int mem_fclk_21285 = 50000000; + +EXPORT_SYMBOL(mem_fclk_21285); + +static int __init parse_tag_memclk(const struct tag *tag) +{ + mem_fclk_21285 = tag->u.memclk.fmemclk; + return 0; +} + +__tagtable(ATAG_MEMCLK, parse_tag_memclk); + +/* + * Footbridge IRQ translation table + * Converts from our IRQ numbers into FootBridge masks + */ +static const int fb_irq_mask[] = { + IRQ_MASK_UART_RX, /* 0 */ + IRQ_MASK_UART_TX, /* 1 */ + IRQ_MASK_TIMER1, /* 2 */ + IRQ_MASK_TIMER2, /* 3 */ + IRQ_MASK_TIMER3, /* 4 */ + IRQ_MASK_IN0, /* 5 */ + IRQ_MASK_IN1, /* 6 */ + IRQ_MASK_IN2, /* 7 */ + IRQ_MASK_IN3, /* 8 */ + IRQ_MASK_DOORBELLHOST, /* 9 */ + IRQ_MASK_DMA1, /* 10 */ + IRQ_MASK_DMA2, /* 11 */ + IRQ_MASK_PCI, /* 12 */ + IRQ_MASK_SDRAMPARITY, /* 13 */ + IRQ_MASK_I2OINPOST, /* 14 */ + IRQ_MASK_PCI_ABORT, /* 15 */ + IRQ_MASK_PCI_SERR, /* 16 */ + IRQ_MASK_DISCARD_TIMER, /* 17 */ + IRQ_MASK_PCI_DPERR, /* 18 */ + IRQ_MASK_PCI_PERR, /* 19 */ +}; + +static void fb_mask_irq(unsigned int irq) +{ + *CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(irq)]; +} + +static void fb_unmask_irq(unsigned int irq) +{ + *CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(irq)]; +} + +static struct irqchip fb_chip = { + .ack = fb_mask_irq, + .mask = fb_mask_irq, + .unmask = fb_unmask_irq, +}; + +static void __init __fb_init_irq(void) +{ + unsigned int irq; + + /* + * setup DC21285 IRQs + */ + *CSR_IRQ_DISABLE = -1; + *CSR_FIQ_DISABLE = -1; + + for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) { + set_irq_chip(irq, &fb_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } +} + +void __init footbridge_init_irq(void) +{ + __fb_init_irq(); + + if (!footbridge_cfn_mode()) + return; + + if (machine_is_ebsa285()) + /* The following is dependent on which slot + * you plug the Southbridge card into. We + * currently assume that you plug it into + * the right-hand most slot. + */ + isa_init_irq(IRQ_PCI); + + if (machine_is_cats()) + isa_init_irq(IRQ_IN2); + + if (machine_is_netwinder()) + isa_init_irq(IRQ_IN3); +} + +/* + * Common mapping for all systems. Note that the outbound write flush is + * commented out since there is a "No Fix" problem with it. Not mapping + * it means that we have extra bullet protection on our feet. + */ +static struct map_desc fb_common_io_desc[] __initdata = { + { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, MT_DEVICE }, + { XBUS_BASE, 0x40000000, XBUS_SIZE, MT_DEVICE } +}; + +/* + * The mapping when the footbridge is in host mode. We don't map any of + * this when we are in add-in mode. + */ +static struct map_desc ebsa285_host_io_desc[] __initdata = { +#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST) + { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, MT_DEVICE }, + { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, MT_DEVICE }, + { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, MT_DEVICE }, + { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, MT_DEVICE }, + { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, MT_DEVICE } +#endif +}; + +/* + * The CO-ebsa285 mapping. + */ +static struct map_desc co285_io_desc[] __initdata = { +#ifdef CONFIG_ARCH_CO285 + { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, MT_DEVICE }, + { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, MT_DEVICE } +#endif +}; + +void __init footbridge_map_io(void) +{ + /* + * Set up the common mapping first; we need this to + * determine whether we're in host mode or not. + */ + iotable_init(fb_common_io_desc, ARRAY_SIZE(fb_common_io_desc)); + + /* + * Now, work out what we've got to map in addition on this + * platform. + */ + if (machine_is_co285()) + iotable_init(co285_io_desc, ARRAY_SIZE(co285_io_desc)); + if (footbridge_cfn_mode()) + iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc)); +} + +#ifdef CONFIG_FOOTBRIDGE_ADDIN + +/* + * These two functions convert virtual addresses to PCI addresses and PCI + * addresses to virtual addresses. Note that it is only legal to use these + * on memory obtained via get_zeroed_page or kmalloc. + */ +unsigned long __virt_to_bus(unsigned long res) +{ + WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory); + + return (res - PAGE_OFFSET) + (*CSR_PCISDRAMBASE & 0xfffffff0); +} +EXPORT_SYMBOL(__virt_to_bus); + +unsigned long __bus_to_virt(unsigned long res) +{ + res -= (*CSR_PCISDRAMBASE & 0xfffffff0); + res += PAGE_OFFSET; + + WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory); + + return res; +} +EXPORT_SYMBOL(__bus_to_virt); + +#endif diff --git a/arch/arm/mach-footbridge/common.h b/arch/arm/mach-footbridge/common.h new file mode 100644 index 0000000..580e31b --- /dev/null +++ b/arch/arm/mach-footbridge/common.h @@ -0,0 +1,9 @@ + +extern struct sys_timer footbridge_timer; +extern struct sys_timer isa_timer; + +extern void isa_rtc_init(void); + +extern void footbridge_map_io(void); +extern void footbridge_init_irq(void); + diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c new file mode 100644 index 0000000..580e1d4 --- /dev/null +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -0,0 +1,68 @@ +/* + * linux/arch/arm/mach-footbridge/dc21285-timer.c + * + * Copyright (C) 1998 Russell King. + * Copyright (C) 1998 Phil Blundell + */ +#include <linux/init.h> +#include <linux/interrupt.h> + +#include <asm/irq.h> + +#include <asm/hardware/dec21285.h> +#include <asm/mach/time.h> + +#include "common.h" + +/* + * Footbridge timer 1 support. + */ +static unsigned long timer1_latch; + +static unsigned long timer1_gettimeoffset (void) +{ + unsigned long value = timer1_latch - *CSR_TIMER1_VALUE; + + return ((tick_nsec / 1000) * value) / timer1_latch; +} + +static irqreturn_t +timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + *CSR_TIMER1_CLR = 0; + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction footbridge_timer_irq = { + .name = "Timer1 timer tick", + .handler = timer1_interrupt, + .flags = SA_INTERRUPT, +}; + +/* + * Set up timer interrupt. + */ +static void __init footbridge_timer_init(void) +{ + isa_rtc_init(); + + timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ); + + *CSR_TIMER1_CLR = 0; + *CSR_TIMER1_LOAD = timer1_latch; + *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; + + setup_irq(IRQ_TIMER1, &footbridge_timer_irq); +} + +struct sys_timer footbridge_timer = { + .init = footbridge_timer_init, + .offset = timer1_gettimeoffset, +}; diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c new file mode 100644 index 0000000..e79884ee --- /dev/null +++ b/arch/arm/mach-footbridge/dc21285.c @@ -0,0 +1,384 @@ +/* + * linux/arch/arm/kernel/dec21285.c: PCI functions for DC21285 + * + * Copyright (C) 1998-2001 Russell King + * Copyright (C) 1998-2000 Phil Blundell + * + * 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/pci.h> +#include <linux/ptrace.h> +#include <linux/interrupt.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/ioport.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/mach/pci.h> +#include <asm/hardware/dec21285.h> + +#define MAX_SLOTS 21 + +#define PCICMD_ABORT ((PCI_STATUS_REC_MASTER_ABORT| \ + PCI_STATUS_REC_TARGET_ABORT)<<16) + +#define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \ + PCI_STATUS_REC_MASTER_ABORT | \ + PCI_STATUS_REC_TARGET_ABORT | \ + PCI_STATUS_PARITY) << 16) + +extern int setup_arm_irq(int, struct irqaction *); +extern void pcibios_report_status(u_int status_mask, int warn); +extern void register_isa_ports(unsigned int, unsigned int, unsigned int); + +static unsigned long +dc21285_base_address(struct pci_bus *bus, unsigned int devfn) +{ + unsigned long addr = 0; + + if (bus->number == 0) { + if (PCI_SLOT(devfn) == 0) + /* + * For devfn 0, point at the 21285 + */ + addr = ARMCSR_BASE; + else { + devfn -= 1 << 3; + + if (devfn < PCI_DEVFN(MAX_SLOTS, 0)) + addr = PCICFG0_BASE | 0xc00000 | (devfn << 8); + } + } else + addr = PCICFG1_BASE | (bus->number << 16) | (devfn << 8); + + return addr; +} + +static int +dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = dc21285_base_address(bus, devfn); + u32 v = 0xffffffff; + + if (addr) + switch (size) { + case 1: + asm("ldr%?b %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where)); + break; + case 2: + asm("ldr%?h %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where)); + break; + case 4: + asm("ldr%? %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where)); + break; + } + + *value = v; + + v = *CSR_PCICMD; + if (v & PCICMD_ABORT) { + *CSR_PCICMD = v & (0xffff|PCICMD_ABORT); + return -1; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int +dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = dc21285_base_address(bus, devfn); + u32 v; + + if (addr) + switch (size) { + case 1: + asm("str%?b %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where)); + break; + case 2: + asm("str%?h %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where)); + break; + case 4: + asm("str%? %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where)); + break; + } + + v = *CSR_PCICMD; + if (v & PCICMD_ABORT) { + *CSR_PCICMD = v & (0xffff|PCICMD_ABORT); + return -1; + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops dc21285_ops = { + .read = dc21285_read_config, + .write = dc21285_write_config, +}; + +static struct timer_list serr_timer; +static struct timer_list perr_timer; + +static void dc21285_enable_error(unsigned long __data) +{ + switch (__data) { + case IRQ_PCI_SERR: + del_timer(&serr_timer); + break; + + case IRQ_PCI_PERR: + del_timer(&perr_timer); + break; + } + + enable_irq(__data); +} + +/* + * Warn on PCI errors. + */ +static irqreturn_t dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int cmd; + unsigned int status; + + cmd = *CSR_PCICMD; + status = cmd >> 16; + cmd = cmd & 0xffff; + + if (status & PCI_STATUS_REC_MASTER_ABORT) { + printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", + instruction_pointer(regs)); + cmd |= PCI_STATUS_REC_MASTER_ABORT << 16; + } + + if (status & PCI_STATUS_REC_TARGET_ABORT) { + printk(KERN_DEBUG "PCI: target abort: "); + pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT, 1); + printk("\n"); + + cmd |= PCI_STATUS_REC_TARGET_ABORT << 16; + } + + *CSR_PCICMD = cmd; + + return IRQ_HANDLED; +} + +static irqreturn_t dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct timer_list *timer = dev_id; + unsigned int cntl; + + printk(KERN_DEBUG "PCI: system error received: "); + pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1); + printk("\n"); + + cntl = *CSR_SA110_CNTL & 0xffffdf07; + *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR; + + /* + * back off this interrupt + */ + disable_irq(irq); + timer->expires = jiffies + HZ; + add_timer(timer); + + return IRQ_HANDLED; +} + +static irqreturn_t dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + printk(KERN_DEBUG "PCI: discard timer expired\n"); + *CSR_SA110_CNTL &= 0xffffde07; + + return IRQ_HANDLED; +} + +static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int cmd; + + printk(KERN_DEBUG "PCI: data parity error detected: "); + pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1); + printk("\n"); + + cmd = *CSR_PCICMD & 0xffff; + *CSR_PCICMD = cmd | 1 << 24; + + return IRQ_HANDLED; +} + +static irqreturn_t dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct timer_list *timer = dev_id; + unsigned int cmd; + + printk(KERN_DEBUG "PCI: parity error detected: "); + pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1); + printk("\n"); + + cmd = *CSR_PCICMD & 0xffff; + *CSR_PCICMD = cmd | 1 << 31; + + /* + * back off this interrupt + */ + disable_irq(irq); + timer->expires = jiffies + HZ; + add_timer(timer); + + return IRQ_HANDLED; +} + +int __init dc21285_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if (nr || !footbridge_cfn_mode()) + return 0; + + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) { + printk("out of memory for root bus resources"); + return 0; + } + + memset(res, 0, sizeof(struct resource) * 2); + + res[0].flags = IORESOURCE_MEM; + res[0].name = "Footbridge non-prefetch"; + res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; + res[1].name = "Footbridge prefetch"; + + allocate_resource(&iomem_resource, &res[1], 0x20000000, + 0xa0000000, 0xffffffff, 0x20000000, NULL, NULL); + allocate_resource(&iomem_resource, &res[0], 0x40000000, + 0x80000000, 0xffffffff, 0x40000000, NULL, NULL); + + sys->resource[0] = &ioport_resource; + sys->resource[1] = &res[0]; + sys->resource[2] = &res[1]; + sys->mem_offset = DC21285_PCI_MEM; + + return 1; +} + +struct pci_bus * __init dc21285_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(0, &dc21285_ops, sys); +} + +void __init dc21285_preinit(void) +{ + unsigned int mem_size, mem_mask; + int cfn_mode; + + mem_size = (unsigned int)high_memory - PAGE_OFFSET; + for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1) + if (mem_mask >= mem_size) + break; + + /* + * These registers need to be set up whether we're the + * central function or not. + */ + *CSR_SDRAMBASEMASK = (mem_mask - 1) & 0x0ffc0000; + *CSR_SDRAMBASEOFFSET = 0; + *CSR_ROMBASEMASK = 0x80000000; + *CSR_CSRBASEMASK = 0; + *CSR_CSRBASEOFFSET = 0; + *CSR_PCIADDR_EXTN = 0; + + cfn_mode = __footbridge_cfn_mode(); + + printk(KERN_INFO "PCI: DC21285 footbridge, revision %02lX, in " + "%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ? + "central function" : "addin"); + + if (footbridge_cfn_mode()) { + /* + * Clear any existing errors - we aren't + * interested in historical data... + */ + *CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) | + SA110_CNTL_RXSERR; + *CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS; + } + + init_timer(&serr_timer); + init_timer(&perr_timer); + + serr_timer.data = IRQ_PCI_SERR; + serr_timer.function = dc21285_enable_error; + perr_timer.data = IRQ_PCI_PERR; + perr_timer.function = dc21285_enable_error; + + /* + * We don't care if these fail. + */ + request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT, + "PCI system error", &serr_timer); + request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT, + "PCI parity error", &perr_timer); + request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, SA_INTERRUPT, + "PCI abort", NULL); + request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT, + "Discard timer", NULL); + request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, SA_INTERRUPT, + "PCI data parity", NULL); + + if (cfn_mode) { + static struct resource csrio; + + csrio.flags = IORESOURCE_IO; + csrio.name = "Footbridge"; + + allocate_resource(&ioport_resource, &csrio, 128, + 0xff00, 0xffff, 128, NULL, NULL); + + /* + * Map our SDRAM at a known address in PCI space, just in case + * the firmware had other ideas. Using a nonzero base is + * necessary, since some VGA cards forcefully use PCI addresses + * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards). + */ + *CSR_PCICSRBASE = 0xf4000000; + *CSR_PCICSRIOBASE = csrio.start; + *CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET); + *CSR_PCIROMBASE = 0; + *CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_INVALIDATE | PCICMD_ERROR_BITS; + } else if (footbridge_cfn_mode() != 0) { + /* + * If we are not compiled to accept "add-in" mode, then + * we are using a constant virt_to_bus translation which + * can not hope to cater for the way the host BIOS has + * set up the machine. + */ + panic("PCI: this kernel is compiled for central " + "function mode only"); + } +} + +void __init dc21285_postinit(void) +{ + register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0); +} diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c new file mode 100644 index 0000000..a6b1396 --- /dev/null +++ b/arch/arm/mach-footbridge/dma.c @@ -0,0 +1,54 @@ +/* + * linux/arch/arm/kernel/dma-ebsa285.c + * + * Copyright (C) 1998 Phil Blundell + * + * DMA functions specific to EBSA-285/CATS architectures + * + * Changelog: + * 09-Nov-1998 RMK Split out ISA DMA functions to dma-isa.c + * 17-Mar-1999 RMK Allow any EBSA285-like architecture to have + * ISA DMA controllers. + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/dma.h> +#include <asm/io.h> + +#include <asm/mach/dma.h> +#include <asm/hardware/dec21285.h> + +#if 0 +static int fb_dma_request(dmach_t channel, dma_t *dma) +{ + return -EINVAL; +} + +static void fb_dma_enable(dmach_t channel, dma_t *dma) +{ +} + +static void fb_dma_disable(dmach_t channel, dma_t *dma) +{ +} + +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 + if (footbridge_cfn_mode()) + isa_init_dma(dma + _ISA_DMA(0)); +#endif +} diff --git a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c new file mode 100644 index 0000000..2c7c363 --- /dev/null +++ b/arch/arm/mach-footbridge/ebsa285-leds.c @@ -0,0 +1,140 @@ +/* + * linux/arch/arm/mach-footbridge/ebsa285-leds.c + * + * Copyright (C) 1998-1999 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. + * EBSA-285 control routines. + * + * The EBSA-285 uses the leds as follows: + * - Green - toggles state every 50 timer interrupts + * - Amber - On if system is not idle + * - Red - currently unused + * + * Changelog: + * 02-05-1999 RMK Various cleanups + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/spinlock.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/mach-types.h> +#include <asm/system.h> + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 +static char led_state; +static char hw_led_state; + +static DEFINE_SPINLOCK(leds_lock); + +static void ebsa285_leds_event(led_event_t evt) +{ + unsigned long flags; + + spin_lock_irqsave(&leds_lock, flags); + + switch (evt) { + case led_start: + hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN; +#ifndef CONFIG_LEDS_CPU + hw_led_state |= XBUS_LED_AMBER; +#endif + led_state |= LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= XBUS_LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= XBUS_LED_AMBER; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~XBUS_LED_AMBER; + break; +#endif + + case led_halted: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~XBUS_LED_RED; + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~XBUS_LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= XBUS_LED_GREEN; + break; + + case led_amber_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~XBUS_LED_AMBER; + break; + + case led_amber_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= XBUS_LED_AMBER; + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~XBUS_LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= XBUS_LED_RED; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + *XBUS_LEDS = hw_led_state; + + spin_unlock_irqrestore(&leds_lock, flags); +} + +static int __init leds_init(void) +{ + if (machine_is_ebsa285() || machine_is_co285()) + leds_event = ebsa285_leds_event; + + leds_event(led_start); + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c new file mode 100644 index 0000000..720c0ba --- /dev/null +++ b/arch/arm/mach-footbridge/ebsa285-pci.c @@ -0,0 +1,48 @@ +/* + * linux/arch/arm/mach-footbridge/ebsa285-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; + +static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->vendor == PCI_VENDOR_ID_CONTAQ && + dev->device == PCI_DEVICE_ID_CONTAQ_82C693) + switch (PCI_FUNC(dev->devfn)) { + case 1: return 14; + case 2: return 15; + case 3: return 12; + } + + return irqmap_ebsa285[(slot + pin) & 3]; +} + +static struct hw_pci ebsa285_pci __initdata = { + .swizzle = pci_std_swizzle, + .map_irq = ebsa285_map_irq, + .nr_controllers = 1, + .setup = dc21285_setup, + .scan = dc21285_scan_bus, + .preinit = dc21285_preinit, + .postinit = dc21285_postinit, +}; + +static int __init ebsa285_init_pci(void) +{ + if (machine_is_ebsa285()) + pci_common_init(&ebsa285_pci); + return 0; +} + +subsys_initcall(ebsa285_init_pci); diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c new file mode 100644 index 0000000..d0931f5a --- /dev/null +++ b/arch/arm/mach-footbridge/ebsa285.c @@ -0,0 +1,24 @@ +/* + * linux/arch/arm/mach-footbridge/ebsa285.c + * + * EBSA285 machine fixup + */ +#include <linux/init.h> + +#include <asm/hardware/dec21285.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> + +#include "common.h" + +MACHINE_START(EBSA285, "EBSA285") + MAINTAINER("Russell King") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + VIDEO(0x000a0000, 0x000bffff) + MAPIO(footbridge_map_io) + INITIRQ(footbridge_init_irq) + .timer = &footbridge_timer, +MACHINE_END + diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c new file mode 100644 index 0000000..b210160 --- /dev/null +++ b/arch/arm/mach-footbridge/isa-irq.c @@ -0,0 +1,168 @@ +/* + * linux/arch/arm/mach-footbridge/irq.c + * + * Copyright (C) 1996-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. + * + * Changelog: + * 22-Aug-1998 RMK Restructured IRQ routines + * 03-Sep-1998 PJB Merged CATS support + * 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder + * 26-Jan-1999 PJB Don't use IACK on CATS + * 16-Mar-1999 RMK Added autodetect of ISA PICs + */ +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/init.h> + +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/hardware/dec21285.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/mach-types.h> + +static void isa_mask_pic_lo_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO); +} + +static void isa_ack_pic_lo_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO); + outb(0x20, PIC_LO); +} + +static void isa_unmask_pic_lo_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO); +} + +static struct irqchip isa_lo_chip = { + .ack = isa_ack_pic_lo_irq, + .mask = isa_mask_pic_lo_irq, + .unmask = isa_unmask_pic_lo_irq, +}; + +static void isa_mask_pic_hi_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI); +} + +static void isa_ack_pic_hi_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI); + outb(0x62, PIC_LO); + outb(0x20, PIC_HI); +} + +static void isa_unmask_pic_hi_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI); +} + +static struct irqchip isa_hi_chip = { + .ack = isa_ack_pic_hi_irq, + .mask = isa_mask_pic_hi_irq, + .unmask = isa_unmask_pic_hi_irq, +}; + +static void +isa_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE; + + if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) { + do_bad_IRQ(isa_irq, desc, regs); + return; + } + + desc = irq_desc + isa_irq; + desc->handle(isa_irq, desc, regs); +} + +static struct irqaction irq_cascade = { .handler = no_action, .name = "cascade", }; +static struct resource pic1_resource = { "pic1", 0x20, 0x3f }; +static struct resource pic2_resource = { "pic2", 0xa0, 0xbf }; + +void __init isa_init_irq(unsigned int host_irq) +{ + unsigned int irq; + + /* + * Setup, and then probe for an ISA PIC + * If the PIC is not there, then we + * ignore the PIC. + */ + outb(0x11, PIC_LO); + outb(_ISA_IRQ(0), PIC_MASK_LO); /* IRQ number */ + outb(0x04, PIC_MASK_LO); /* Slave on Ch2 */ + outb(0x01, PIC_MASK_LO); /* x86 */ + outb(0xf5, PIC_MASK_LO); /* pattern: 11110101 */ + + outb(0x11, PIC_HI); + outb(_ISA_IRQ(8), PIC_MASK_HI); /* IRQ number */ + outb(0x02, PIC_MASK_HI); /* Slave on Ch1 */ + outb(0x01, PIC_MASK_HI); /* x86 */ + outb(0xfa, PIC_MASK_HI); /* pattern: 11111010 */ + + outb(0x0b, PIC_LO); + outb(0x0b, PIC_HI); + + if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) { + outb(0xff, PIC_MASK_LO);/* mask all IRQs */ + outb(0xff, PIC_MASK_HI);/* mask all IRQs */ + } else { + printk(KERN_INFO "IRQ: ISA PIC not found\n"); + host_irq = (unsigned int)-1; + } + + if (host_irq != (unsigned int)-1) { + for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) { + set_irq_chip(irq, &isa_lo_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) { + set_irq_chip(irq, &isa_hi_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + request_resource(&ioport_resource, &pic1_resource); + request_resource(&ioport_resource, &pic2_resource); + setup_irq(IRQ_ISA_CASCADE, &irq_cascade); + + set_irq_chained_handler(host_irq, isa_irq_handler); + + /* + * On the NetWinder, don't automatically + * enable ISA IRQ11 when it is requested. + * There appears to be a missing pull-up + * resistor on this line. + */ + if (machine_is_netwinder()) + set_irq_flags(_ISA_IRQ(11), IRQF_VALID | + IRQF_PROBE | IRQF_NOAUTOEN); + } +} + + diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c new file mode 100644 index 0000000..a4fefa0 --- /dev/null +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -0,0 +1,94 @@ +/* + * linux/arch/arm/mach-footbridge/isa-timer.c + * + * Copyright (C) 1998 Russell King. + * Copyright (C) 1998 Phil Blundell + */ +#include <linux/init.h> +#include <linux/interrupt.h> + +#include <asm/io.h> +#include <asm/irq.h> + +#include <asm/mach/time.h> + +#include "common.h" + +/* + * ISA timer tick support + */ +#define mSEC_10_from_14 ((14318180 + 100) / 200) + +static unsigned long isa_gettimeoffset(void) +{ + int count; + + static int count_p = (mSEC_10_from_14/6); /* for the first call after boot */ + static unsigned long jiffies_p = 0; + + /* + * cache volatile jiffies temporarily; we have IRQs turned off. + */ + unsigned long jiffies_t; + + /* timer count may underflow right here */ + outb_p(0x00, 0x43); /* latch the count ASAP */ + + count = inb_p(0x40); /* read the latched count */ + + /* + * We do this guaranteed double memory access instead of a _p + * postfix in the previous port access. Wheee, hackady hack + */ + jiffies_t = jiffies; + + count |= inb_p(0x40) << 8; + + /* Detect timer underflows. If we haven't had a timer tick since + the last time we were called, and time is apparently going + backwards, the counter must have wrapped during this routine. */ + if ((jiffies_t == jiffies_p) && (count > count_p)) + count -= (mSEC_10_from_14/6); + else + jiffies_p = jiffies_t; + + count_p = count; + + count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000); + count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6); + + return count; +} + +static irqreturn_t +isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + timer_tick(regs); + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +static struct irqaction isa_timer_irq = { + .name = "ISA timer tick", + .handler = isa_timer_interrupt, + .flags = SA_INTERRUPT, +}; + +static void __init isa_timer_init(void) +{ + isa_rtc_init(); + + /* enable PIT timer */ + /* set for periodic (4) and LSB/MSB write (0x30) */ + outb(0x34, 0x43); + outb((mSEC_10_from_14/6) & 0xFF, 0x40); + outb((mSEC_10_from_14/6) >> 8, 0x40); + + setup_irq(IRQ_ISA_TIMER, &isa_timer_irq); +} + +struct sys_timer isa_timer = { + .init = isa_timer_init, + .offset = isa_gettimeoffset, +}; diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c new file mode 100644 index 0000000..aa3a1fe --- /dev/null +++ b/arch/arm/mach-footbridge/isa.c @@ -0,0 +1,48 @@ +/* + * linux/arch/arm/mach-footbridge/isa.c + * + * Copyright (C) 2004 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/init.h> +#include <linux/serial_8250.h> + +#include <asm/irq.h> + +static struct plat_serial8250_port serial_platform_data[] = { + { + .iobase = 0x3f8, + .irq = IRQ_ISA_UART, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = 0x2f8, + .irq = IRQ_ISA_UART2, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static int __init footbridge_isa_init(void) +{ + return platform_device_register(&serial_device); +} + +arch_initcall(footbridge_isa_init); diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c new file mode 100644 index 0000000..1e1dfd7 --- /dev/null +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -0,0 +1,660 @@ +/* + * linux/arch/arm/mach-footbridge/netwinder-hw.c + * + * Netwinder machine fixup + * + * Copyright (C) 1998, 1999 Russell King, Phil Blundell + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/init.h> + +#include <asm/hardware/dec21285.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/mach-types.h> +#include <asm/setup.h> + +#include <asm/mach/arch.h> + +#include "common.h" + +#define IRDA_IO_BASE 0x180 +#define GP1_IO_BASE 0x338 +#define GP2_IO_BASE 0x33a + + +#ifdef CONFIG_LEDS +#define DEFAULT_LEDS 0 +#else +#define DEFAULT_LEDS GPIO_GREEN_LED +#endif + +/* + * Winbond WB83977F accessibility stuff + */ +static inline void wb977_open(void) +{ + outb(0x87, 0x370); + outb(0x87, 0x370); +} + +static inline void wb977_close(void) +{ + outb(0xaa, 0x370); +} + +static inline void wb977_wb(int reg, int val) +{ + outb(reg, 0x370); + outb(val, 0x371); +} + +static inline void wb977_ww(int reg, int val) +{ + outb(reg, 0x370); + outb(val >> 8, 0x371); + outb(reg + 1, 0x370); + outb(val & 255, 0x371); +} + +#define wb977_device_select(dev) wb977_wb(0x07, dev) +#define wb977_device_disable() wb977_wb(0x30, 0x00) +#define wb977_device_enable() wb977_wb(0x30, 0x01) + +/* + * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE + */ +DEFINE_SPINLOCK(gpio_lock); + +static unsigned int current_gpio_op; +static unsigned int current_gpio_io; +static unsigned int current_cpld; + +void gpio_modify_op(int mask, int set) +{ + unsigned int new_gpio, changed; + + new_gpio = (current_gpio_op & ~mask) | set; + changed = new_gpio ^ current_gpio_op; + current_gpio_op = new_gpio; + + if (changed & 0xff) + outb(new_gpio, GP1_IO_BASE); + if (changed & 0xff00) + outb(new_gpio >> 8, GP2_IO_BASE); +} + +static inline void __gpio_modify_io(int mask, int in) +{ + unsigned int new_gpio, changed; + int port; + + new_gpio = (current_gpio_io & ~mask) | in; + changed = new_gpio ^ current_gpio_io; + current_gpio_io = new_gpio; + + changed >>= 1; + new_gpio >>= 1; + + wb977_device_select(7); + + for (port = 0xe1; changed && port < 0xe8; changed >>= 1) { + wb977_wb(port, new_gpio & 1); + + port += 1; + new_gpio >>= 1; + } + + wb977_device_select(8); + + for (port = 0xe8; changed && port < 0xec; changed >>= 1) { + wb977_wb(port, new_gpio & 1); + + port += 1; + new_gpio >>= 1; + } +} + +void gpio_modify_io(int mask, int in) +{ + /* Open up the SuperIO chip */ + wb977_open(); + + __gpio_modify_io(mask, in); + + /* Close up the EFER gate */ + wb977_close(); +} + +int gpio_read(void) +{ + return inb(GP1_IO_BASE) | inb(GP2_IO_BASE) << 8; +} + +/* + * Initialise the Winbond W83977F global registers + */ +static inline void wb977_init_global(void) +{ + /* + * Enable R/W config registers + */ + wb977_wb(0x26, 0x40); + + /* + * Power down FDC (not used) + */ + wb977_wb(0x22, 0xfe); + + /* + * GP12, GP11, CIRRX, IRRXH, GP10 + */ + wb977_wb(0x2a, 0xc1); + + /* + * GP23, GP22, GP21, GP20, GP13 + */ + wb977_wb(0x2b, 0x6b); + + /* + * GP17, GP16, GP15, GP14 + */ + wb977_wb(0x2c, 0x55); +} + +/* + * Initialise the Winbond W83977F printer port + */ +static inline void wb977_init_printer(void) +{ + wb977_device_select(1); + + /* + * mode 1 == EPP + */ + wb977_wb(0xf0, 0x01); +} + +/* + * Initialise the Winbond W83977F keyboard controller + */ +static inline void wb977_init_keyboard(void) +{ + wb977_device_select(5); + + /* + * Keyboard controller address + */ + wb977_ww(0x60, 0x0060); + wb977_ww(0x62, 0x0064); + + /* + * Keyboard IRQ 1, active high, edge trigger + */ + wb977_wb(0x70, 1); + wb977_wb(0x71, 0x02); + + /* + * Mouse IRQ 5, active high, edge trigger + */ + wb977_wb(0x72, 5); + wb977_wb(0x73, 0x02); + + /* + * KBC 8MHz + */ + wb977_wb(0xf0, 0x40); + + /* + * Enable device + */ + wb977_device_enable(); +} + +/* + * Initialise the Winbond W83977F Infra-Red device + */ +static inline void wb977_init_irda(void) +{ + wb977_device_select(6); + + /* + * IR base address + */ + wb977_ww(0x60, IRDA_IO_BASE); + + /* + * IRDA IRQ 6, active high, edge trigger + */ + wb977_wb(0x70, 6); + wb977_wb(0x71, 0x02); + + /* + * RX DMA - ISA DMA 0 + */ + wb977_wb(0x74, 0x00); + + /* + * TX DMA - Disable Tx DMA + */ + wb977_wb(0x75, 0x04); + + /* + * Append CRC, Enable bank selection + */ + wb977_wb(0xf0, 0x03); + + /* + * Enable device + */ + wb977_device_enable(); +} + +/* + * Initialise Winbond W83977F general purpose IO + */ +static inline void wb977_init_gpio(void) +{ + unsigned long flags; + + /* + * Set up initial I/O definitions + */ + current_gpio_io = -1; + __gpio_modify_io(-1, GPIO_DONE | GPIO_WDTIMER); + + wb977_device_select(7); + + /* + * Group1 base address + */ + wb977_ww(0x60, GP1_IO_BASE); + wb977_ww(0x62, 0); + wb977_ww(0x64, 0); + + /* + * GP10 (Orage button) IRQ 10, active high, edge trigger + */ + wb977_wb(0x70, 10); + wb977_wb(0x71, 0x02); + + /* + * GP10: Debounce filter enabled, IRQ, input + */ + wb977_wb(0xe0, 0x19); + + /* + * Enable Group1 + */ + wb977_device_enable(); + + wb977_device_select(8); + + /* + * Group2 base address + */ + wb977_ww(0x60, GP2_IO_BASE); + + /* + * Clear watchdog timer regs + * - timer disable + */ + wb977_wb(0xf2, 0x00); + + /* + * - disable LED, no mouse nor keyboard IRQ + */ + wb977_wb(0xf3, 0x00); + + /* + * - timer counting, disable power LED, disable timeouot + */ + wb977_wb(0xf4, 0x00); + + /* + * Enable group2 + */ + wb977_device_enable(); + + /* + * Set Group1/Group2 outputs + */ + spin_lock_irqsave(&gpio_lock, flags); + gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN); + spin_unlock_irqrestore(&gpio_lock, flags); +} + +/* + * Initialise the Winbond W83977F chip. + */ +static void __init wb977_init(void) +{ + request_region(0x370, 2, "W83977AF configuration"); + + /* + * Open up the SuperIO chip + */ + wb977_open(); + + /* + * Initialise the global registers + */ + wb977_init_global(); + + /* + * Initialise the various devices in + * the multi-IO chip. + */ + wb977_init_printer(); + wb977_init_keyboard(); + wb977_init_irda(); + wb977_init_gpio(); + + /* + * Close up the EFER gate + */ + wb977_close(); +} + +void cpld_modify(int mask, int set) +{ + int msk; + + current_cpld = (current_cpld & ~mask) | set; + + gpio_modify_io(GPIO_DATA | GPIO_IOCLK | GPIO_IOLOAD, 0); + gpio_modify_op(GPIO_IOLOAD, 0); + + for (msk = 8; msk; msk >>= 1) { + int bit = current_cpld & msk; + + gpio_modify_op(GPIO_DATA | GPIO_IOCLK, bit ? GPIO_DATA : 0); + gpio_modify_op(GPIO_IOCLK, GPIO_IOCLK); + } + + gpio_modify_op(GPIO_IOCLK|GPIO_DATA, 0); + gpio_modify_op(GPIO_IOLOAD|GPIO_DSCLK, GPIO_IOLOAD|GPIO_DSCLK); + gpio_modify_op(GPIO_IOLOAD, 0); +} + +static void __init cpld_init(void) +{ + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE); + spin_unlock_irqrestore(&gpio_lock, flags); +} + +static unsigned char rwa_unlock[] __initdata = +{ 0x00, 0x00, 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b, + 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74, + 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 }; + +#ifndef DEBUG +#define dprintk(x...) +#else +#define dprintk(x...) printk(x) +#endif + +#define WRITE_RWA(r,v) do { outb((r), 0x279); udelay(10); outb((v), 0xa79); } while (0) + +static inline void rwa010_unlock(void) +{ + int i; + + WRITE_RWA(2, 2); + mdelay(10); + + for (i = 0; i < sizeof(rwa_unlock); i++) { + outb(rwa_unlock[i], 0x279); + udelay(10); + } +} + +static inline void rwa010_read_ident(void) +{ + unsigned char si[9]; + int i, j; + + WRITE_RWA(3, 0); + WRITE_RWA(0, 128); + + outb(1, 0x279); + + mdelay(1); + + dprintk("Identifier: "); + for (i = 0; i < 9; i++) { + si[i] = 0; + for (j = 0; j < 8; j++) { + int bit; + udelay(250); + inb(0x203); + udelay(250); + bit = inb(0x203); + dprintk("%02X ", bit); + bit = (bit == 0xaa) ? 1 : 0; + si[i] |= bit << j; + } + dprintk("(%02X) ", si[i]); + } + dprintk("\n"); +} + +static inline void rwa010_global_init(void) +{ + WRITE_RWA(6, 2); // Assign a card no = 2 + + dprintk("Card no = %d\n", inb(0x203)); + + /* disable the modem section of the chip */ + WRITE_RWA(7, 3); + WRITE_RWA(0x30, 0); + + /* disable the cdrom section of the chip */ + WRITE_RWA(7, 4); + WRITE_RWA(0x30, 0); + + /* disable the MPU-401 section of the chip */ + WRITE_RWA(7, 2); + WRITE_RWA(0x30, 0); +} + +static inline void rwa010_game_port_init(void) +{ + int i; + + WRITE_RWA(7, 5); + + dprintk("Slider base: "); + WRITE_RWA(0x61, 1); + i = inb(0x203); + + WRITE_RWA(0x60, 2); + dprintk("%02X%02X (201)\n", inb(0x203), i); + + WRITE_RWA(0x30, 1); +} + +static inline void rwa010_waveartist_init(int base, int irq, int dma) +{ + int i; + + WRITE_RWA(7, 0); + + dprintk("WaveArtist base: "); + WRITE_RWA(0x61, base & 255); + i = inb(0x203); + + WRITE_RWA(0x60, base >> 8); + dprintk("%02X%02X (%X),", inb(0x203), i, base); + + WRITE_RWA(0x70, irq); + dprintk(" irq: %d (%d),", inb(0x203), irq); + + WRITE_RWA(0x74, dma); + dprintk(" dma: %d (%d)\n", inb(0x203), dma); + + WRITE_RWA(0x30, 1); +} + +static inline void rwa010_soundblaster_init(int sb_base, int al_base, int irq, int dma) +{ + int i; + + WRITE_RWA(7, 1); + + dprintk("SoundBlaster base: "); + WRITE_RWA(0x61, sb_base & 255); + i = inb(0x203); + + WRITE_RWA(0x60, sb_base >> 8); + dprintk("%02X%02X (%X),", inb(0x203), i, sb_base); + + dprintk(" irq: "); + WRITE_RWA(0x70, irq); + dprintk("%d (%d),", inb(0x203), irq); + + dprintk(" 8-bit DMA: "); + WRITE_RWA(0x74, dma); + dprintk("%d (%d)\n", inb(0x203), dma); + + dprintk("AdLib base: "); + WRITE_RWA(0x63, al_base & 255); + i = inb(0x203); + + WRITE_RWA(0x62, al_base >> 8); + dprintk("%02X%02X (%X)\n", inb(0x203), i, al_base); + + WRITE_RWA(0x30, 1); +} + +static void rwa010_soundblaster_reset(void) +{ + int i; + + outb(1, 0x226); + udelay(3); + outb(0, 0x226); + + for (i = 0; i < 5; i++) { + if (inb(0x22e) & 0x80) + break; + mdelay(1); + } + if (i == 5) + printk("SoundBlaster: DSP reset failed\n"); + + dprintk("SoundBlaster DSP reset: %02X (AA)\n", inb(0x22a)); + + for (i = 0; i < 5; i++) { + if ((inb(0x22c) & 0x80) == 0) + break; + mdelay(1); + } + + if (i == 5) + printk("SoundBlaster: DSP not ready\n"); + else { + outb(0xe1, 0x22c); + + dprintk("SoundBlaster DSP id: "); + i = inb(0x22a); + udelay(1); + i |= inb(0x22a) << 8; + dprintk("%04X\n", i); + + for (i = 0; i < 5; i++) { + if ((inb(0x22c) & 0x80) == 0) + break; + mdelay(1); + } + + if (i == 5) + printk("SoundBlaster: could not turn speaker off\n"); + + outb(0xd3, 0x22c); + } + + /* turn on OPL3 */ + outb(5, 0x38a); + outb(1, 0x38b); +} + +static void __init rwa010_init(void) +{ + rwa010_unlock(); + rwa010_read_ident(); + rwa010_global_init(); + rwa010_game_port_init(); + rwa010_waveartist_init(0x250, 3, 7); + rwa010_soundblaster_init(0x220, 0x388, 3, 1); + rwa010_soundblaster_reset(); +} + +EXPORT_SYMBOL(gpio_lock); +EXPORT_SYMBOL(gpio_modify_op); +EXPORT_SYMBOL(gpio_modify_io); +EXPORT_SYMBOL(cpld_modify); + +/* + * Initialise any other hardware after we've got the PCI bus + * initialised. We may need the PCI bus to talk to this other + * hardware. + */ +static int __init nw_hw_init(void) +{ + if (machine_is_netwinder()) { + unsigned long flags; + + wb977_init(); + cpld_init(); + rwa010_init(); + + spin_lock_irqsave(&gpio_lock, flags); + gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS); + spin_unlock_irqrestore(&gpio_lock, flags); + } + return 0; +} + +__initcall(nw_hw_init); + +/* + * Older NeTTroms either do not provide a parameters + * page, or they don't supply correct information in + * the parameter page. + */ +static void __init +fixup_netwinder(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ +#ifdef CONFIG_ISAPNP + extern int isapnp_disable; + + /* + * We must not use the kernels ISAPnP code + * on the NetWinder - it will reset the settings + * for the WaveArtist chip and render it inoperable. + */ + isapnp_disable = 1; +#endif +} + +MACHINE_START(NETWINDER, "Rebel-NetWinder") + MAINTAINER("Russell King/Rebel.com") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + VIDEO(0x000a0000, 0x000bffff) + DISABLE_PARPORT(0) + DISABLE_PARPORT(2) + FIXUP(fixup_netwinder) + MAPIO(footbridge_map_io) + INITIRQ(footbridge_init_irq) + .timer = &isa_timer, +MACHINE_END diff --git a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c new file mode 100644 index 0000000..7451fc0 --- /dev/null +++ b/arch/arm/mach-footbridge/netwinder-leds.c @@ -0,0 +1,141 @@ +/* + * linux/arch/arm/mach-footbridge/netwinder-leds.c + * + * Copyright (C) 1998-1999 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. + * + * NetWinder LED control routines. + * + * The Netwinder uses the leds as follows: + * - Green - toggles state every 50 timer interrupts + * - Red - On if the system is not idle + * + * Changelog: + * 02-05-1999 RMK Various cleanups + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/spinlock.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/mach-types.h> +#include <asm/system.h> + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 +static char led_state; +static char hw_led_state; + +static DEFINE_SPINLOCK(leds_lock); +extern spinlock_t gpio_lock; + +static void netwinder_leds_event(led_event_t evt) +{ + unsigned long flags; + + spin_lock_irqsave(&leds_lock, flags); + + switch (evt) { + case led_start: + led_state |= LED_STATE_ENABLED; + hw_led_state = GPIO_GREEN_LED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= GPIO_GREEN_LED; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~GPIO_RED_LED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= GPIO_RED_LED; + break; +#endif + + case led_halted: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= GPIO_RED_LED; + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_GREEN_LED; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~GPIO_GREEN_LED; + break; + + case led_amber_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED; + break; + + case led_amber_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED); + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_RED_LED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~GPIO_RED_LED; + break; + + default: + break; + } + + spin_unlock_irqrestore(&leds_lock, flags); + + if (led_state & LED_STATE_ENABLED) { + spin_lock_irqsave(&gpio_lock, flags); + gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state); + spin_unlock_irqrestore(&gpio_lock, flags); + } +} + +static int __init leds_init(void) +{ + if (machine_is_netwinder()) + leds_event = netwinder_leds_event; + + leds_event(led_start); + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c new file mode 100644 index 0000000..e263d6d --- /dev/null +++ b/arch/arm/mach-footbridge/netwinder-pci.c @@ -0,0 +1,62 @@ +/* + * linux/arch/arm/mach-footbridge/netwinder-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +/* + * We now use the slot ID instead of the device identifiers to select + * which interrupt is routed where. + */ +static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) { + case 0: /* host bridge */ + return 0; + + case 9: /* CyberPro */ + return IRQ_NETWINDER_VGA; + + case 10: /* DC21143 */ + return IRQ_NETWINDER_ETHER100; + + case 12: /* Winbond 553 */ + return IRQ_ISA_HARDDISK1; + + case 13: /* Winbond 89C940F */ + return IRQ_NETWINDER_ETHER10; + + default: + printk(KERN_ERR "PCI: unknown device in slot %s\n", + pci_name(dev)); + return 0; + } +} + +static struct hw_pci netwinder_pci __initdata = { + .swizzle = pci_std_swizzle, + .map_irq = netwinder_map_irq, + .nr_controllers = 1, + .setup = dc21285_setup, + .scan = dc21285_scan_bus, + .preinit = dc21285_preinit, + .postinit = dc21285_postinit, +}; + +static int __init netwinder_pci_init(void) +{ + if (machine_is_netwinder()) + pci_common_init(&netwinder_pci); + return 0; +} + +subsys_initcall(netwinder_pci_init); diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c new file mode 100644 index 0000000..d5fca95 --- /dev/null +++ b/arch/arm/mach-footbridge/personal-pci.c @@ -0,0 +1,56 @@ +/* + * linux/arch/arm/mach-footbridge/personal-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +static int irqmap_personal_server[] __initdata = { + IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0, + IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI +}; + +static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + unsigned char line; + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line); + + if (line > 0x40 && line <= 0x5f) { + /* line corresponds to the bit controlling this interrupt + * in the footbridge. Ignore the first 8 interrupt bits, + * look up the rest in the map. IN0 is bit number 8 + */ + return irqmap_personal_server[(line & 0x1f) - 8]; + } else if (line == 0) { + /* no interrupt */ + return 0; + } else + return irqmap_personal_server[(line - 1) & 3]; +} + +static struct hw_pci personal_server_pci __initdata = { + .map_irq = personal_server_map_irq, + .nr_controllers = 1, + .setup = dc21285_setup, + .scan = dc21285_scan_bus, + .preinit = dc21285_preinit, + .postinit = dc21285_postinit, +}; + +static int __init personal_pci_init(void) +{ + if (machine_is_personal_server()) + pci_common_init(&personal_server_pci); + return 0; +} + +subsys_initcall(personal_pci_init); diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c new file mode 100644 index 0000000..415086d --- /dev/null +++ b/arch/arm/mach-footbridge/personal.c @@ -0,0 +1,23 @@ +/* + * linux/arch/arm/mach-footbridge/personal.c + * + * Personal server (Skiff) machine fixup + */ +#include <linux/init.h> + +#include <asm/hardware/dec21285.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> + +#include "common.h" + +MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer") + MAINTAINER("Jamey Hicks / George France") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + MAPIO(footbridge_map_io) + INITIRQ(footbridge_init_irq) + .timer = &footbridge_timer, +MACHINE_END + diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c new file mode 100644 index 0000000..2c64a0b --- /dev/null +++ b/arch/arm/mach-footbridge/time.c @@ -0,0 +1,180 @@ +/* + * linux/include/asm-arm/arch-ebsa285/time.h + * + * Copyright (C) 1998 Russell King. + * Copyright (C) 1998 Phil Blundell + * + * CATS has a real-time clock, though the evaluation board doesn't. + * + * Changelog: + * 21-Mar-1998 RMK Created + * 27-Aug-1998 PJB CATS support + * 28-Dec-1998 APH Made leds optional + * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder + * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in + */ + +#define RTC_PORT(x) (rtc_base+(x)) +#define RTC_ALWAYS_BCD 0 + +#include <linux/timex.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/mc146818rtc.h> +#include <linux/bcd.h> + +#include <asm/hardware.h> +#include <asm/io.h> + +#include <asm/mach/time.h> +#include "common.h" + +static int rtc_base; + +static unsigned long __init get_isa_cmos_time(void) +{ + unsigned int year, mon, day, hour, min, sec; + int i; + + // check to see if the RTC makes sense..... + if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0) + return mktime(1970, 1, 1, 0, 0, 0); + + /* The Linux interpretation of the CMOS clock register contents: + * When the Update-In-Progress (UIP) flag goes from 1 to 0, the + * RTC registers show the second which has precisely just started. + * Let's hope other operating systems interpret the RTC the same way. + */ + /* read RTC exactly on falling edge of update flag */ + for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ + if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) + break; + + for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ + if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + break; + + do { /* Isn't this overkill ? UIP above should guarantee consistency */ + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + } while (sec != CMOS_READ(RTC_SECONDS)); + + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + if ((year += 1900) < 1970) + year += 100; + return mktime(year, mon, day, hour, min, sec); +} + +static int set_isa_cmos_time(void) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned char save_control, save_freq_select; + unsigned long nowtime = xtime.tv_sec; + + save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + cmos_minutes = CMOS_READ(RTC_MINUTES); + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + } + CMOS_WRITE(real_seconds,RTC_SECONDS); + CMOS_WRITE(real_minutes,RTC_MINUTES); + } else + retval = -1; + + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + + return retval; +} + +void __init isa_rtc_init(void) +{ + if (machine_is_co285() || + machine_is_personal_server()) + /* + * Add-in 21285s shouldn't access the RTC + */ + rtc_base = 0; + else + rtc_base = 0x70; + + if (rtc_base) { + int reg_d, reg_b; + + /* + * Probe for the RTC. + */ + reg_d = CMOS_READ(RTC_REG_D); + + /* + * make sure the divider is set + */ + CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A); + + /* + * Set control reg B + * (24 hour mode, update enabled) + */ + reg_b = CMOS_READ(RTC_REG_B) & 0x7f; + reg_b |= 2; + CMOS_WRITE(reg_b, RTC_REG_B); + + if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && + CMOS_READ(RTC_REG_B) == reg_b) { + struct timespec tv; + + /* + * We have a RTC. Check the battery + */ + if ((reg_d & 0x80) == 0) + printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); + + tv.tv_nsec = 0; + tv.tv_sec = get_isa_cmos_time(); + do_settimeofday(&tv); + set_rtc = set_isa_cmos_time; + } else + rtc_base = 0; + } +} diff --git a/arch/arm/mach-h720x/Kconfig b/arch/arm/mach-h720x/Kconfig new file mode 100644 index 0000000..9b6982ef --- /dev/null +++ b/arch/arm/mach-h720x/Kconfig @@ -0,0 +1,38 @@ +if ARCH_H720X + +menu "h720x Implementations" + +config ARCH_H7201 + bool "gms30c7201" + depends on ARCH_H720X + select CPU_H7201 + help + Say Y here if you are using the Hynix GMS30C7201 Reference Board + +config ARCH_H7202 + bool "hms30c7202" + select CPU_H7202 + depends on ARCH_H720X + help + Say Y here if you are using the Hynix HMS30C7202 Reference Board + +endmenu + +config CPU_H7201 + bool + help + Select code specific to h7201 variants + +config CPU_H7202 + bool + help + Select code specific to h7202 variants +config H7202_SERIAL23 + depends on CPU_H7202 + bool "Use serial ports 2+3" + help + Say Y here if you wish to use serial ports 2+3. They share their + pins with the keyboard matrix controller, so you have to decide. + + +endif diff --git a/arch/arm/mach-h720x/Makefile b/arch/arm/mach-h720x/Makefile new file mode 100644 index 0000000..e4cf728 --- /dev/null +++ b/arch/arm/mach-h720x/Makefile @@ -0,0 +1,16 @@ +# +# Makefile for the linux kernel. +# + +# Common support +obj-y := common.o +obj-m := +obj-n := +obj- := + +# Specific board support + +obj-$(CONFIG_ARCH_H7201) += h7201-eval.o +obj-$(CONFIG_ARCH_H7202) += h7202-eval.o +obj-$(CONFIG_CPU_H7201) += cpu-h7201.o +obj-$(CONFIG_CPU_H7202) += cpu-h7202.o diff --git a/arch/arm/mach-h720x/Makefile.boot b/arch/arm/mach-h720x/Makefile.boot new file mode 100644 index 0000000..5298401 --- /dev/null +++ b/arch/arm/mach-h720x/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-$(CONFIG_ARCH_H720X) := 0x40008000 + diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c new file mode 100644 index 0000000..96aa3af --- /dev/null +++ b/arch/arm/mach-h720x/common.c @@ -0,0 +1,247 @@ +/* + * linux/arch/arm/mach-h720x/common.c + * + * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de> + * 2003 Robert Schwebel <r.schwebel@pengutronix.de> + * 2004 Sascha Hauer <s.hauer@pengutronix.de> + * + * common stuff for Hynix h720x processors + * + * 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/sched.h> +#include <linux/slab.h> +#include <linux/mman.h> +#include <linux/init.h> +#include <linux/interrupt.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/mach/map.h> +#include <asm/arch/irqs.h> + +#include <asm/mach/dma.h> + +#if 0 +#define IRQDBG(args...) printk(args) +#else +#define IRQDBG(args...) do {} while(0) +#endif + +void __init arch_dma_init(dma_t *dma) +{ +} + +/* + * Return usecs since last timer reload + * (timercount * (usecs perjiffie)) / (ticks per jiffie) + */ +unsigned long h720x_gettimeoffset(void) +{ + return (CPU_REG (TIMER_VIRT, TM0_COUNT) * tick_usec) / LATCH; +} + +/* + * mask Global irq's + */ +static void mask_global_irq (unsigned int irq ) +{ + CPU_REG (IRQC_VIRT, IRQC_IER) &= ~(1 << irq); +} + +/* + * unmask Global irq's + */ +static void unmask_global_irq (unsigned int irq ) +{ + CPU_REG (IRQC_VIRT, IRQC_IER) |= (1 << irq); +} + + +/* + * ack GPIO irq's + * Ack only for edge triggered int's valid + */ +static void inline ack_gpio_irq(u32 irq) +{ + u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq)); + u32 bit = IRQ_TO_BIT(irq); + if ( (CPU_REG (reg_base, GPIO_EDGE) & bit)) + CPU_REG (reg_base, GPIO_CLR) = bit; +} + +/* + * mask GPIO irq's + */ +static void inline mask_gpio_irq(u32 irq) +{ + u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq)); + u32 bit = IRQ_TO_BIT(irq); + CPU_REG (reg_base, GPIO_MASK) &= ~bit; +} + +/* + * unmask GPIO irq's + */ +static void inline unmask_gpio_irq(u32 irq) +{ + u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(irq)); + u32 bit = IRQ_TO_BIT(irq); + CPU_REG (reg_base, GPIO_MASK) |= bit; +} + +static void +h720x_gpio_handler(unsigned int mask, unsigned int irq, + struct irqdesc *desc, struct pt_regs *regs) +{ + IRQDBG("%s irq: %d\n",__FUNCTION__,irq); + desc = irq_desc + irq; + while (mask) { + if (mask & 1) { + IRQDBG("handling irq %d\n", irq); + desc->handle(irq, desc, regs); + } + irq++; + desc++; + mask >>= 1; + } +} + +static void +h720x_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = CPU_REG(GPIO_A_VIRT,GPIO_STAT); + irq = IRQ_CHAINED_GPIOA(0); + IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + h720x_gpio_handler(mask, irq, desc, regs); +} + +static void +h720x_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT); + irq = IRQ_CHAINED_GPIOB(0); + IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + h720x_gpio_handler(mask, irq, desc, regs); +} + +static void +h720x_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = CPU_REG(GPIO_C_VIRT,GPIO_STAT); + irq = IRQ_CHAINED_GPIOC(0); + IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + h720x_gpio_handler(mask, irq, desc, regs); +} + +static void +h720x_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = CPU_REG(GPIO_D_VIRT,GPIO_STAT); + irq = IRQ_CHAINED_GPIOD(0); + IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + h720x_gpio_handler(mask, irq, desc, regs); +} + +#ifdef CONFIG_CPU_H7202 +static void +h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = CPU_REG(GPIO_E_VIRT,GPIO_STAT); + irq = IRQ_CHAINED_GPIOE(0); + IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + h720x_gpio_handler(mask, irq, desc, regs); +} +#endif + +static struct irqchip h720x_global_chip = { + .ack = mask_global_irq, + .mask = mask_global_irq, + .unmask = unmask_global_irq, +}; + +static struct irqchip h720x_gpio_chip = { + .ack = ack_gpio_irq, + .mask = mask_gpio_irq, + .unmask = unmask_gpio_irq, +}; + +/* + * Initialize IRQ's, mask all, enable multiplexed irq's + */ +void __init h720x_init_irq (void) +{ + int irq; + + /* Mask global irq's */ + CPU_REG (IRQC_VIRT, IRQC_IER) = 0x0; + + /* Mask all multiplexed irq's */ + CPU_REG (GPIO_A_VIRT, GPIO_MASK) = 0x0; + CPU_REG (GPIO_B_VIRT, GPIO_MASK) = 0x0; + CPU_REG (GPIO_C_VIRT, GPIO_MASK) = 0x0; + CPU_REG (GPIO_D_VIRT, GPIO_MASK) = 0x0; + + /* Initialize global IRQ's, fast path */ + for (irq = 0; irq < NR_GLBL_IRQS; irq++) { + set_irq_chip(irq, &h720x_global_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + /* Initialize multiplexed IRQ's, slow path */ + for (irq = IRQ_CHAINED_GPIOA(0) ; irq <= IRQ_CHAINED_GPIOD(31); irq++) { + set_irq_chip(irq, &h720x_gpio_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID ); + } + set_irq_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler); + set_irq_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler); + set_irq_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler); + set_irq_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler); + +#ifdef CONFIG_CPU_H7202 + for (irq = IRQ_CHAINED_GPIOE(0) ; irq <= IRQ_CHAINED_GPIOE(31); irq++) { + set_irq_chip(irq, &h720x_gpio_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID ); + } + set_irq_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler); +#endif + + /* Enable multiplexed irq's */ + CPU_REG (IRQC_VIRT, IRQC_IER) = IRQ_ENA_MUX; +} + +static struct map_desc h720x_io_desc[] __initdata = { + { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, +}; + +/* Initialize io tables */ +void __init h720x_map_io(void) +{ + iotable_init(h720x_io_desc,ARRAY_SIZE(h720x_io_desc)); +} diff --git a/arch/arm/mach-h720x/common.h b/arch/arm/mach-h720x/common.h new file mode 100644 index 0000000..d8798db --- /dev/null +++ b/arch/arm/mach-h720x/common.h @@ -0,0 +1,29 @@ +/* + * linux/arch/arm/mach-h720x/common.h + * + * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de> + * 2003 Robert Schwebel <r.schwebel@pengutronix.de> + * 2004 Sascha Hauer <s.hauer@pengutronix.de> + * + * Architecture specific stuff for Hynix GMS30C7201 development board + * + * 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. + * + */ + +extern unsigned long h720x_gettimeoffset(void); +extern void __init h720x_init_irq (void); +extern void __init h720x_map_io(void); + +#ifdef CONFIG_ARCH_H7202 +extern struct sys_timer h7202_timer; +extern void __init init_hw_h7202(void); +extern void __init h7202_init_irq (void); +extern void __init h7202_init_time(void); +#endif + +#ifdef CONFIG_ARCH_H7201 +extern struct sys_timer h7201_timer; +#endif diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c new file mode 100644 index 0000000..7436568 --- /dev/null +++ b/arch/arm/mach-h720x/cpu-h7201.c @@ -0,0 +1,64 @@ +/* + * linux/arch/arm/mach-h720x/cpu-h7201.c + * + * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de> + * 2003 Robert Schwebel <r.schwebel@pengutronix.de> + * 2004 Sascha Hauer <s.hauer@pengutronix.de> + * + * processor specific stuff for the Hynix h7201 + * + * 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/init.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <asm/types.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/arch/irqs.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include "common.h" +/* + * Timer interrupt handler + */ +static irqreturn_t +h7201_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction h7201_timer_irq = { + .name = "h7201 Timer Tick", + .flags = SA_INTERRUPT, + .handler = h7201_timer_interrupt +}; + +/* + * Setup TIMER0 as system timer + */ +void __init h7201_init_time(void) +{ + CPU_REG (TIMER_VIRT, TM0_PERIOD) = LATCH; + CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_RESET; + CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_REPEAT | TM_START; + CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) = ENABLE_TM0_INTR | TIMER_ENABLE_BIT; + + setup_irq(IRQ_TIMER0, &h7201_timer_irq); +} + +struct sys_timer h7201_timer = { + .init = h7201_init_time, + .offset = h720x_gettimeoffset, +}; diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c new file mode 100644 index 0000000..21b8fb6 --- /dev/null +++ b/arch/arm/mach-h720x/cpu-h7202.c @@ -0,0 +1,228 @@ +/* + * linux/arch/arm/mach-h720x/cpu-h7202.c + * + * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de> + * 2003 Robert Schwebel <r.schwebel@pengutronix.de> + * 2004 Sascha Hauer <s.hauer@pengutronix.de> + * + * processor specific stuff for the Hynix h7202 + * + * 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/init.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <asm/types.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/arch/irqs.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include <linux/device.h> +#include <linux/serial_8250.h> +#include "common.h" + +static struct resource h7202ps2_resources[] = { + [0] = { + .start = 0x8002c000, + .end = 0x8002c040, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PS2, + .end = IRQ_PS2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device h7202ps2_device = { + .name = "h7202ps2", + .id = -1, + .num_resources = ARRAY_SIZE(h7202ps2_resources), + .resource = h7202ps2_resources, +}; + +static struct plat_serial8250_port serial_platform_data[] = { + { + .membase = (void*)SERIAL0_VIRT, + .mapbase = SERIAL0_BASE, + .irq = IRQ_UART0, + .uartclk = 2*1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .membase = (void*)SERIAL1_VIRT, + .mapbase = SERIAL1_BASE, + .irq = IRQ_UART1, + .uartclk = 2*1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, +#ifdef CONFIG_H7202_SERIAL23 + { + .membase = (void*)SERIAL2_VIRT, + .mapbase = SERIAL2_BASE, + .irq = IRQ_UART2, + .uartclk = 2*1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .membase = (void*)SERIAL3_VIRT, + .mapbase = SERIAL3_BASE, + .irq = IRQ_UART3, + .uartclk = 2*1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, +#endif + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static struct platform_device *devices[] __initdata = { + &h7202ps2_device, + &serial_device, +}; + +/* Although we have two interrupt lines for the timers, we only have one + * status register which clears all pending timer interrupts on reading. So + * we have to handle all timer interrupts in one place. + */ +static void +h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); + + if ( mask & TSTAT_T0INT ) { + write_seqlock(&xtime_lock); + timer_tick(regs); + write_sequnlock(&xtime_lock); + if( mask == TSTAT_T0INT ) + return; + } + + mask >>= 1; + irq = IRQ_TIMER1; + desc = irq_desc + irq; + while (mask) { + if (mask & 1) + desc->handle(irq, desc, regs); + irq++; + desc++; + mask >>= 1; + } +} + +/* + * Timer interrupt handler + */ +static irqreturn_t +h7202_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + h7202_timerx_demux_handler(0, NULL, regs); + return IRQ_HANDLED; +} + +/* + * mask multiplexed timer irq's + */ +static void inline mask_timerx_irq (u32 irq) +{ + unsigned int bit; + bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1)); + CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) &= ~bit; +} + +/* + * unmask multiplexed timer irq's + */ +static void inline unmask_timerx_irq (u32 irq) +{ + unsigned int bit; + bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1)); + CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) |= bit; +} + +static struct irqchip h7202_timerx_chip = { + .ack = mask_timerx_irq, + .mask = mask_timerx_irq, + .unmask = unmask_timerx_irq, +}; + +static struct irqaction h7202_timer_irq = { + .name = "h7202 Timer Tick", + .flags = SA_INTERRUPT, + .handler = h7202_timer_interrupt +}; + +/* + * Setup TIMER0 as system timer + */ +void __init h7202_init_time(void) +{ + CPU_REG (TIMER_VIRT, TM0_PERIOD) = LATCH; + CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_RESET; + CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_REPEAT | TM_START; + CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) = ENABLE_TM0_INTR | TIMER_ENABLE_BIT; + + setup_irq(IRQ_TIMER0, &h7202_timer_irq); +} + +struct sys_timer h7202_timer = { + .init = h7202_init_time, + .offset = h720x_gettimeoffset, +}; + +void __init h7202_init_irq (void) +{ + int irq; + + CPU_REG (GPIO_E_VIRT, GPIO_MASK) = 0x0; + + for (irq = IRQ_TIMER1; + irq < IRQ_CHAINED_TIMERX(NR_TIMERX_IRQS); irq++) { + mask_timerx_irq(irq); + set_irq_chip(irq, &h7202_timerx_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID ); + } + set_irq_chained_handler(IRQ_TIMERX, h7202_timerx_demux_handler); + + h720x_init_irq(); +} + +void __init init_hw_h7202(void) +{ + /* Enable clocks */ + CPU_REG (PMU_BASE, PMU_PLL_CTRL) |= PLL_2_EN | PLL_1_EN | PLL_3_MUTE; + + CPU_REG (SERIAL0_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN; + CPU_REG (SERIAL1_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN; +#ifdef CONFIG_H7202_SERIAL23 + CPU_REG (SERIAL2_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN; + CPU_REG (SERIAL3_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN; + CPU_IO (GPIO_AMULSEL) = AMULSEL_USIN2 | AMULSEL_USOUT2 | + AMULSEL_USIN3 | AMULSEL_USOUT3; +#endif + (void) platform_add_devices(devices, ARRAY_SIZE(devices)); +} diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c new file mode 100644 index 0000000..9b24b9b --- /dev/null +++ b/arch/arm/mach-h720x/h7201-eval.c @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/mach-h720x/h7201-eval.c + * + * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de> + * 2003 Robert Schwebel <r.schwebel@pengutronix.de> + * 2004 Sascha Hauer <s.hauer@pengutronix.de> + * + * Architecture specific stuff for Hynix GMS30C7201 development board + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/device.h> + +#include <asm/setup.h> +#include <asm/types.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/mach/arch.h> +#include <asm/hardware.h> +#include "common.h" + +MACHINE_START(H7201, "Hynix GMS30C7201") + MAINTAINER("Robert Schwebel, Pengutronix") + BOOT_MEM(0x40000000, 0x80000000, 0xf0000000) + BOOT_PARAMS(0xc0001000) + MAPIO(h720x_map_io) + INITIRQ(h720x_init_irq) + .timer = &h7201_timer, +MACHINE_END diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c new file mode 100644 index 0000000..3456a00 --- /dev/null +++ b/arch/arm/mach-h720x/h7202-eval.c @@ -0,0 +1,81 @@ +/* + * linux/arch/arm/mach-h720x/h7202-eval.c + * + * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de> + * 2003 Robert Schwebel <r.schwebel@pengutronix.de> + * 2004 Sascha Hauer <s.hauer@pengutronix.de> + * + * Architecture specific stuff for Hynix HMS30C7202 development board + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/device.h> + +#include <asm/setup.h> +#include <asm/types.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/mach/arch.h> +#include <asm/hardware.h> +#include "common.h" + +static struct resource cirrus_resources[] = { + [0] = { + .start = ETH0_PHYS + 0x300, + .end = ETH0_PHYS + 0x300 + 0x10, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CHAINED_GPIOB(8), + .end = IRQ_CHAINED_GPIOB(8), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cirrus_device = { + .name = "cirrus-cs89x0", + .id = -1, + .num_resources = ARRAY_SIZE(cirrus_resources), + .resource = cirrus_resources, +}; + +static struct platform_device *devices[] __initdata = { + &cirrus_device, +}; + +/* + * Hardware init. This is called early in initcalls + * Place pin inits here. So you avoid adding ugly + * #ifdef stuff to common drivers. + * Use this only, if your bootloader is not able + * to initialize the pins proper. + */ +static void __init init_eval_h7202(void) +{ + init_hw_h7202(); + (void) platform_add_devices(devices, ARRAY_SIZE(devices)); + + /* Enable interrupt on portb bit 8 (ethernet) */ + CPU_REG (GPIO_B_VIRT, GPIO_POL) &= ~(1 << 8); + CPU_REG (GPIO_B_VIRT, GPIO_EN) |= (1 << 8); +} + +MACHINE_START(H7202, "Hynix HMS30C7202") + MAINTAINER("Robert Schwebel, Pengutronix") + BOOT_MEM(0x40000000, 0x80000000, 0xf0000000) + BOOT_PARAMS(0x40000100) + MAPIO(h720x_map_io) + INITIRQ(h7202_init_irq) + .timer = &h7202_timer, + INIT_MACHINE(init_eval_h7202) +MACHINE_END diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig new file mode 100644 index 0000000..ec85813 --- /dev/null +++ b/arch/arm/mach-imx/Kconfig @@ -0,0 +1,10 @@ +menu "IMX Implementations" + depends on ARCH_IMX + +config ARCH_MX1ADS + bool "mx1ads" + depends on ARCH_IMX + help + Say Y here if you are using the Motorola MX1ADS board + +endmenu diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile new file mode 100644 index 0000000..0b27d79f --- /dev/null +++ b/arch/arm/mach-imx/Makefile @@ -0,0 +1,19 @@ +# +# 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). + +# Object file lists. + +obj-y += irq.o time.o dma.o generic.o + +# Specific board support +obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o + +# Support for blinky lights +led-y := leds.o + +obj-$(CONFIG_LEDS) += $(led-y) +led-$(CONFIG_ARCH_MX1ADS) += leds-mx1ads.o diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot new file mode 100644 index 0000000..fd72ce5 --- /dev/null +++ b/arch/arm/mach-imx/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-$(CONFIG_ARCH_MX1ADS) := 0x08008000 + diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c new file mode 100644 index 0000000..71a59e1 --- /dev/null +++ b/arch/arm/mach-imx/dma.c @@ -0,0 +1,203 @@ +/* + * linux/arch/arm/mach-imx/dma.c + * + * imx DMA registration and IRQ dispatching + * + * 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. + * + * 03/03/2004 Sascha Hauer <sascha@saschahauer.de> + * initial version heavily inspired by + * linux/arch/arm/mach-pxa/dma.c + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/errno.h> + +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/dma.h> + +static struct dma_channel { + char *name; + void (*irq_handler) (int, void *, struct pt_regs *); + void (*err_handler) (int, void *, struct pt_regs *); + void *data; +} dma_channels[11]; + +/* set err_handler to NULL to have the standard info-only error handler */ +int +imx_request_dma(char *name, imx_dma_prio prio, + void (*irq_handler) (int, void *, struct pt_regs *), + void (*err_handler) (int, void *, struct pt_regs *), void *data) +{ + unsigned long flags; + int i, found = 0; + + /* basic sanity checks */ + if (!name || !irq_handler) + return -EINVAL; + + local_irq_save(flags); + + /* try grabbing a DMA channel with the requested priority */ + for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) { + if (!dma_channels[i].name) { + found = 1; + break; + } + } + + if (!found) { + /* requested prio group is full, try hier priorities */ + for (i = prio - 1; i >= 0; i--) { + if (!dma_channels[i].name) { + found = 1; + break; + } + } + } + + if (found) { + DIMR &= ~(1 << i); + dma_channels[i].name = name; + dma_channels[i].irq_handler = irq_handler; + dma_channels[i].err_handler = err_handler; + dma_channels[i].data = data; + } else { + printk(KERN_WARNING "No more available DMA channels for %s\n", + name); + i = -ENODEV; + } + + local_irq_restore(flags); + return i; +} + +void +imx_free_dma(int dma_ch) +{ + unsigned long flags; + + if (!dma_channels[dma_ch].name) { + printk(KERN_CRIT + "%s: trying to free channel %d which is already freed\n", + __FUNCTION__, dma_ch); + return; + } + + local_irq_save(flags); + DIMR &= ~(1 << dma_ch); + dma_channels[dma_ch].name = NULL; + local_irq_restore(flags); +} + +static irqreturn_t +dma_err_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + int i, disr = DISR; + struct dma_channel *channel; + unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR; + + DISR = disr; + for (i = 0; i < 11; i++) { + channel = &dma_channels[i]; + + if ( (err_mask & 1<<i) && channel->name && channel->err_handler) { + channel->err_handler(i, channel->data, regs); + continue; + } + + if (DBTOSR & (1 << i)) { + printk(KERN_WARNING + "Burst timeout on channel %d (%s)\n", + i, channel->name); + DBTOSR |= (1 << i); + } + if (DRTOSR & (1 << i)) { + printk(KERN_WARNING + "Request timeout on channel %d (%s)\n", + i, channel->name); + DRTOSR |= (1 << i); + } + if (DSESR & (1 << i)) { + printk(KERN_WARNING + "Transfer timeout on channel %d (%s)\n", + i, channel->name); + DSESR |= (1 << i); + } + if (DBOSR & (1 << i)) { + printk(KERN_WARNING + "Buffer overflow timeout on channel %d (%s)\n", + i, channel->name); + DBOSR |= (1 << i); + } + } + return IRQ_HANDLED; +} + +static irqreturn_t +dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + int i, disr = DISR; + + DISR = disr; + for (i = 0; i < 11; i++) { + if (disr & (1 << i)) { + struct dma_channel *channel = &dma_channels[i]; + if (channel->name && channel->irq_handler) { + channel->irq_handler(i, channel->data, regs); + } else { + /* + * IRQ for an unregistered DMA channel: + * let's clear the interrupts and disable it. + */ + printk(KERN_WARNING + "spurious IRQ for DMA channel %d\n", i); + } + } + } + return IRQ_HANDLED; +} + +static int __init +imx_dma_init(void) +{ + int ret; + + /* reset DMA module */ + DCR = DCR_DRST; + + ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL); + if (ret) { + printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n"); + return ret; + } + + ret = request_irq(DMA_ERR, dma_err_handler, 0, "DMA", NULL); + if (ret) { + printk(KERN_CRIT "Wow! Can't register ERRIRQ for DMA\n"); + free_irq(DMA_INT, NULL); + } + + /* enable DMA module */ + DCR = DCR_DEN; + + /* clear all interrupts */ + DISR = 0x3ff; + + /* enable interrupts */ + DIMR = 0; + + return ret; +} + +arch_initcall(imx_dma_init); + +EXPORT_SYMBOL(imx_request_dma); +EXPORT_SYMBOL(imx_free_dma); diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c new file mode 100644 index 0000000..54377d0 --- /dev/null +++ b/arch/arm/mach-imx/generic.c @@ -0,0 +1,274 @@ +/* + * arch/arm/mach-imx/generic.c + * + * author: Sascha Hauer + * Created: april 20th, 2004 + * Copyright: Synertronixx GmbH + * + * Common code for i.MX machines + * + * 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/device.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <asm/hardware.h> + +#include <asm/mach/map.h> + +void imx_gpio_mode(int gpio_mode) +{ + unsigned int pin = gpio_mode & GPIO_PIN_MASK; + unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5; + unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10; + unsigned int tmp; + + /* Pullup enable */ + if(gpio_mode & GPIO_PUEN) + PUEN(port) |= (1<<pin); + else + PUEN(port) &= ~(1<<pin); + + /* Data direction */ + if(gpio_mode & GPIO_OUT) + DDIR(port) |= 1<<pin; + else + DDIR(port) &= ~(1<<pin); + + /* Primary / alternate function */ + if(gpio_mode & GPIO_AF) + GPR(port) |= (1<<pin); + else + GPR(port) &= ~(1<<pin); + + /* use as gpio? */ + if( ocr == 3 ) + GIUS(port) |= (1<<pin); + else + GIUS(port) &= ~(1<<pin); + + /* Output / input configuration */ + /* FIXME: I'm not very sure about OCR and ICONF, someone + * should have a look over it + */ + if(pin<16) { + tmp = OCR1(port); + tmp &= ~( 3<<(pin*2)); + tmp |= (ocr << (pin*2)); + OCR1(port) = tmp; + + if( gpio_mode & GPIO_AOUT ) + ICONFA1(port) &= ~( 3<<(pin*2)); + if( gpio_mode & GPIO_BOUT ) + ICONFB1(port) &= ~( 3<<(pin*2)); + } else { + tmp = OCR2(port); + tmp &= ~( 3<<((pin-16)*2)); + tmp |= (ocr << ((pin-16)*2)); + OCR2(port) = tmp; + + if( gpio_mode & GPIO_AOUT ) + ICONFA2(port) &= ~( 3<<((pin-16)*2)); + if( gpio_mode & GPIO_BOUT ) + ICONFB2(port) &= ~( 3<<((pin-16)*2)); + } +} + +EXPORT_SYMBOL(imx_gpio_mode); + +/* + * get the system pll clock in Hz + * + * mfi + mfn / (mfd +1) + * f = 2 * f_ref * -------------------- + * pd + 1 + */ +static unsigned int imx_decode_pll(unsigned int pll) +{ + u32 mfi = (pll >> 10) & 0xf; + u32 mfn = pll & 0x3ff; + u32 mfd = (pll >> 16) & 0x3ff; + u32 pd = (pll >> 26) & 0xf; + u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); + + mfi = mfi <= 5 ? 5 : mfi; + + return (2 * (f_ref>>10) * ( (mfi<<10) + (mfn<<10) / (mfd+1) )) / (pd+1); +} + +unsigned int imx_get_system_clk(void) +{ + return imx_decode_pll(SPCTL0); +} +EXPORT_SYMBOL(imx_get_system_clk); + +unsigned int imx_get_mcu_clk(void) +{ + return imx_decode_pll(MPCTL0); +} +EXPORT_SYMBOL(imx_get_mcu_clk); + +/* + * get peripheral clock 1 ( UART[12], Timer[12], PWM ) + */ +unsigned int imx_get_perclk1(void) +{ + return imx_get_system_clk() / (((PCDR) & 0xf)+1); +} +EXPORT_SYMBOL(imx_get_perclk1); + +/* + * get peripheral clock 2 ( LCD, SD, SPI[12] ) + */ +unsigned int imx_get_perclk2(void) +{ + return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); +} +EXPORT_SYMBOL(imx_get_perclk2); + +/* + * get peripheral clock 3 ( SSI ) + */ +unsigned int imx_get_perclk3(void) +{ + return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); +} +EXPORT_SYMBOL(imx_get_perclk3); + +/* + * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) + */ +unsigned int imx_get_hclk(void) +{ + return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); +} +EXPORT_SYMBOL(imx_get_hclk); + +static struct resource imx_mmc_resources[] = { + [0] = { + .start = 0x00214000, + .end = 0x002140FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = (SDHC_INT), + .end = (SDHC_INT), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device imx_mmc_device = { + .name = "imx-mmc", + .id = 0, + .num_resources = ARRAY_SIZE(imx_mmc_resources), + .resource = imx_mmc_resources, +}; + +static struct resource imx_uart1_resources[] = { + [0] = { + .start = 0x00206000, + .end = 0x002060FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = (UART1_MINT_RX), + .end = (UART1_MINT_RX), + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = (UART1_MINT_TX), + .end = (UART1_MINT_TX), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device imx_uart1_device = { + .name = "imx-uart", + .id = 0, + .num_resources = ARRAY_SIZE(imx_uart1_resources), + .resource = imx_uart1_resources, +}; + +static struct resource imx_uart2_resources[] = { + [0] = { + .start = 0x00207000, + .end = 0x002070FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = (UART2_MINT_RX), + .end = (UART2_MINT_RX), + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = (UART2_MINT_TX), + .end = (UART2_MINT_TX), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device imx_uart2_device = { + .name = "imx-uart", + .id = 1, + .num_resources = ARRAY_SIZE(imx_uart2_resources), + .resource = imx_uart2_resources, +}; + +static struct resource imxfb_resources[] = { + [0] = { + .start = 0x00205000, + .end = 0x002050FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = LCDC_INT, + .end = LCDC_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device imxfb_device = { + .name = "imx-fb", + .id = 0, + .num_resources = ARRAY_SIZE(imxfb_resources), + .resource = imxfb_resources, +}; + +static struct platform_device *devices[] __initdata = { + &imx_mmc_device, + &imxfb_device, + &imx_uart1_device, + &imx_uart2_device, +}; + +static struct map_desc imx_io_desc[] __initdata = { + /* virtual physical length type */ + {IMX_IO_BASE, IMX_IO_PHYS, IMX_IO_SIZE, MT_DEVICE}, +}; + +void __init +imx_map_io(void) +{ + iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc)); +} + +static int __init imx_init(void) +{ + return platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +subsys_initcall(imx_init); diff --git a/arch/arm/mach-imx/generic.h b/arch/arm/mach-imx/generic.h new file mode 100644 index 0000000..e91003e --- /dev/null +++ b/arch/arm/mach-imx/generic.h @@ -0,0 +1,16 @@ +/* + * linux/arch/arm/mach-imx/generic.h + * + * Author: Sascha Hauer <sascha@saschahauer.de> + * Copyright: Synertronixx GmbH + * + * 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. + */ + +extern void __init imx_map_io(void); +extern void __init imx_init_irq(void); + +struct sys_timer; +extern struct sys_timer imx_timer; diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c new file mode 100644 index 0000000..0c2713426 --- /dev/null +++ b/arch/arm/mach-imx/irq.c @@ -0,0 +1,252 @@ +/* + * linux/arch/arm/mach-imx/irq.c + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * + * 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 + * + * 03/03/2004 Sascha Hauer <sascha@saschahauer.de> + * Copied from the motorola bsp package and added gpio demux + * interrupt handler + */ + +#include <linux/init.h> +#include <linux/list.h> +#include <linux/timer.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/irq.h> + +/* + * + * We simply use the ENABLE DISABLE registers inside of the IMX + * to turn on/off specific interrupts. FIXME- We should + * also add support for the accelerated interrupt controller + * by putting offets to irq jump code in the appropriate + * places. + * + */ + +#define INTENNUM_OFF 0x8 +#define INTDISNUM_OFF 0xC + +#define VA_AITC_BASE IO_ADDRESS(IMX_AITC_BASE) +#define IMX_AITC_INTDISNUM (VA_AITC_BASE + INTDISNUM_OFF) +#define IMX_AITC_INTENNUM (VA_AITC_BASE + INTENNUM_OFF) + +#if 0 +#define DEBUG_IRQ(fmt...) printk(fmt) +#else +#define DEBUG_IRQ(fmt...) do { } while (0) +#endif + +static void +imx_mask_irq(unsigned int irq) +{ + __raw_writel(irq, IMX_AITC_INTDISNUM); +} + +static void +imx_unmask_irq(unsigned int irq) +{ + __raw_writel(irq, IMX_AITC_INTENNUM); +} + +static int +imx_gpio_irq_type(unsigned int _irq, unsigned int type) +{ + unsigned int irq_type = 0, irq, reg, bit; + + irq = _irq - IRQ_GPIOA(0); + reg = irq >> 5; + bit = 1 << (irq % 32); + + if (type == IRQT_PROBE) { + /* Don't mess with enabled GPIOs using preconfigured edges or + GPIOs set to alternate function during probe */ + /* TODO: support probe */ +// if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) & +// GPIO_bit(gpio)) +// return 0; +// if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2))) +// return 0; +// type = __IRQT_RISEDGE | __IRQT_FALEDGE; + } + + GIUS(reg) |= bit; + DDIR(reg) &= ~(bit); + + DEBUG_IRQ("setting type of irq %d to ", _irq); + + if (type & __IRQT_RISEDGE) { + DEBUG_IRQ("rising edges\n"); + irq_type = 0x0; + } + if (type & __IRQT_FALEDGE) { + DEBUG_IRQ("falling edges\n"); + irq_type = 0x1; + } + if (type & __IRQT_LOWLVL) { + DEBUG_IRQ("low level\n"); + irq_type = 0x3; + } + if (type & __IRQT_HIGHLVL) { + DEBUG_IRQ("high level\n"); + irq_type = 0x2; + } + + if (irq % 32 < 16) { + ICR1(reg) = (ICR1(reg) & ~(0x3 << ((irq % 16) * 2))) | + (irq_type << ((irq % 16) * 2)); + } else { + ICR2(reg) = (ICR2(reg) & ~(0x3 << ((irq % 16) * 2))) | + (irq_type << ((irq % 16) * 2)); + } + + return 0; + +} + +static void +imx_gpio_ack_irq(unsigned int irq) +{ + DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); + ISR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32); +} + +static void +imx_gpio_mask_irq(unsigned int irq) +{ + DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); + IMR(IRQ_TO_REG(irq)) &= ~( 1 << ((irq - IRQ_GPIOA(0)) % 32)); +} + +static void +imx_gpio_unmask_irq(unsigned int irq) +{ + DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); + IMR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32); +} + +static void +imx_gpio_handler(unsigned int mask, unsigned int irq, + struct irqdesc *desc, struct pt_regs *regs) +{ + desc = irq_desc + irq; + while (mask) { + if (mask & 1) { + DEBUG_IRQ("handling irq %d\n", irq); + desc->handle(irq, desc, regs); + } + irq++; + desc++; + mask >>= 1; + } +} + +static void +imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = ISR(0); + irq = IRQ_GPIOA(0); + imx_gpio_handler(mask, irq, desc, regs); +} + +static void +imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = ISR(1); + irq = IRQ_GPIOB(0); + imx_gpio_handler(mask, irq, desc, regs); +} + +static void +imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = ISR(2); + irq = IRQ_GPIOC(0); + imx_gpio_handler(mask, irq, desc, regs); +} + +static void +imx_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask, irq; + + mask = ISR(3); + irq = IRQ_GPIOD(0); + imx_gpio_handler(mask, irq, desc, regs); +} + +static struct irqchip imx_internal_chip = { + .ack = imx_mask_irq, + .mask = imx_mask_irq, + .unmask = imx_unmask_irq, +}; + +static struct irqchip imx_gpio_chip = { + .ack = imx_gpio_ack_irq, + .mask = imx_gpio_mask_irq, + .unmask = imx_gpio_unmask_irq, + .type = imx_gpio_irq_type, +}; + +void __init +imx_init_irq(void) +{ + unsigned int irq; + + DEBUG_IRQ("Initializing imx interrupts\n"); + + /* Mask all interrupts initially */ + IMR(0) = 0; + IMR(1) = 0; + IMR(2) = 0; + IMR(3) = 0; + + for (irq = 0; irq < IMX_IRQS; irq++) { + set_irq_chip(irq, &imx_internal_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } + + for (irq = IRQ_GPIOA(0); irq < IRQ_GPIOD(32); irq++) { + set_irq_chip(irq, &imx_gpio_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID); + } + + set_irq_chained_handler(GPIO_INT_PORTA, imx_gpioa_demux_handler); + set_irq_chained_handler(GPIO_INT_PORTB, imx_gpiob_demux_handler); + set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler); + set_irq_chained_handler(GPIO_INT_PORTD, imx_gpiod_demux_handler); + + /* Disable all interrupts initially. */ + /* In IMX this is done in the bootloader. */ +} diff --git a/arch/arm/mach-imx/leds-mx1ads.c b/arch/arm/mach-imx/leds-mx1ads.c new file mode 100644 index 0000000..e6399b0 --- /dev/null +++ b/arch/arm/mach-imx/leds-mx1ads.c @@ -0,0 +1,54 @@ +/* + * linux/arch/arm/mach-imx/leds-mx1ads.c + * + * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de> + * + * Original (leds-footbridge.c) by 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/kernel.h> +#include <linux/init.h> +#include <asm/hardware.h> +#include <asm/system.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/mach-types.h> +#include "leds.h" + +/* + * The MX1ADS Board has only one usable LED, + * so select only the timer led or the + * cpu usage led + */ +void +mx1ads_leds_event(led_event_t ledevt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (ledevt) { +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + DR(0) &= ~(1<<2); + break; + + case led_idle_end: + DR(0) |= 1<<2; + break; +#endif + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + DR(0) ^= 1<<2; +#endif + default: + break; + } + local_irq_restore(flags); +} diff --git a/arch/arm/mach-imx/leds.c b/arch/arm/mach-imx/leds.c new file mode 100644 index 0000000..471c1db --- /dev/null +++ b/arch/arm/mach-imx/leds.c @@ -0,0 +1,31 @@ +/* + * linux/arch/arm/mach-imx/leds.h + * + * Copyright (C) 2004 Sascha Hauer <sascha@saschahauer.de> + * + * + * 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/init.h> + +#include <asm/leds.h> +#include <asm/mach-types.h> + +#include "leds.h" + +static int __init +leds_init(void) +{ + if (machine_is_mx1ads()) { + leds_event = mx1ads_leds_event; + } + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-imx/leds.h b/arch/arm/mach-imx/leds.h new file mode 100644 index 0000000..83fa21e --- /dev/null +++ b/arch/arm/mach-imx/leds.h @@ -0,0 +1,9 @@ +/* + * include/asm-arm/arch-imx/leds.h + * + * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de> + * + * blinky lights for IMX-based systems + * + */ +extern void mx1ads_leds_event(led_event_t evt); diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c new file mode 100644 index 0000000..625dd01 --- /dev/null +++ b/arch/arm/mach-imx/mx1ads.c @@ -0,0 +1,88 @@ +/* + * arch/arm/mach-imx/mx1ads.c + * + * Initially based on: + * linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c + * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de> + * + * 2004 (c) MontaVista Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/device.h> +#include <linux/init.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/pgtable.h> +#include <asm/page.h> + +#include <asm/mach/map.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <linux/interrupt.h> +#include "generic.h" +#include <asm/serial.h> + +static struct resource mx1ads_resources[] = { + [0] = { + .start = IMX_CS4_VIRT, + .end = IMX_CS4_VIRT + 16, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 13, + .end = 13, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mx1ads_device = { + .name = "mx1ads", + .num_resources = ARRAY_SIZE(mx1ads_resources), + .resource = mx1ads_resources, +}; + +static struct platform_device *devices[] __initdata = { + &mx1ads_device, +}; + +static void __init +mx1ads_init(void) +{ +#ifdef CONFIG_LEDS + imx_gpio_mode(GPIO_PORTA | GPIO_OUT | GPIO_GPIO | 2); +#endif + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static struct map_desc mx1ads_io_desc[] __initdata = { + /* virtual physical length type */ + {IMX_CS0_VIRT, IMX_CS0_PHYS, IMX_CS0_SIZE, MT_DEVICE}, + {IMX_CS1_VIRT, IMX_CS1_PHYS, IMX_CS1_SIZE, MT_DEVICE}, + {IMX_CS2_VIRT, IMX_CS2_PHYS, IMX_CS2_SIZE, MT_DEVICE}, + {IMX_CS3_VIRT, IMX_CS3_PHYS, IMX_CS3_SIZE, MT_DEVICE}, + {IMX_CS4_VIRT, IMX_CS4_PHYS, IMX_CS4_SIZE, MT_DEVICE}, + {IMX_CS5_VIRT, IMX_CS5_PHYS, IMX_CS5_SIZE, MT_DEVICE}, +}; + +static void __init +mx1ads_map_io(void) +{ + imx_map_io(); + iotable_init(mx1ads_io_desc, ARRAY_SIZE(mx1ads_io_desc)); +} + +MACHINE_START(MX1ADS, "Motorola MX1ADS") + MAINTAINER("Sascha Hauer, Pengutronix") + BOOT_MEM(0x08000000, 0x00200000, 0xe0200000) + BOOT_PARAMS(0x08000100) + MAPIO(mx1ads_map_io) + INITIRQ(imx_init_irq) + .timer = &imx_timer, + INIT_MACHINE(mx1ads_init) +MACHINE_END diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c new file mode 100644 index 0000000..11f1e56 --- /dev/null +++ b/arch/arm/mach-imx/time.c @@ -0,0 +1,101 @@ +/* + * linux/arch/arm/mach-imx/time.c + * + * Copyright (C) 2000-2001 Deep Blue Solutions + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * + * 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/kernel.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/time.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/irq.h> +#include <asm/mach/time.h> + +/* Use timer 1 as system timer */ +#define TIMER_BASE IMX_TIM1_BASE + +/* + * Returns number of us since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +static unsigned long imx_gettimeoffset(void) +{ + unsigned long ticks; + + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + ticks = IMX_TCN(TIMER_BASE); + + /* + * Interrupt pending? If so, we've reloaded once already. + */ + if (IMX_TSTAT(TIMER_BASE) & TSTAT_COMP) + ticks += LATCH; + + /* + * Convert the ticks to usecs + */ + return (1000000 / CLK32) * ticks; +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t +imx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + /* clear the interrupt */ + if (IMX_TSTAT(TIMER_BASE)) + IMX_TSTAT(TIMER_BASE) = 0; + + timer_tick(regs); + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction imx_timer_irq = { + .name = "i.MX Timer Tick", + .flags = SA_INTERRUPT, + .handler = imx_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +static void __init imx_timer_init(void) +{ + /* + * Initialise to a known state (all timers off, and timing reset) + */ + IMX_TCTL(TIMER_BASE) = 0; + IMX_TPRER(TIMER_BASE) = 0; + IMX_TCMP(TIMER_BASE) = LATCH - 1; + IMX_TCTL(TIMER_BASE) = TCTL_CLK_32 | TCTL_IRQEN | TCTL_TEN; + + /* + * Make irqs happen for the system timer + */ + setup_irq(TIM1_INT, &imx_timer_irq); +} + +struct sys_timer imx_timer = { + .init = imx_timer_init, + .offset = imx_gettimeoffset, +}; diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig new file mode 100644 index 0000000..df97d16 --- /dev/null +++ b/arch/arm/mach-integrator/Kconfig @@ -0,0 +1,33 @@ +if ARCH_INTEGRATOR + +menu "Integrator Options" + +config ARCH_INTEGRATOR_AP + bool "Support Integrator/AP and Integrator/PP2 platforms" + help + Include support for the ARM(R) Integrator/AP and + Integrator/PP2 platforms. + +config ARCH_INTEGRATOR_CP + bool "Support Integrator/CP platform" + select ARCH_CINTEGRATOR + help + Include support for the ARM(R) Integrator CP platform. + +config ARCH_CINTEGRATOR + bool + +config INTEGRATOR_IMPD1 + tristate "Include support for Integrator/IM-PD1" + depends on ARCH_INTEGRATOR_AP + help + The IM-PD1 is an add-on logic module for the Integrator which + allows ARM(R) Ltd PrimeCells to be developed and evaluated. + The IM-PD1 can be found on the Integrator/PP2 platform. + + To compile this driver as a module, choose M here: the + module will be called impd1. + +endmenu + +endif diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile new file mode 100644 index 0000000..158daaf --- /dev/null +++ b/arch/arm/mach-integrator/Makefile @@ -0,0 +1,14 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := clock.o core.o lm.o time.o +obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o +obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o + +obj-$(CONFIG_LEDS) += leds.o +obj-$(CONFIG_PCI) += pci_v3.o pci.o +obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o +obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o diff --git a/arch/arm/mach-integrator/Makefile.boot b/arch/arm/mach-integrator/Makefile.boot new file mode 100644 index 0000000..c7e75ac --- /dev/null +++ b/arch/arm/mach-integrator/Makefile.boot @@ -0,0 +1,4 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 + diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c new file mode 100644 index 0000000..5620059 --- /dev/null +++ b/arch/arm/mach-integrator/clock.c @@ -0,0 +1,141 @@ +/* + * linux/arch/arm/mach-integrator/clock.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> + +#include <asm/semaphore.h> +#include <asm/hardware/clock.h> +#include <asm/hardware/icst525.h> + +#include "clock.h" + +static LIST_HEAD(clocks); +static DECLARE_MUTEX(clocks_sem); + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + down(&clocks_sem); + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + break; + } + } + up(&clocks_sem); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +int clk_use(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_use); + +void clk_unuse(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_unuse); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + struct icst525_vco vco; + + vco = icst525_khz_to_vco(clk->params, rate / 1000); + return icst525_khz(clk->params, vco) * 1000; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EIO; + if (clk->setvco) { + struct icst525_vco vco; + + vco = icst525_khz_to_vco(clk->params, rate / 1000); + clk->rate = icst525_khz(clk->params, vco) * 1000; + + printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n", + clk->name, vco.s, vco.r, vco.v); + + clk->setvco(clk, vco); + ret = 0; + } + return 0; +} +EXPORT_SYMBOL(clk_set_rate); + +/* + * These are fixed clocks. + */ +static struct clk kmi_clk = { + .name = "KMIREFCLK", + .rate = 24000000, +}; + +static struct clk uart_clk = { + .name = "UARTCLK", + .rate = 14745600, +}; + +int clk_register(struct clk *clk) +{ + down(&clocks_sem); + list_add(&clk->node, &clocks); + up(&clocks_sem); + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + down(&clocks_sem); + list_del(&clk->node); + up(&clocks_sem); +} +EXPORT_SYMBOL(clk_unregister); + +static int __init clk_init(void) +{ + clk_register(&kmi_clk); + clk_register(&uart_clk); + return 0; +} +arch_initcall(clk_init); diff --git a/arch/arm/mach-integrator/clock.h b/arch/arm/mach-integrator/clock.h new file mode 100644 index 0000000..09e6328 --- /dev/null +++ b/arch/arm/mach-integrator/clock.h @@ -0,0 +1,25 @@ +/* + * linux/arch/arm/mach-integrator/clock.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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. + */ +struct module; +struct icst525_params; + +struct clk { + struct list_head node; + unsigned long rate; + struct module *owner; + const char *name; + const struct icst525_params *params; + void *data; + void (*setvco)(struct clk *, struct icst525_vco vco); +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h new file mode 100644 index 0000000..609c49d --- /dev/null +++ b/arch/arm/mach-integrator/common.h @@ -0,0 +1,2 @@ +extern void integrator_time_init(unsigned long, unsigned int); +extern unsigned long integrator_gettimeoffset(void); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c new file mode 100644 index 0000000..86c50c3 --- /dev/null +++ b/arch/arm/mach-integrator/core.c @@ -0,0 +1,271 @@ +/* + * linux/arch/arm/mach-integrator/core.c + * + * Copyright (C) 2000-2003 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 version 2, as + * published by the Free Software Foundation. + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/sched.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/hardware/amba.h> +#include <asm/arch/cm.h> +#include <asm/system.h> +#include <asm/leds.h> +#include <asm/mach/time.h> + +#include "common.h" + +static struct amba_device rtc_device = { + .dev = { + .bus_id = "mb:15", + }, + .res = { + .start = INTEGRATOR_RTC_BASE, + .end = INTEGRATOR_RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_RTCINT, NO_IRQ }, + .periphid = 0x00041030, +}; + +static struct amba_device uart0_device = { + .dev = { + .bus_id = "mb:16", + }, + .res = { + .start = INTEGRATOR_UART0_BASE, + .end = INTEGRATOR_UART0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_UARTINT0, NO_IRQ }, + .periphid = 0x0041010, +}; + +static struct amba_device uart1_device = { + .dev = { + .bus_id = "mb:17", + }, + .res = { + .start = INTEGRATOR_UART1_BASE, + .end = INTEGRATOR_UART1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_UARTINT1, NO_IRQ }, + .periphid = 0x0041010, +}; + +static struct amba_device kmi0_device = { + .dev = { + .bus_id = "mb:18", + }, + .res = { + .start = KMI0_BASE, + .end = KMI0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_KMIINT0, NO_IRQ }, + .periphid = 0x00041050, +}; + +static struct amba_device kmi1_device = { + .dev = { + .bus_id = "mb:19", + }, + .res = { + .start = KMI1_BASE, + .end = KMI1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_KMIINT1, NO_IRQ }, + .periphid = 0x00041050, +}; + +static struct amba_device *amba_devs[] __initdata = { + &rtc_device, + &uart0_device, + &uart1_device, + &kmi0_device, + &kmi1_device, +}; + +static int __init integrator_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + + return 0; +} + +arch_initcall(integrator_init); + +#define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET + +static DEFINE_SPINLOCK(cm_lock); + +/** + * cm_control - update the CM_CTRL register. + * @mask: bits to change + * @set: bits to set + */ +void cm_control(u32 mask, u32 set) +{ + unsigned long flags; + u32 val; + + spin_lock_irqsave(&cm_lock, flags); + val = readl(CM_CTRL) & ~mask; + writel(val | set, CM_CTRL); + spin_unlock_irqrestore(&cm_lock, flags); +} + +EXPORT_SYMBOL(cm_control); + +/* + * Where is the timer (VA)? + */ +#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000) +#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100) +#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200) +#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) + +/* + * How long is the timer interval? + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) +#if TIMER_INTERVAL >= 0x100000 +#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) +#elif TIMER_INTERVAL >= 0x10000 +#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) +#else +#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) +#endif + +/* + * What does it look like? + */ +typedef struct TimerStruct { + unsigned long TimerLoad; + unsigned long TimerValue; + unsigned long TimerControl; + unsigned long TimerClear; +} TimerStruct_t; + +static unsigned long timer_reload; + +/* + * Returns number of ms since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +unsigned long integrator_gettimeoffset(void) +{ + volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE; + unsigned long ticks1, ticks2, status; + + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + ticks2 = timer1->TimerValue & 0xffff; + do { + ticks1 = ticks2; + status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); + ticks2 = timer1->TimerValue & 0xffff; + } while (ticks2 > ticks1); + + /* + * Number of ticks since last interrupt. + */ + ticks1 = timer_reload - ticks2; + + /* + * Interrupt pending? If so, we've reloaded once already. + */ + if (status & (1 << IRQ_TIMERINT1)) + ticks1 += timer_reload; + + /* + * Convert the ticks to usecs + */ + return TICKS2USECS(ticks1); +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t +integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; + + write_seqlock(&xtime_lock); + + // ...clear the interrupt + timer1->TimerClear = 1; + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction integrator_timer_irq = { + .name = "Integrator Timer Tick", + .flags = SA_INTERRUPT, + .handler = integrator_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +void __init integrator_time_init(unsigned long reload, unsigned int ctrl) +{ + volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; + volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; + volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; + unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */ + + timer_reload = reload; + timer_ctrl |= ctrl; + + if (timer_reload > 0x100000) { + timer_reload >>= 8; + timer_ctrl |= 0x08; /* /256 */ + } else if (timer_reload > 0x010000) { + timer_reload >>= 4; + timer_ctrl |= 0x04; /* /16 */ + } + + /* + * Initialise to a known state (all timers off) + */ + timer0->TimerControl = 0; + timer1->TimerControl = 0; + timer2->TimerControl = 0; + + timer1->TimerLoad = timer_reload; + timer1->TimerValue = timer_reload; + timer1->TimerControl = timer_ctrl; + + /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); +} diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c new file mode 100644 index 0000000..71c58bff --- /dev/null +++ b/arch/arm/mach-integrator/cpu.c @@ -0,0 +1,221 @@ +/* + * linux/arch/arm/mach-integrator/cpu.c + * + * Copyright (C) 2001-2002 Deep Blue Solutions Ltd. + * + * $Id: cpu.c,v 1.6 2002/07/18 13:58:51 rmk Exp $ + * + * 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. + * + * CPU support functions + */ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/cpufreq.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/smp.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/hardware/icst525.h> + +static struct cpufreq_driver integrator_driver; + +#define CM_ID (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_ID_OFFSET) +#define CM_OSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_OSC_OFFSET) +#define CM_STAT (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_STAT_OFFSET) +#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) + +static const struct icst525_params lclk_params = { + .ref = 24000, + .vco_max = 320000, + .vd_min = 8, + .vd_max = 132, + .rd_min = 24, + .rd_max = 24, +}; + +static const struct icst525_params cclk_params = { + .ref = 24000, + .vco_max = 320000, + .vd_min = 12, + .vd_max = 160, + .rd_min = 24, + .rd_max = 24, +}; + +/* + * Validate the speed policy. + */ +static int integrator_verify_policy(struct cpufreq_policy *policy) +{ + struct icst525_vco vco; + + cpufreq_verify_within_limits(policy, + policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + + vco = icst525_khz_to_vco(&cclk_params, policy->max); + policy->max = icst525_khz(&cclk_params, vco); + + vco = icst525_khz_to_vco(&cclk_params, policy->min); + policy->min = icst525_khz(&cclk_params, vco); + + cpufreq_verify_within_limits(policy, + policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + + return 0; +} + + +static int integrator_set_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + cpumask_t cpus_allowed; + int cpu = policy->cpu; + struct icst525_vco vco; + struct cpufreq_freqs freqs; + u_int cm_osc; + + /* + * Save this threads cpus_allowed mask. + */ + cpus_allowed = current->cpus_allowed; + + /* + * Bind to the specified CPU. When this call returns, + * we should be running on the right CPU. + */ + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(cpu != smp_processor_id()); + + /* get current setting */ + cm_osc = __raw_readl(CM_OSC); + + if (machine_is_integrator()) { + vco.s = (cm_osc >> 8) & 7; + } else if (machine_is_cintegrator()) { + vco.s = 1; + } + vco.v = cm_osc & 255; + vco.r = 22; + freqs.old = icst525_khz(&cclk_params, vco); + + /* icst525_khz_to_vco rounds down -- so we need the next + * larger freq in case of CPUFREQ_RELATION_L. + */ + if (relation == CPUFREQ_RELATION_L) + target_freq += 999; + if (target_freq > policy->max) + target_freq = policy->max; + vco = icst525_khz_to_vco(&cclk_params, target_freq); + freqs.new = icst525_khz(&cclk_params, vco); + + freqs.cpu = policy->cpu; + + if (freqs.old == freqs.new) { + set_cpus_allowed(current, cpus_allowed); + return 0; + } + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + cm_osc = __raw_readl(CM_OSC); + + if (machine_is_integrator()) { + cm_osc &= 0xfffff800; + cm_osc |= vco.s << 8; + } else if (machine_is_cintegrator()) { + cm_osc &= 0xffffff00; + } + cm_osc |= vco.v; + + __raw_writel(0xa05f, CM_LOCK); + __raw_writel(cm_osc, CM_OSC); + __raw_writel(0, CM_LOCK); + + /* + * Restore the CPUs allowed mask. + */ + set_cpus_allowed(current, cpus_allowed); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return 0; +} + +static unsigned int integrator_get(unsigned int cpu) +{ + cpumask_t cpus_allowed; + unsigned int current_freq; + u_int cm_osc; + struct icst525_vco vco; + + cpus_allowed = current->cpus_allowed; + + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(cpu != smp_processor_id()); + + /* detect memory etc. */ + cm_osc = __raw_readl(CM_OSC); + + if (machine_is_integrator()) { + vco.s = (cm_osc >> 8) & 7; + } else if (machine_is_cintegrator()) { + vco.s = 1; + } + vco.v = cm_osc & 255; + vco.r = 22; + + current_freq = icst525_khz(&cclk_params, vco); /* current freq */ + + set_cpus_allowed(current, cpus_allowed); + + return current_freq; +} + +static int integrator_cpufreq_init(struct cpufreq_policy *policy) +{ + + /* set default policy and cpuinfo */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.max_freq = 160000; + policy->cpuinfo.min_freq = 12000; + policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */ + policy->cur = policy->min = policy->max = integrator_get(policy->cpu); + + return 0; +} + +static struct cpufreq_driver integrator_driver = { + .verify = integrator_verify_policy, + .target = integrator_set_target, + .get = integrator_get, + .init = integrator_cpufreq_init, + .name = "integrator", +}; + +static int __init integrator_cpu_init(void) +{ + return cpufreq_register_driver(&integrator_driver); +} + +static void __exit integrator_cpu_exit(void) +{ + cpufreq_unregister_driver(&integrator_driver); +} + +MODULE_AUTHOR ("Russell M. King"); +MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs"); +MODULE_LICENSE ("GPL"); + +module_init(integrator_cpu_init); +module_exit(integrator_cpu_exit); diff --git a/arch/arm/mach-integrator/dma.c b/arch/arm/mach-integrator/dma.c new file mode 100644 index 0000000..aae6f23 --- /dev/null +++ b/arch/arm/mach-integrator/dma.c @@ -0,0 +1,35 @@ +/* + * 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/slab.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/impd1.c b/arch/arm/mach-integrator/impd1.c new file mode 100644 index 0000000..c3c2f17 --- /dev/null +++ b/arch/arm/mach-integrator/impd1.c @@ -0,0 +1,475 @@ +/* + * linux/arch/arm/mach-integrator/impd1.c + * + * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved. + * + * 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. + * + * This file provides the core support for the IM-PD1 module. + * + * Module / boot parameters. + * lmid=n impd1.lmid=n - set the logic module position in stack to 'n' + */ +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/mm.h> + +#include <asm/io.h> +#include <asm/hardware/icst525.h> +#include <asm/hardware/amba.h> +#include <asm/hardware/amba_clcd.h> +#include <asm/arch/lm.h> +#include <asm/arch/impd1.h> +#include <asm/sizes.h> + +#include "clock.h" + +static int module_id; + +module_param_named(lmid, module_id, int, 0444); +MODULE_PARM_DESC(lmid, "logic module stack position"); + +struct impd1_module { + void __iomem *base; + struct clk vcos[2]; +}; + +static const struct icst525_params impd1_vco_params = { + .ref = 24000, /* 24 MHz */ + .vco_max = 200000, /* 200 MHz */ + .vd_min = 12, + .vd_max = 519, + .rd_min = 3, + .rd_max = 120, +}; + +static void impd1_setvco(struct clk *clk, struct icst525_vco vco) +{ + struct impd1_module *impd1 = clk->data; + int vconr = clk - impd1->vcos; + u32 val; + + val = vco.v | (vco.r << 9) | (vco.s << 16); + + writel(0xa05f, impd1->base + IMPD1_LOCK); + switch (vconr) { + case 0: + writel(val, impd1->base + IMPD1_OSC1); + break; + case 1: + writel(val, impd1->base + IMPD1_OSC2); + break; + } + writel(0, impd1->base + IMPD1_LOCK); + +#if DEBUG + vco.v = val & 0x1ff; + vco.r = (val >> 9) & 0x7f; + vco.s = (val >> 16) & 7; + + pr_debug("IM-PD1: VCO%d clock is %ld kHz\n", + vconr, icst525_khz(&impd1_vco_params, vco)); +#endif +} + +void impd1_tweak_control(struct device *dev, u32 mask, u32 val) +{ + struct impd1_module *impd1 = dev_get_drvdata(dev); + u32 cur; + + val &= mask; + cur = readl(impd1->base + IMPD1_CTRL) & ~mask; + writel(cur | val, impd1->base + IMPD1_CTRL); +} + +EXPORT_SYMBOL(impd1_tweak_control); + +/* + * CLCD support + */ +#define PANEL PROSPECTOR + +#define LTM10C209 1 +#define PROSPECTOR 2 +#define SVGA 3 +#define VGA 4 + +#if PANEL == VGA +#define PANELTYPE vga +static struct clcd_panel vga = { + .mode = { + .name = "VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39721, + .left_margin = 40, + .right_margin = 24, + .upper_margin = 32, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .connector = IMPD1_CTRL_DISP_VGA, + .bpp = 16, + .grayscale = 0, +}; + +#elif PANEL == SVGA +#define PANELTYPE svga +static struct clcd_panel svga = { + .mode = { + .name = "SVGA", + .refresh = 0, + .xres = 800, + .yres = 600, + .pixclock = 27778, + .left_margin = 20, + .right_margin = 20, + .upper_margin = 5, + .lower_margin = 5, + .hsync_len = 164, + .vsync_len = 62, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .connector = IMPD1_CTRL_DISP_VGA, + .bpp = 16, + .grayscale = 0, +}; + +#elif PANEL == PROSPECTOR +#define PANELTYPE prospector +static struct clcd_panel prospector = { + .mode = { + .name = "PROSPECTOR", + .refresh = 0, + .xres = 640, + .yres = 480, + .pixclock = 40000, + .left_margin = 33, + .right_margin = 64, + .upper_margin = 36, + .lower_margin = 7, + .hsync_len = 64, + .vsync_len = 25, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .fixedtimings = 1, + .connector = IMPD1_CTRL_DISP_LCD, + .bpp = 16, + .grayscale = 0, +}; + +#elif PANEL == LTM10C209 +#define PANELTYPE ltm10c209 +/* + * Untested. + */ +static struct clcd_panel ltm10c209 = { + .mode = { + .name = "LTM10C209", + .refresh = 0, + .xres = 640, + .yres = 480, + .pixclock = 40000, + .left_margin = 20, + .right_margin = 20, + .upper_margin = 19, + .lower_margin = 19, + .hsync_len = 20, + .vsync_len = 10, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .fixedtimings = 1, + .connector = IMPD1_CTRL_DISP_LCD, + .bpp = 16, + .grayscale = 0, +}; +#endif + +/* + * Disable all display connectors on the interface module. + */ +static void impd1fb_clcd_disable(struct clcd_fb *fb) +{ + impd1_tweak_control(fb->dev->dev.parent, IMPD1_CTRL_DISP_MASK, 0); +} + +/* + * Enable the relevant connector on the interface module. + */ +static void impd1fb_clcd_enable(struct clcd_fb *fb) +{ + impd1_tweak_control(fb->dev->dev.parent, IMPD1_CTRL_DISP_MASK, + fb->panel->connector | IMPD1_CTRL_DISP_ENABLE); +} + +static int impd1fb_clcd_setup(struct clcd_fb *fb) +{ + unsigned long framebase = fb->dev->res.start + 0x01000000; + unsigned long framesize = SZ_1M; + int ret = 0; + + fb->panel = &PANELTYPE; + + if (!request_mem_region(framebase, framesize, "clcd framebuffer")) { + printk(KERN_ERR "IM-PD1: unable to reserve framebuffer\n"); + return -EBUSY; + } + + fb->fb.screen_base = ioremap(framebase, framesize); + if (!fb->fb.screen_base) { + printk(KERN_ERR "IM-PD1: unable to map framebuffer\n"); + ret = -ENOMEM; + goto free_buffer; + } + + fb->fb.fix.smem_start = framebase; + fb->fb.fix.smem_len = framesize; + + return 0; + + free_buffer: + release_mem_region(framebase, framesize); + return ret; +} + +static int impd1fb_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + unsigned long start, size; + + start = vma->vm_pgoff + (fb->fb.fix.smem_start >> PAGE_SHIFT); + size = vma->vm_end - vma->vm_start; + + return remap_pfn_range(vma, vma->vm_start, start, size, + vma->vm_page_prot); +} + +static void impd1fb_clcd_remove(struct clcd_fb *fb) +{ + iounmap(fb->fb.screen_base); + release_mem_region(fb->fb.fix.smem_start, fb->fb.fix.smem_len); +} + +static struct clcd_board impd1_clcd_data = { + .name = "IM-PD/1", + .check = clcdfb_check, + .decode = clcdfb_decode, + .disable = impd1fb_clcd_disable, + .enable = impd1fb_clcd_enable, + .setup = impd1fb_clcd_setup, + .mmap = impd1fb_clcd_mmap, + .remove = impd1fb_clcd_remove, +}; + +struct impd1_device { + unsigned long offset; + unsigned int irq[2]; + unsigned int id; + void *platform_data; +}; + +static struct impd1_device impd1_devs[] = { + { + .offset = 0x03000000, + .id = 0x00041190, + }, { + .offset = 0x00100000, + .irq = { 1 }, + .id = 0x00141011, + }, { + .offset = 0x00200000, + .irq = { 2 }, + .id = 0x00141011, + }, { + .offset = 0x00300000, + .irq = { 3 }, + .id = 0x00041022, + }, { + .offset = 0x00400000, + .irq = { 4 }, + .id = 0x00041061, + }, { + .offset = 0x00500000, + .irq = { 5 }, + .id = 0x00041061, + }, { + .offset = 0x00600000, + .irq = { 6 }, + .id = 0x00041130, + }, { + .offset = 0x00700000, + .irq = { 7, 8 }, + .id = 0x00041181, + }, { + .offset = 0x00800000, + .irq = { 9 }, + .id = 0x00041041, + }, { + .offset = 0x01000000, + .irq = { 11 }, + .id = 0x00041110, + .platform_data = &impd1_clcd_data, + } +}; + +static const char *impd1_vconames[2] = { + "CLCDCLK", + "AUXVCO2", +}; + +static int impd1_probe(struct lm_device *dev) +{ + struct impd1_module *impd1; + int i, ret; + + if (dev->id != module_id) + return -EINVAL; + + if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers")) + return -EBUSY; + + impd1 = kmalloc(sizeof(struct impd1_module), GFP_KERNEL); + if (!impd1) { + ret = -ENOMEM; + goto release_lm; + } + memset(impd1, 0, sizeof(struct impd1_module)); + + impd1->base = ioremap(dev->resource.start, SZ_4K); + if (!impd1->base) { + ret = -ENOMEM; + goto free_impd1; + } + + lm_set_drvdata(dev, impd1); + + printk("IM-PD1 found at 0x%08lx\n", dev->resource.start); + + for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { + impd1->vcos[i].owner = THIS_MODULE, + impd1->vcos[i].name = impd1_vconames[i], + impd1->vcos[i].params = &impd1_vco_params, + impd1->vcos[i].data = impd1, + impd1->vcos[i].setvco = impd1_setvco; + + clk_register(&impd1->vcos[i]); + } + + for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { + struct impd1_device *idev = impd1_devs + i; + struct amba_device *d; + unsigned long pc_base; + + pc_base = dev->resource.start + idev->offset; + + d = kmalloc(sizeof(struct amba_device), GFP_KERNEL); + if (!d) + continue; + + memset(d, 0, sizeof(struct amba_device)); + + snprintf(d->dev.bus_id, sizeof(d->dev.bus_id), + "lm%x:%5.5lx", dev->id, idev->offset >> 12); + + d->dev.parent = &dev->dev; + d->res.start = dev->resource.start + idev->offset; + d->res.end = d->res.start + SZ_4K - 1; + d->res.flags = IORESOURCE_MEM; + d->irq[0] = dev->irq; + d->irq[1] = dev->irq; + d->periphid = idev->id; + d->dev.platform_data = idev->platform_data; + + ret = amba_device_register(d, &dev->resource); + if (ret) { + printk("unable to register device %s: %d\n", + d->dev.bus_id, ret); + kfree(d); + } + } + + return 0; + + free_impd1: + if (impd1 && impd1->base) + iounmap(impd1->base); + if (impd1) + kfree(impd1); + release_lm: + release_mem_region(dev->resource.start, SZ_4K); + return ret; +} + +static void impd1_remove(struct lm_device *dev) +{ + struct impd1_module *impd1 = lm_get_drvdata(dev); + struct list_head *l, *n; + int i; + + list_for_each_safe(l, n, &dev->dev.children) { + struct device *d = list_to_dev(l); + + device_unregister(d); + } + + for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) + clk_unregister(&impd1->vcos[i]); + + lm_set_drvdata(dev, NULL); + + iounmap(impd1->base); + kfree(impd1); + release_mem_region(dev->resource.start, SZ_4K); +} + +static struct lm_driver impd1_driver = { + .drv = { + .name = "impd1", + }, + .probe = impd1_probe, + .remove = impd1_remove, +}; + +static int __init impd1_init(void) +{ + return lm_driver_register(&impd1_driver); +} + +static void __exit impd1_exit(void) +{ + lm_driver_unregister(&impd1_driver); +} + +module_init(impd1_init); +module_exit(impd1_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Integrator/IM-PD1 logic module core driver"); +MODULE_AUTHOR("Deep Blue Solutions Ltd"); diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c new file mode 100644 index 0000000..91ba9fd --- /dev/null +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -0,0 +1,302 @@ +/* + * linux/arch/arm/mach-integrator/integrator_ap.c + * + * Copyright (C) 2000-2003 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/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/hardware/amba.h> +#include <asm/hardware/amba_kmi.h> + +#include <asm/arch/lm.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/irq.h> +#include <asm/mach/map.h> +#include <asm/mach/time.h> + +#include "common.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_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE) +#define VA_EBI_BASE IO_ADDRESS(INTEGRATOR_EBI_BASE) +#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET + +/* + * Logical Physical + * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M) + * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M) + * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k) + * ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M) + * 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 + * f1600000 16000000 UART 0 + * f1700000 17000000 UART 1 + * f1a00000 1a000000 Debug LEDs + * f1b00000 1b000000 GPIO + */ + +static struct map_desc ap_io_desc[] __initdata = { + { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, + { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE }, + { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE }, + { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_64K, MT_DEVICE }, + { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE } +}; + +static void __init ap_map_io(void) +{ + iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc)); +} + +#define INTEGRATOR_SC_VALID_INT 0x003fffff + +static void sc_mask_irq(unsigned int irq) +{ + writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); +} + +static void sc_unmask_irq(unsigned int irq) +{ + writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET); +} + +static struct irqchip sc_chip = { + .ack = sc_mask_irq, + .mask = sc_mask_irq, + .unmask = sc_unmask_irq, +}; + +static void __init ap_init_irq(void) +{ + unsigned int i; + + /* Disable all interrupts initially. */ + /* Do the core module ones */ + writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + + /* do the header card stuff next */ + writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); + writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); + + for (i = 0; i < NR_IRQS; i++) { + if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) { + set_irq_chip(i, &sc_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + } +} + +#ifdef CONFIG_PM +static unsigned long ic_irq_enable; + +static int irq_suspend(struct sys_device *dev, pm_message_t state) +{ + ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE); + return 0; +} + +static int irq_resume(struct sys_device *dev) +{ + /* disable all irq sources */ + writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); + writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); + + writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET); + return 0; +} +#else +#define irq_suspend NULL +#define irq_resume NULL +#endif + +static struct sysdev_class irq_class = { + set_kset_name("irq"), + .suspend = irq_suspend, + .resume = irq_resume, +}; + +static struct sys_device irq_device = { + .id = 0, + .cls = &irq_class, +}; + +static int __init irq_init_sysfs(void) +{ + int ret = sysdev_class_register(&irq_class); + if (ret == 0) + ret = sysdev_register(&irq_device); + return ret; +} + +device_initcall(irq_init_sysfs); + +/* + * Flash handling. + */ +#define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET) +#define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET) +#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET) +#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET) + +static int ap_flash_init(void) +{ + u32 tmp; + + writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); + + tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE; + writel(tmp, EBI_CSR1); + + if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) { + writel(0xa05f, EBI_LOCK); + writel(tmp, EBI_CSR1); + writel(0, EBI_LOCK); + } + return 0; +} + +static void ap_flash_exit(void) +{ + u32 tmp; + + writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); + + tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE; + writel(tmp, EBI_CSR1); + + if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) { + writel(0xa05f, EBI_LOCK); + writel(tmp, EBI_CSR1); + writel(0, EBI_LOCK); + } +} + +static void ap_flash_set_vpp(int on) +{ + unsigned long reg = on ? SC_CTRLS : SC_CTRLC; + + writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); +} + +static struct flash_platform_data ap_flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = ap_flash_init, + .exit = ap_flash_exit, + .set_vpp = ap_flash_set_vpp, +}; + +static struct resource cfi_flash_resource = { + .start = INTEGRATOR_FLASH_BASE, + .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { + .name = "armflash", + .id = 0, + .dev = { + .platform_data = &ap_flash_data, + }, + .num_resources = 1, + .resource = &cfi_flash_resource, +}; + +static void __init ap_init(void) +{ + unsigned long sc_dec; + int i; + + platform_device_register(&cfi_flash_device); + + sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); + for (i = 0; i < 4; i++) { + struct lm_device *lmdev; + + if ((sc_dec & (16 << i)) == 0) + continue; + + lmdev = kmalloc(sizeof(struct lm_device), GFP_KERNEL); + if (!lmdev) + continue; + + memset(lmdev, 0, sizeof(struct lm_device)); + + lmdev->resource.start = 0xc0000000 + 0x10000000 * i; + lmdev->resource.end = lmdev->resource.start + 0x0fffffff; + lmdev->resource.flags = IORESOURCE_MEM; + lmdev->irq = IRQ_AP_EXPINT0 + i; + lmdev->id = i; + + lm_device_register(lmdev); + } +} + +static void __init ap_init_timer(void) +{ + integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0); +} + +static struct sys_timer ap_timer = { + .init = ap_init_timer, + .offset = integrator_gettimeoffset, +}; + +MACHINE_START(INTEGRATOR, "ARM-Integrator") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) + BOOT_PARAMS(0x00000100) + MAPIO(ap_map_io) + INITIRQ(ap_init_irq) + .timer = &ap_timer, + INIT_MACHINE(ap_init) +MACHINE_END diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c new file mode 100644 index 0000000..68e15c3 --- /dev/null +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -0,0 +1,528 @@ +/* + * linux/arch/arm/mach-integrator/integrator_cp.c + * + * Copyright (C) 2003 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. + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/hardware/amba.h> +#include <asm/hardware/amba_kmi.h> +#include <asm/hardware/amba_clcd.h> +#include <asm/hardware/icst525.h> + +#include <asm/arch/cm.h> +#include <asm/arch/lm.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/irq.h> +#include <asm/mach/mmc.h> +#include <asm/mach/map.h> +#include <asm/mach/time.h> + +#include "common.h" +#include "clock.h" + +#define INTCP_PA_MMC_BASE 0x1c000000 +#define INTCP_PA_AACI_BASE 0x1d000000 + +#define INTCP_PA_FLASH_BASE 0x24000000 +#define INTCP_FLASH_SIZE SZ_32M + +#define INTCP_PA_CLCD_BASE 0xc0000000 + +#define INTCP_VA_CIC_BASE 0xf1000040 +#define INTCP_VA_PIC_BASE 0xf1400000 +#define INTCP_VA_SIC_BASE 0xfca00000 + +#define INTCP_PA_ETH_BASE 0xc8000000 +#define INTCP_ETH_SIZE 0x10 + +#define INTCP_VA_CTRL_BASE 0xfcb00000 +#define INTCP_FLASHPROG 0x04 +#define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) +#define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) + +/* + * Logical Physical + * f1000000 10000000 Core module registers + * f1100000 11000000 System controller registers + * f1200000 12000000 EBI registers + * f1300000 13000000 Counter/Timer + * f1400000 14000000 Interrupt controller + * f1600000 16000000 UART 0 + * f1700000 17000000 UART 1 + * f1a00000 1a000000 Debug LEDs + * f1b00000 1b000000 GPIO + */ + +static struct map_desc intcp_io_desc[] __initdata = { + { IO_ADDRESS(INTEGRATOR_HDR_BASE), INTEGRATOR_HDR_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_SC_BASE), INTEGRATOR_SC_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_EBI_BASE), INTEGRATOR_EBI_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_CT_BASE), INTEGRATOR_CT_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_IC_BASE), INTEGRATOR_IC_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, + { 0xfc900000, 0xc9000000, SZ_4K, MT_DEVICE }, + { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE }, + { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE }, +}; + +static void __init intcp_map_io(void) +{ + iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); +} + +#define cic_writel __raw_writel +#define cic_readl __raw_readl +#define pic_writel __raw_writel +#define pic_readl __raw_readl +#define sic_writel __raw_writel +#define sic_readl __raw_readl + +static void cic_mask_irq(unsigned int irq) +{ + irq -= IRQ_CIC_START; + cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); +} + +static void cic_unmask_irq(unsigned int irq) +{ + irq -= IRQ_CIC_START; + cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET); +} + +static struct irqchip cic_chip = { + .ack = cic_mask_irq, + .mask = cic_mask_irq, + .unmask = cic_unmask_irq, +}; + +static void pic_mask_irq(unsigned int irq) +{ + irq -= IRQ_PIC_START; + pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); +} + +static void pic_unmask_irq(unsigned int irq) +{ + irq -= IRQ_PIC_START; + pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET); +} + +static struct irqchip pic_chip = { + .ack = pic_mask_irq, + .mask = pic_mask_irq, + .unmask = pic_unmask_irq, +}; + +static void sic_mask_irq(unsigned int irq) +{ + irq -= IRQ_SIC_START; + sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); +} + +static void sic_unmask_irq(unsigned int irq) +{ + irq -= IRQ_SIC_START; + sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET); +} + +static struct irqchip sic_chip = { + .ack = sic_mask_irq, + .mask = sic_mask_irq, + .unmask = sic_unmask_irq, +}; + +static void +sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS); + + if (status == 0) { + do_bad_IRQ(irq, desc, regs); + return; + } + + do { + irq = ffs(status) - 1; + status &= ~(1 << irq); + + irq += IRQ_SIC_START; + + desc = irq_desc + irq; + desc->handle(irq, desc, regs); + } while (status); +} + +static void __init intcp_init_irq(void) +{ + unsigned int i; + + /* + * Disable all interrupt sources + */ + pic_writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); + pic_writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); + + for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) { + if (i == 11) + i = 22; + if (i == IRQ_CP_CPPLDINT) + i++; + if (i == 29) + break; + set_irq_chip(i, &pic_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + + cic_writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); + cic_writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); + + for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) { + set_irq_chip(i, &cic_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID); + } + + sic_writel(0x00000fff, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); + sic_writel(0x00000fff, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); + + for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { + set_irq_chip(i, &sic_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + + set_irq_handler(IRQ_CP_CPPLDINT, sic_handle_irq); + pic_unmask_irq(IRQ_CP_CPPLDINT); +} + +/* + * Clock handling + */ +#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) +#define CM_AUXOSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+0x1c) + +static const struct icst525_params cp_auxvco_params = { + .ref = 24000, + .vco_max = 320000, + .vd_min = 8, + .vd_max = 263, + .rd_min = 3, + .rd_max = 65, +}; + +static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco) +{ + u32 val; + + val = readl(CM_AUXOSC) & ~0x7ffff; + val |= vco.v | (vco.r << 9) | (vco.s << 16); + + writel(0xa05f, CM_LOCK); + writel(val, CM_AUXOSC); + writel(0, CM_LOCK); +} + +static struct clk cp_clcd_clk = { + .name = "CLCDCLK", + .params = &cp_auxvco_params, + .setvco = cp_auxvco_set, +}; + +static struct clk cp_mmci_clk = { + .name = "MCLK", + .rate = 14745600, +}; + +/* + * Flash handling. + */ +static int intcp_flash_init(void) +{ + u32 val; + + val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); + val |= CINTEGRATOR_FLASHPROG_FLWREN; + writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); + + return 0; +} + +static void intcp_flash_exit(void) +{ + u32 val; + + val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); + val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN); + writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); +} + +static void intcp_flash_set_vpp(int on) +{ + u32 val; + + val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); + if (on) + val |= CINTEGRATOR_FLASHPROG_FLVPPEN; + else + val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN; + writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); +} + +static struct flash_platform_data intcp_flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = intcp_flash_init, + .exit = intcp_flash_exit, + .set_vpp = intcp_flash_set_vpp, +}; + +static struct resource intcp_flash_resource = { + .start = INTCP_PA_FLASH_BASE, + .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device intcp_flash_device = { + .name = "armflash", + .id = 0, + .dev = { + .platform_data = &intcp_flash_data, + }, + .num_resources = 1, + .resource = &intcp_flash_resource, +}; + +static struct resource smc91x_resources[] = { + [0] = { + .start = INTCP_PA_ETH_BASE, + .end = INTCP_PA_ETH_BASE + INTCP_ETH_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CP_ETHINT, + .end = IRQ_CP_ETHINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct platform_device *intcp_devs[] __initdata = { + &intcp_flash_device, + &smc91x_device, +}; + +/* + * It seems that the card insertion interrupt remains active after + * we've acknowledged it. We therefore ignore the interrupt, and + * rely on reading it from the SIC. This also means that we must + * clear the latched interrupt. + */ +static unsigned int mmc_status(struct device *dev) +{ + unsigned int status = readl(0xfca00004); + writel(8, 0xfcb00008); + + return status & 8; +} + +static struct mmc_platform_data mmc_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .status = mmc_status, +}; + +static struct amba_device mmc_device = { + .dev = { + .bus_id = "mb:1c", + .platform_data = &mmc_data, + }, + .res = { + .start = INTCP_PA_MMC_BASE, + .end = INTCP_PA_MMC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }, + .periphid = 0, +}; + +static struct amba_device aaci_device = { + .dev = { + .bus_id = "mb:1d", + }, + .res = { + .start = INTCP_PA_AACI_BASE, + .end = INTCP_PA_AACI_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_CP_AACIINT, NO_IRQ }, + .periphid = 0, +}; + + +/* + * CLCD support + */ +static struct clcd_panel vga = { + .mode = { + .name = "VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39721, + .left_margin = 40, + .right_margin = 24, + .upper_margin = 32, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .bpp = 16, + .grayscale = 0, +}; + +/* + * Ensure VGA is selected. + */ +static void cp_clcd_enable(struct clcd_fb *fb) +{ + cm_control(CM_CTRL_LCDMUXSEL_MASK, CM_CTRL_LCDMUXSEL_VGA); +} + +static unsigned long framesize = SZ_1M; + +static int cp_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + fb->panel = &vga; + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, + &dma, GFP_KERNEL); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = framesize; + + return 0; +} + +static int cp_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, + fb->fb.fix.smem_len); +} + +static void cp_clcd_remove(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +static struct clcd_board clcd_data = { + .name = "Integrator/CP", + .check = clcdfb_check, + .decode = clcdfb_decode, + .enable = cp_clcd_enable, + .setup = cp_clcd_setup, + .mmap = cp_clcd_mmap, + .remove = cp_clcd_remove, +}; + +static struct amba_device clcd_device = { + .dev = { + .bus_id = "mb:c0", + .coherent_dma_mask = ~0, + .platform_data = &clcd_data, + }, + .res = { + .start = INTCP_PA_CLCD_BASE, + .end = INTCP_PA_CLCD_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .dma_mask = ~0, + .irq = { IRQ_CP_CLCDCINT, NO_IRQ }, + .periphid = 0, +}; + +static struct amba_device *amba_devs[] __initdata = { + &mmc_device, + &aaci_device, + &clcd_device, +}; + +static void __init intcp_init(void) +{ + int i; + + clk_register(&cp_clcd_clk); + clk_register(&cp_mmci_clk); + + platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); + + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } +} + +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ + +static void __init intcp_timer_init(void) +{ + integrator_time_init(1000000 / HZ, TIMER_CTRL_IE); +} + +static struct sys_timer cp_timer = { + .init = intcp_timer_init, + .offset = integrator_gettimeoffset, +}; + +MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) + BOOT_PARAMS(0x00000100) + MAPIO(intcp_map_io) + INITIRQ(intcp_init_irq) + .timer = &cp_timer, + INIT_MACHINE(intcp_init) +MACHINE_END diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c new file mode 100644 index 0000000..9d182b7 --- /dev/null +++ b/arch/arm/mach-integrator/leds.c @@ -0,0 +1,88 @@ +/* + * linux/arch/arm/mach-integrator/leds.c + * + * Integrator/AP and Integrator/CP 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> +#include <asm/arch/cm.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); + unsigned int update_alpha_leds; + + // yup, change the LEDs + local_irq_save(flags); + update_alpha_leds = 0; + + switch(ledevt) { + case led_idle_start: + cm_control(CM_CTRL_LED, 0); + break; + + case led_idle_end: + cm_control(CM_CTRL_LED, CM_CTRL_LED); + 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() || machine_is_cintegrator()) + leds_event = integrator_leds_event; + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c new file mode 100644 index 0000000..c5f19d1 --- /dev/null +++ b/arch/arm/mach-integrator/lm.c @@ -0,0 +1,96 @@ +/* + * linux/arch/arm/mach-integrator/lm.c + * + * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved. + * + * 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/module.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/arch/lm.h> + +#define to_lm_device(d) container_of(d, struct lm_device, dev) +#define to_lm_driver(d) container_of(d, struct lm_driver, drv) + +static int lm_match(struct device *dev, struct device_driver *drv) +{ + return 1; +} + +static struct bus_type lm_bustype = { + .name = "logicmodule", + .match = lm_match, +// .suspend = lm_suspend, +// .resume = lm_resume, +}; + +static int __init lm_init(void) +{ + return bus_register(&lm_bustype); +} + +postcore_initcall(lm_init); + +static int lm_bus_probe(struct device *dev) +{ + struct lm_device *lmdev = to_lm_device(dev); + struct lm_driver *lmdrv = to_lm_driver(dev->driver); + + return lmdrv->probe(lmdev); +} + +static int lm_bus_remove(struct device *dev) +{ + struct lm_device *lmdev = to_lm_device(dev); + struct lm_driver *lmdrv = to_lm_driver(dev->driver); + + lmdrv->remove(lmdev); + return 0; +} + +int lm_driver_register(struct lm_driver *drv) +{ + drv->drv.bus = &lm_bustype; + drv->drv.probe = lm_bus_probe; + drv->drv.remove = lm_bus_remove; + + return driver_register(&drv->drv); +} + +void lm_driver_unregister(struct lm_driver *drv) +{ + driver_unregister(&drv->drv); +} + +static void lm_device_release(struct device *dev) +{ + struct lm_device *d = to_lm_device(dev); + + kfree(d); +} + +int lm_device_register(struct lm_device *dev) +{ + int ret; + + dev->dev.release = lm_device_release; + dev->dev.bus = &lm_bustype; + + snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "lm%d", dev->id); + dev->resource.name = dev->dev.bus_id; + + ret = request_resource(&iomem_resource, &dev->resource); + if (ret == 0) { + ret = device_register(&dev->dev); + if (ret) + release_resource(&dev->resource); + } + return ret; +} + +EXPORT_SYMBOL(lm_driver_register); +EXPORT_SYMBOL(lm_driver_unregister); diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c new file mode 100644 index 0000000..394ec92 --- /dev/null +++ b/arch/arm/mach-integrator/pci.c @@ -0,0 +1,132 @@ +/* + * 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/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> +#include <asm/mach-types.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_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_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(void *); + +static struct hw_pci integrator_pci __initdata = { + .swizzle = integrator_swizzle, + .map_irq = integrator_map_irq, + .setup = pci_v3_setup, + .nr_controllers = 1, + .scan = pci_v3_scan_bus, + .preinit = pci_v3_preinit, + .postinit = pci_v3_postinit, +}; + +static int __init integrator_pci_init(void) +{ + if (machine_is_integrator()) + pci_common_init(&integrator_pci); + return 0; +} + +subsys_initcall(integrator_pci_init); diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c new file mode 100644 index 0000000..229a63a --- /dev/null +++ b/arch/arm/mach-integrator/pci_v3.c @@ -0,0 +1,604 @@ +/* + * linux/arch/arm/mach-integrator/pci_v3.c + * + * PCI functions for V3 host PCI bridge + * + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000-2001 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/kernel.h> +#include <linux/pci.h> +#include <linux/ptrace.h> +#include <linux/slab.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/io.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 + * 61000000 - 61FFFFFF 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. + * + * 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 61000000 - 61FFFFFF + * + * 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 61000000 - 61FFFFFF 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 v3_writeb(o,v) __raw_writeb(v, PCI_V3_VADDR + (unsigned int)(o)) +#define v3_readb(o) (__raw_readb(PCI_V3_VADDR + (unsigned int)(o))) + +#define v3_writew(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o)) +#define v3_readw(o) (__raw_readw(PCI_V3_VADDR + (unsigned int)(o))) + +#define v3_writel(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o)) +#define v3_readl(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 dependent 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 DEFINE_SPINLOCK(v3_lock); + +#define PCI_BUS_NONMEM_START 0x00000000 +#define PCI_BUS_NONMEM_SIZE SZ_256M + +#define PCI_BUS_PREMEM_START PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE +#define PCI_BUS_PREMEM_SIZE SZ_256M + +#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 + +#undef V3_LB_BASE_PREFETCH +#define V3_LB_BASE_PREFETCH 0 + +static unsigned long v3_open_config_window(struct pci_bus *bus, + unsigned int devfn, int offset) +{ + unsigned int address, mapaddress, busnr; + + busnr = bus->number; + + /* + * Trap out illegal values + */ + if (offset > 255) + BUG(); + if (busnr > 255) + BUG(); + if (devfn > 255) + BUG(); + + if (busnr == 0) { + int slot = PCI_SLOT(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(devfn) << 8; + mapaddress = V3_LB_MAP_TYPE_CONFIG; + + if (slot > 12) + /* + * high order bits are handled by the MAP register + */ + mapaddress |= 1 << (slot - 5); + 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 = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN; + address = (busnr << 16) | (devfn << 8); + } + + /* + * Set up base0 to see all 512Mbytes of memory space (not + * prefetchable), this frees up base1 for re-use by + * configuration memory + */ + v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) | + V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE); + + /* + * Set up base1/map1 to point into configuration space. + */ + v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) | + V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE); + v3_writew(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 + */ + v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) | + V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH | + V3_LB_BASE_ENABLE); + v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) | + V3_LB_MAP_TYPE_MEM_MULTIPLE); + + /* + * And shrink base0 back to a 256M window (NOTE: MAP0 already correct) + */ + v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) | + V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE); +} + +static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *val) +{ + unsigned long addr; + unsigned long flags; + u32 v; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(bus, devfn, where); + + switch (size) { + case 1: + v = __raw_readb(addr); + break; + + case 2: + v = __raw_readw(addr); + break; + + default: + v = __raw_readl(addr); + break; + } + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + *val = v; + return PCIBIOS_SUCCESSFUL; +} + +static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) +{ + unsigned long addr; + unsigned long flags; + + spin_lock_irqsave(&v3_lock, flags); + addr = v3_open_config_window(bus, devfn, where); + + switch (size) { + case 1: + __raw_writeb((u8)val, addr); + __raw_readb(addr); + break; + + case 2: + __raw_writew((u16)val, addr); + __raw_readw(addr); + break; + + case 4: + __raw_writel(val, addr); + __raw_readl(addr); + break; + } + + v3_close_config_window(); + spin_unlock_irqrestore(&v3_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pci_v3_ops = { + .read = v3_read_config, + .write = v3_write_config, +}; + +static struct resource non_mem = { + .name = "PCI non-prefetchable", + .start = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START, + .end = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct resource pre_mem = { + .name = "PCI prefetchable", + .start = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START, + .end = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1, + .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH, +}; + +static int __init pci_v3_setup_resources(struct resource **resource) +{ + if (request_resource(&iomem_resource, &non_mem)) { + printk(KERN_ERR "PCI: unable to allocate non-prefetchable " + "memory region\n"); + return -EBUSY; + } + if (request_resource(&iomem_resource, &pre_mem)) { + release_resource(&non_mem); + printk(KERN_ERR "PCI: unable to allocate prefetchable " + "memory region\n"); + return -EBUSY; + } + + /* + * 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 + */ + resource[0] = &ioport_resource; + resource[1] = &non_mem; + resource[2] = &pre_mem; + + return 1; +} + +/* + * These don't seem to be implemented on the Integrator I have, which + * means I can't get additional information on the reason for the pm2fb + * problems. I suppose I'll just have to mind-meld with the machine. ;) + */ +#define SC_PCI (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_PCIENABLE_OFFSET) +#define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x20) +#define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x24) + +static int +v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + unsigned long pc = instruction_pointer(regs); + unsigned long instr = *(unsigned long *)pc; +#if 0 + char buf[128]; + + sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", + addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255, + v3_readb(V3_LB_ISTAT)); + printk(KERN_DEBUG "%s", buf); + printascii(buf); +#endif + + v3_writeb(V3_LB_ISTAT, 0); + __raw_writel(3, SC_PCI); + + /* + * If the instruction being executed was a read, + * make it look like it read all-ones. + */ + if ((instr & 0x0c100000) == 0x04100000) { + int reg = (instr >> 12) & 15; + unsigned long val; + + if (instr & 0x00400000) + val = 255; + else + val = -1; + + regs->uregs[reg] = val; + regs->ARM_pc += 4; + return 0; + } + + if ((instr & 0x0e100090) == 0x00100090) { + int reg = (instr >> 12) & 15; + + regs->uregs[reg] = -1; + regs->ARM_pc += 4; + return 0; + } + + return 1; +} + +static irqreturn_t v3_irq(int irq, void *devid, struct pt_regs *regs) +{ +#ifdef CONFIG_DEBUG_LL + unsigned long pc = instruction_pointer(regs); + unsigned long instr = *(unsigned long *)pc; + char buf[128]; + + sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", irq, + pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255, + v3_readb(V3_LB_ISTAT)); + printascii(buf); +#endif + + v3_writew(V3_PCI_STAT, 0xf000); + v3_writeb(V3_LB_ISTAT, 0); + __raw_writel(3, SC_PCI); + +#ifdef CONFIG_DEBUG_LL + /* + * If the instruction being executed was a read, + * make it look like it read all-ones. + */ + if ((instr & 0x0c100000) == 0x04100000) { + int reg = (instr >> 16) & 15; + sprintf(buf, " reg%d = %08lx\n", reg, regs->uregs[reg]); + printascii(buf); + } +#endif + return IRQ_HANDLED; +} + +int __init pci_v3_setup(int nr, struct pci_sys_data *sys) +{ + int ret = 0; + + if (nr == 0) { + sys->mem_offset = PHYS_PCI_MEM_BASE; + ret = pci_v3_setup_resources(sys->resource); + } + + return ret; +} + +struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &pci_v3_ops, sys); +} + +/* + * V3_LB_BASE? - local bus address + * V3_LB_MAP? - pci bus address + */ +void __init pci_v3_preinit(void) +{ + unsigned long flags; + unsigned int temp; + int ret; + + /* + * Hook in our fault handler for PCI errors + */ + hook_fault_code(4, v3_pci_fault, SIGBUS, "external abort on linefetch"); + hook_fault_code(6, v3_pci_fault, SIGBUS, "external abort on linefetch"); + hook_fault_code(8, v3_pci_fault, SIGBUS, "external abort on non-linefetch"); + hook_fault_code(10, v3_pci_fault, SIGBUS, "external abort on non-linefetch"); + + spin_lock_irqsave(&v3_lock, flags); + + /* + * Unlock V3 registers, but only if they were previously locked. + */ + if (v3_readw(V3_SYSTEM) & V3_SYSTEM_M_LOCK) + v3_writew(V3_SYSTEM, 0xa05f); + + /* + * Setup window 0 - PCI non-prefetchable memory + * Local: 0x40000000 Bus: 0x00000000 Size: 256MB + */ + v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) | + V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE); + v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(PCI_BUS_NONMEM_START) | + V3_LB_MAP_TYPE_MEM); + + /* + * Setup window 1 - PCI prefetchable memory + * Local: 0x50000000 Bus: 0x10000000 Size: 256MB + */ + v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) | + V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH | + V3_LB_BASE_ENABLE); + v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) | + V3_LB_MAP_TYPE_MEM_MULTIPLE); + + /* + * Setup window 2 - PCI IO + */ + v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(PHYS_PCI_IO_BASE) | + V3_LB_BASE_ENABLE); + v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0)); + + /* + * Disable PCI to host IO cycles + */ + temp = v3_readw(V3_PCI_CFG) & ~V3_PCI_CFG_M_I2O_EN; + temp |= V3_PCI_CFG_M_IO_REG_DIS | V3_PCI_CFG_M_IO_DIS; + v3_writew(V3_PCI_CFG, temp); + + printk(KERN_DEBUG "FIFO_CFG: %04x FIFO_PRIO: %04x\n", + v3_readw(V3_FIFO_CFG), v3_readw(V3_FIFO_PRIORITY)); + + /* + * Set the V3 FIFO such that writes have higher priority than + * reads, and local bus write causes local bus read fifo flush. + * Same for PCI. + */ + v3_writew(V3_FIFO_PRIORITY, 0x0a0a); + + /* + * Re-lock the system register. + */ + temp = v3_readw(V3_SYSTEM) | V3_SYSTEM_M_LOCK; + v3_writew(V3_SYSTEM, temp); + + /* + * Clear any error conditions, and enable write errors. + */ + v3_writeb(V3_LB_ISTAT, 0); + v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10)); + v3_writeb(V3_LB_IMASK, 0x28); + __raw_writel(3, SC_PCI); + + /* + * Grab the PCI error interrupt. + */ + ret = request_irq(IRQ_AP_V3INT, v3_irq, 0, "V3", NULL); + if (ret) + printk(KERN_ERR "PCI: unable to grab PCI error " + "interrupt: %d\n", ret); + + spin_unlock_irqrestore(&v3_lock, flags); +} + +void __init pci_v3_postinit(void) +{ + unsigned int pci_cmd; + + pci_cmd = PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; + + v3_writew(V3_PCI_CMD, pci_cmd); + + v3_writeb(V3_LB_ISTAT, ~0x40); + v3_writeb(V3_LB_IMASK, 0x68); + +#if 0 + ret = request_irq(IRQ_AP_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL); + if (ret) + printk(KERN_ERR "PCI: unable to grab local bus timeout " + "interrupt: %d\n", ret); +#endif +} diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c new file mode 100644 index 0000000..20729de --- /dev/null +++ b/arch/arm/mach-integrator/time.c @@ -0,0 +1,213 @@ +/* + * linux/arch/arm/mach-integrator/time.c + * + * Copyright (C) 2000-2001 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 version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/time.h> +#include <linux/mc146818rtc.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/hardware/amba.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/rtc.h> + +#include <asm/mach/time.h> + +#define RTC_DR (0) +#define RTC_MR (4) +#define RTC_STAT (8) +#define RTC_EOI (8) +#define RTC_LR (12) +#define RTC_CR (16) +#define RTC_CR_MIE (1 << 0) + +extern int (*set_rtc)(void); +static void __iomem *rtc_base; + +static int integrator_set_rtc(void) +{ + __raw_writel(xtime.tv_sec, rtc_base + RTC_LR); + return 1; +} + +static void rtc_read_alarm(struct rtc_wkalrm *alrm) +{ + rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); +} + +static int rtc_set_alarm(struct rtc_wkalrm *alrm) +{ + unsigned long time; + int ret; + + ret = rtc_tm_to_time(&alrm->time, &time); + if (ret == 0) + writel(time, rtc_base + RTC_MR); + return ret; +} + +static void rtc_read_time(struct rtc_time *tm) +{ + rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); +} + +/* + * Set the RTC time. Unfortunately, we can't accurately set + * the point at which the counter updates. + * + * Also, since RTC_LR is transferred to RTC_CR on next rising + * edge of the 1Hz clock, we must write the time one second + * in advance. + */ +static int rtc_set_time(struct rtc_time *tm) +{ + unsigned long time; + int ret; + + ret = rtc_tm_to_time(tm, &time); + if (ret == 0) + writel(time + 1, rtc_base + RTC_LR); + + return ret; +} + +static struct rtc_ops rtc_ops = { + .owner = THIS_MODULE, + .read_time = rtc_read_time, + .set_time = rtc_set_time, + .read_alarm = rtc_read_alarm, + .set_alarm = rtc_set_alarm, +}; + +static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + writel(0, rtc_base + RTC_EOI); + return IRQ_HANDLED; +} + +static int rtc_probe(struct amba_device *dev, void *id) +{ + int ret; + + if (rtc_base) + return -EBUSY; + + ret = amba_request_regions(dev, NULL); + if (ret) + goto out; + + rtc_base = ioremap(dev->res.start, SZ_4K); + if (!rtc_base) { + ret = -ENOMEM; + goto res_out; + } + + __raw_writel(0, rtc_base + RTC_CR); + __raw_writel(0, rtc_base + RTC_EOI); + + xtime.tv_sec = __raw_readl(rtc_base + RTC_DR); + + ret = request_irq(dev->irq[0], rtc_interrupt, SA_INTERRUPT, + "rtc-pl030", dev); + if (ret) + goto map_out; + + ret = register_rtc(&rtc_ops); + if (ret) + goto irq_out; + + set_rtc = integrator_set_rtc; + return 0; + + irq_out: + free_irq(dev->irq[0], dev); + map_out: + iounmap(rtc_base); + rtc_base = NULL; + res_out: + amba_release_regions(dev); + out: + return ret; +} + +static int rtc_remove(struct amba_device *dev) +{ + set_rtc = NULL; + + writel(0, rtc_base + RTC_CR); + + free_irq(dev->irq[0], dev); + unregister_rtc(&rtc_ops); + + iounmap(rtc_base); + rtc_base = NULL; + amba_release_regions(dev); + + return 0; +} + +static struct timespec rtc_delta; + +static int rtc_suspend(struct amba_device *dev, pm_message_t state) +{ + struct timespec rtc; + + rtc.tv_sec = readl(rtc_base + RTC_DR); + rtc.tv_nsec = 0; + save_time_delta(&rtc_delta, &rtc); + + return 0; +} + +static int rtc_resume(struct amba_device *dev) +{ + struct timespec rtc; + + rtc.tv_sec = readl(rtc_base + RTC_DR); + rtc.tv_nsec = 0; + restore_time_delta(&rtc_delta, &rtc); + + return 0; +} + +static struct amba_id rtc_ids[] = { + { + .id = 0x00041030, + .mask = 0x000fffff, + }, + { 0, 0 }, +}; + +static struct amba_driver rtc_driver = { + .drv = { + .name = "rtc-pl030", + }, + .probe = rtc_probe, + .remove = rtc_remove, + .suspend = rtc_suspend, + .resume = rtc_resume, + .id_table = rtc_ids, +}; + +static int __init integrator_rtc_init(void) +{ + return amba_driver_register(&rtc_driver); +} + +static void __exit integrator_rtc_exit(void) +{ + amba_driver_unregister(&rtc_driver); +} + +module_init(integrator_rtc_init); +module_exit(integrator_rtc_exit); diff --git a/arch/arm/mach-iop3xx/Kconfig b/arch/arm/mach-iop3xx/Kconfig new file mode 100644 index 0000000..2bfe8c7 --- /dev/null +++ b/arch/arm/mach-iop3xx/Kconfig @@ -0,0 +1,63 @@ +if ARCH_IOP3XX + +menu "IOP3xx Implementation Options" + +comment "IOP3xx Platform Types" + +config ARCH_IQ80321 + bool "Enable support for IQ80321" + select ARCH_IOP321 + help + Say Y here if you want to run your kernel on the Intel IQ80321 + evaluation kit for the IOP321 chipset. + +config ARCH_IQ31244 + bool "Enable support for IQ31244" + select ARCH_IOP321 + help + Say Y here if you want to run your kernel on the Intel IQ31244 + evaluation kit for the IOP321 chipset. + +config ARCH_IQ80331 + bool "Enable support for IQ80331" + select ARCH_IOP331 + help + Say Y here if you want to run your kernel on the Intel IQ80331 + evaluation kit for the IOP331 chipset. + +config MACH_IQ80332 + bool "Enable support for IQ80332" + select ARCH_IOP331 + help + Say Y here if you want to run your kernel on the Intel IQ80332 + evaluation kit for the IOP332 chipset + +config ARCH_EP80219 + bool "Enable support for EP80219" + select ARCH_IOP321 + select ARCH_IQ31244 + +# Which IOP variant are we running? +config ARCH_IOP321 + bool + help + The IQ80321 uses the IOP321 variant. + The IQ31244 and EP80219 uses the IOP321 variant. + +config ARCH_IOP331 + bool + default ARCH_IQ80331 + help + The IQ80331, IQ80332, and IQ80333 uses the IOP331 variant. + +comment "IOP3xx Chipset Features" + +config IOP331_STEPD + bool "Chip stepping D of the IOP80331 processor or IOP80333" + depends on (ARCH_IOP331) + help + Say Y here if you have StepD of the IOP80331 or IOP8033 + based platforms. + +endmenu +endif diff --git a/arch/arm/mach-iop3xx/Makefile b/arch/arm/mach-iop3xx/Makefile new file mode 100644 index 0000000..b17eb1f --- /dev/null +++ b/arch/arm/mach-iop3xx/Makefile @@ -0,0 +1,23 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := common.o + +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_IOP321) += iop321-setup.o iop321-irq.o iop321-pci.o iop321-time.o + +obj-$(CONFIG_ARCH_IOP331) += iop331-setup.o iop331-irq.o iop331-pci.o iop331-time.o + +obj-$(CONFIG_ARCH_IQ80321) += iq80321-mm.o iq80321-pci.o + +obj-$(CONFIG_ARCH_IQ31244) += iq31244-mm.o iq31244-pci.o + +obj-$(CONFIG_ARCH_IQ80331) += iq80331-mm.o iq80331-pci.o + +obj-$(CONFIG_MACH_IQ80332) += iq80332-mm.o iq80332-pci.o diff --git a/arch/arm/mach-iop3xx/Makefile.boot b/arch/arm/mach-iop3xx/Makefile.boot new file mode 100644 index 0000000..6387aa2 --- /dev/null +++ b/arch/arm/mach-iop3xx/Makefile.boot @@ -0,0 +1,9 @@ + zreladdr-y := 0xa0008000 +params_phys-y := 0xa0000100 +initrd_phys-y := 0xa0800000 +ifeq ($(CONFIG_ARCH_IOP331),y) + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 +endif + diff --git a/arch/arm/mach-iop3xx/common.c b/arch/arm/mach-iop3xx/common.c new file mode 100644 index 0000000..bda7394 --- /dev/null +++ b/arch/arm/mach-iop3xx/common.c @@ -0,0 +1,74 @@ +/* + * arch/arm/mach-iop3xx/common.c + * + * Common routines shared across all IOP3xx implementations + * + * Author: Deepak Saxena <dsaxena@mvista.com> + * + * Copyright 2003 (c) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/config.h> +#include <linux/delay.h> +#include <asm/hardware.h> + +/* + * Shared variables + */ +unsigned long iop3xx_pcibios_min_io = 0; +unsigned long iop3xx_pcibios_min_mem = 0; + +#ifdef CONFIG_ARCH_EP80219 +#include <linux/kernel.h> +/* + * Default power-off for EP80219 + */ +#include <asm/mach-types.h> + +static inline void ep80219_send_to_pic(__u8 c) { +} + +void ep80219_power_off(void) +{ + /* + * This function will send a SHUTDOWN_COMPLETE message to the PIC controller + * over I2C. We are not using the i2c subsystem since we are going to power + * off and it may be removed + */ + + /* Send the Address byte w/ the start condition */ + *IOP321_IDBR1 = 0x60; + *IOP321_ICR1 = 0xE9; + mdelay(1); + + /* Send the START_MSG byte w/ no start or stop condition */ + *IOP321_IDBR1 = 0x0F; + *IOP321_ICR1 = 0xE8; + mdelay(1); + + /* Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or stop condition */ + *IOP321_IDBR1 = 0x03; + *IOP321_ICR1 = 0xE8; + mdelay(1); + + /* Send an ignored byte w/ stop condition */ + *IOP321_IDBR1 = 0x00; + *IOP321_ICR1 = 0xEA; + + while (1) ; +} + +#include <linux/init.h> +#include <linux/pm.h> + +static int __init ep80219_init(void) +{ + pm_power_off = ep80219_power_off; + return 0; +} +arch_initcall(ep80219_init); +#endif diff --git a/arch/arm/mach-iop3xx/iop321-irq.c b/arch/arm/mach-iop3xx/iop321-irq.c new file mode 100644 index 0000000..d42aae6 --- /dev/null +++ b/arch/arm/mach-iop3xx/iop321-irq.c @@ -0,0 +1,96 @@ +/* + * linux/arch/arm/mach-iop3xx/iop321-irq.c + * + * Generic IOP321 IRQ handling functionality + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * + * 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. + * + * Added IOP3XX chipset and IQ80321 board masking code. + * + */ +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/list.h> + +#include <asm/mach/irq.h> +#include <asm/irq.h> +#include <asm/hardware.h> + +#include <asm/mach-types.h> + +static u32 iop321_mask /* = 0 */; + +static inline void intctl_write(u32 val) +{ + asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); +} + +static inline void intstr_write(u32 val) +{ + asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val)); +} + +static void +iop321_irq_mask (unsigned int irq) +{ + + iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS)); + + intctl_write(iop321_mask); +} + +static void +iop321_irq_unmask (unsigned int irq) +{ + iop321_mask |= (1 << (irq - IOP321_IRQ_OFS)); + + intctl_write(iop321_mask); +} + +struct irqchip ext_chip = { + .ack = iop321_irq_mask, + .mask = iop321_irq_mask, + .unmask = iop321_irq_unmask, +}; + +void __init iop321_init_irq(void) +{ + unsigned int i, tmp; + + /* Enable access to coprocessor 6 for dealing with IRQs. + * From RMK: + * Basically, the Intel documentation here is poor. It appears that + * you need to set the bit to be able to access the coprocessor from + * SVC mode. Whether that allows access from user space or not is + * unclear. + */ + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "orr %0, %0, %1\n\t" + "mcr p15, 0, %0, c15, c1, 0\n\t" + /* The action is delayed, so we have to do this: */ + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4" + : "=r" (tmp) : "i" (1 << 6) ); + + intctl_write(0); // disable all interrupts + intstr_write(0); // treat all as IRQ + if(machine_is_iq80321() || + machine_is_iq31244()) // all interrupts are inputs to chip + *IOP321_PCIIRSR = 0x0f; + + for(i = IOP321_IRQ_OFS; i < NR_IOP321_IRQS; i++) + { + set_irq_chip(i, &ext_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + + } +} + diff --git a/arch/arm/mach-iop3xx/iop321-pci.c b/arch/arm/mach-iop3xx/iop321-pci.c new file mode 100644 index 0000000..8ba6a0e --- /dev/null +++ b/arch/arm/mach-iop3xx/iop321-pci.c @@ -0,0 +1,220 @@ +/* + * arch/arm/mach-iop3xx/iop321-pci.c + * + * PCI support for the Intel IOP321 chipset + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * + * 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/pci.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/ioport.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach/pci.h> + +#include <asm/arch/iop321.h> + +// #define DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +/* + * This routine builds either a type0 or type1 configuration command. If the + * bus is on the 80321 then a type0 made, else a type1 is created. + */ +static u32 iop321_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + if (sys->busnr == bus->number) + addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); + else + addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; + + addr |= PCI_FUNC(devfn) << 8 | (where & ~3); + + return addr; +} + +/* + * This routine checks the status of the last configuration cycle. If an error + * was detected it returns a 1, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop321_pci_status(void) +{ + unsigned int status; + int ret = 0; + + /* + * Check the status registers. + */ + status = *IOP321_ATUSR; + if (status & 0xf900) + { + DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); + *IOP321_ATUSR = status & 0xf900; + ret = 1; + } + status = *IOP321_ATUISR; + if (status & 0x679f) + { + DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); + *IOP321_ATUISR = status & 0x679f; + ret = 1; + } + return ret; +} + +/* + * Simply write the address register and read the configuration + * data. Note that the 4 nop's ensure that we are able to handle + * a delayed abort (in theory.) + */ +static inline u32 iop321_read(unsigned long addr) +{ + u32 val; + + __asm__ __volatile__( + "str %1, [%2]\n\t" + "ldr %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : "=r" (val) + : "r" (addr), "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); + + return val; +} + +/* + * The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop321_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = iop321_cfg_address(bus, devfn, where); + u32 val = iop321_read(addr) >> ((where & 3) * 8); + + if( iop321_pci_status() ) + val = 0xffffffff; + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop321_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop321_read(addr); + if (!iop321_pci_status() == 0) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + *IOP321_OCCDR = val | value << where; + } else { + asm volatile( + "str %1, [%2]\n\t" + "str %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : + : "r" (value), "r" (addr), + "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop321_ops = { + .read = iop321_read_config, + .write = iop321_write_config, +}; + +/* + * When a PCI device does not exist during config cycles, the 80200 gets a + * bus error instead of returning 0xffffffff. This handler simply returns. + */ +int +iop321_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", + addr, fsr, regs->ARM_pc, regs->ARM_lr); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +/* + * Scan an IOP321 PCI bus. sys->bus defines which bus we scan. + */ +struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &iop321_ops, sys); +} + +void iop321_init(void) +{ + DBG("PCI: Intel 80321 PCI init code.\n"); + DBG("ATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD); + DBG("ATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n", + *IOP321_OMWTVR0, + *IOP321_OIOWTVR); + DBG("ATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR); + DBG("ATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n", + *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0); + DBG("ATU: IOP321_OMWTVR0=0x%08x\n", *IOP321_OMWTVR0); + DBG("ATU: IOP321_IABAR1=0x%08x IOP321_IALR1=0x%08x\n", + *IOP321_IABAR1, *IOP321_IALR1); + DBG("ATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n", + *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR); + DBG("ATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n", + *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2); + DBG("ATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n", + *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3); + + hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort"); +} + diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c new file mode 100644 index 0000000..bf23e0f --- /dev/null +++ b/arch/arm/mach-iop3xx/iop321-setup.c @@ -0,0 +1,169 @@ +/* + * linux/arch/arm/mach-iop3xx/iop321-setup.c + * + * Author: Nicolas Pitre <nico@cam.org> + * Copyright (C) 2001 MontaVista Software, Inc. + * Copyright (C) 2004 Intel Corporation. + * + * 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/mm.h> +#include <linux/init.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/major.h> +#include <linux/fs.h> +#include <linux/device.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_core.h> + +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/mach/map.h> +#include <asm/setup.h> +#include <asm/system.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#define IOP321_UART_XTAL 1843200 + +/* + * Standard IO mapping for all IOP321 based systems + */ +static struct map_desc iop321_std_desc[] __initdata = { + /* virtual physical length type */ + + /* mem mapped registers */ + { IOP321_VIRT_MEM_BASE, IOP321_PHYS_MEM_BASE, 0x00002000, MT_DEVICE }, + + /* PCI IO space */ + { IOP321_PCI_LOWER_IO_VA, IOP321_PCI_LOWER_IO_PA, IOP321_PCI_IO_WINDOW_SIZE, MT_DEVICE } +}; + +#ifdef CONFIG_ARCH_IQ80321 +#define UARTBASE IQ80321_UART +#define IRQ_UART IRQ_IQ80321_UART +#endif + +#ifdef CONFIG_ARCH_IQ31244 +#define UARTBASE IQ31244_UART +#define IRQ_UART IRQ_IQ31244_UART +#endif + +static struct uart_port iop321_serial_ports[] = { + { + .membase = (char*)(UARTBASE), + .mapbase = (UARTBASE), + .irq = IRQ_UART, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = IOP321_UART_XTAL, + .line = 0, + .type = PORT_16550A, + .fifosize = 16 + } +}; + +static struct resource iop32x_i2c_0_resources[] = { + [0] = { + .start = 0xfffff680, + .end = 0xfffff698, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP321_I2C_0, + .end = IRQ_IOP321_I2C_0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop32x_i2c_1_resources[] = { + [0] = { + .start = 0xfffff6a0, + .end = 0xfffff6b8, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP321_I2C_1, + .end = IRQ_IOP321_I2C_1, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device iop32x_i2c_0_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop32x_i2c_0_resources +}; + +static struct platform_device iop32x_i2c_1_controller = { + .name = "IOP3xx-I2C", + .id = 1, + .num_resources = 2, + .resource = iop32x_i2c_1_resources +}; + +static struct platform_device *iop32x_devices[] __initdata = { + &iop32x_i2c_0_controller, + &iop32x_i2c_1_controller +}; + +void __init iop32x_init(void) +{ + if(iop_is_321()) + { + platform_add_devices(iop32x_devices, + ARRAY_SIZE(iop32x_devices)); + } +} + +void __init iop321_map_io(void) +{ + iotable_init(iop321_std_desc, ARRAY_SIZE(iop321_std_desc)); + early_serial_setup(&iop321_serial_ports[0]); +} + +#ifdef CONFIG_ARCH_IQ80321 +extern void iq80321_map_io(void); +extern struct sys_timer iop321_timer; +extern void iop321_init_time(void); +#endif + +#ifdef CONFIG_ARCH_IQ31244 +extern void iq31244_map_io(void); +extern struct sys_timer iop321_timer; +extern void iop321_init_time(void); +#endif + +#if defined(CONFIG_ARCH_IQ80321) +MACHINE_START(IQ80321, "Intel IQ80321") + MAINTAINER("Intel Corporation") + BOOT_MEM(PHYS_OFFSET, IQ80321_UART, IQ80321_UART) + MAPIO(iq80321_map_io) + INITIRQ(iop321_init_irq) + .timer = &iop321_timer, + BOOT_PARAMS(0xa0000100) + INIT_MACHINE(iop32x_init) +MACHINE_END +#elif defined(CONFIG_ARCH_IQ31244) +MACHINE_START(IQ31244, "Intel IQ31244") + MAINTAINER("Intel Corp.") + BOOT_MEM(PHYS_OFFSET, IQ31244_UART, IQ31244_UART) + MAPIO(iq31244_map_io) + INITIRQ(iop321_init_irq) + .timer = &iop321_timer, + BOOT_PARAMS(0xa0000100) + INIT_MACHINE(iop32x_init) +MACHINE_END +#else +#error No machine descriptor defined for this IOP3XX implementation +#endif diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c new file mode 100644 index 0000000..9b7dd64 --- /dev/null +++ b/arch/arm/mach-iop3xx/iop321-time.c @@ -0,0 +1,109 @@ +/* + * arch/arm/mach-iop3xx/iop321-time.c + * + * Timer code for IOP321 based systems + * + * Author: Deepak Saxena <dsaxena@mvista.com> + * + * Copyright 2002-2003 MontaVista Software Inc. + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/time.h> +#include <linux/init.h> +#include <linux/timex.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/mach-types.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> + +#define IOP321_TIME_SYNC 0 + +static inline unsigned long get_elapsed(void) +{ + return LATCH - *IOP321_TU_TCR0; +} + +static unsigned long iop321_gettimeoffset(void) +{ + unsigned long elapsed, usec; + u32 tisr1, tisr2; + + /* + * If an interrupt was pending before we read the timer, + * we've already wrapped. Factor this into the time. + * If an interrupt was pending after we read the timer, + * it may have wrapped between checking the interrupt + * status and reading the timer. Re-read the timer to + * be sure its value is after the wrap. + */ + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); + elapsed = get_elapsed(); + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); + + if(tisr1 & 1) + elapsed += LATCH; + else if (tisr2 & 1) + elapsed = LATCH + get_elapsed(); + + /* + * Now convert them to usec. + */ + usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH; + + return usec; +} + +static irqreturn_t +iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 tisr; + + write_seqlock(&xtime_lock); + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); + tisr |= 1; + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction iop321_timer_irq = { + .name = "IOP321 Timer Tick", + .handler = iop321_timer_interrupt, + .flags = SA_INTERRUPT +}; + +static void __init iop321_timer_init(void) +{ + u32 timer_ctl; + + setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq); + + timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD | + IOP321_TMR_RATIO_1_1; + + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); + + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); +} + +struct sys_timer iop321_timer = { + .init = &iop321_timer_init, + .offset = iop321_gettimeoffset, +}; diff --git a/arch/arm/mach-iop3xx/iop331-irq.c b/arch/arm/mach-iop3xx/iop331-irq.c new file mode 100644 index 0000000..f4d4321 --- /dev/null +++ b/arch/arm/mach-iop3xx/iop331-irq.c @@ -0,0 +1,127 @@ +/* + * linux/arch/arm/mach-iop3xx/iop331-irq.c + * + * Generic IOP331 IRQ handling functionality + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2003 Intel Corp. + * + * 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/init.h> +#include <linux/interrupt.h> +#include <linux/list.h> + +#include <asm/mach/irq.h> +#include <asm/irq.h> +#include <asm/hardware.h> + +#include <asm/mach-types.h> + +static u32 iop331_mask0 = 0; +static u32 iop331_mask1 = 0; + +static inline void intctl_write0(u32 val) +{ + // INTCTL0 + asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); +} + +static inline void intctl_write1(u32 val) +{ + // INTCTL1 + asm volatile("mcr p6,0,%0,c1,c0,0"::"r" (val)); +} + +static inline void intstr_write0(u32 val) +{ + // INTSTR0 + asm volatile("mcr p6,0,%0,c2,c0,0"::"r" (val)); +} + +static inline void intstr_write1(u32 val) +{ + // INTSTR1 + asm volatile("mcr p6,0,%0,c3,c0,0"::"r" (val)); +} + +static void +iop331_irq_mask1 (unsigned int irq) +{ + iop331_mask0 &= ~(1 << (irq - IOP331_IRQ_OFS)); + intctl_write0(iop331_mask0); +} + +static void +iop331_irq_mask2 (unsigned int irq) +{ + iop331_mask1 &= ~(1 << (irq - IOP331_IRQ_OFS - 32)); + intctl_write1(iop331_mask1); +} + +static void +iop331_irq_unmask1(unsigned int irq) +{ + iop331_mask0 |= (1 << (irq - IOP331_IRQ_OFS)); + intctl_write0(iop331_mask0); +} + +static void +iop331_irq_unmask2(unsigned int irq) +{ + iop331_mask1 |= (1 << (irq - IOP331_IRQ_OFS - 32)); + intctl_write1(iop331_mask1); +} + +struct irqchip iop331_irqchip1 = { + .ack = iop331_irq_mask1, + .mask = iop331_irq_mask1, + .unmask = iop331_irq_unmask1, +}; + +struct irqchip iop331_irqchip2 = { + .ack = iop331_irq_mask2, + .mask = iop331_irq_mask2, + .unmask = iop331_irq_unmask2, +}; + +void __init iop331_init_irq(void) +{ + unsigned int i, tmp; + + /* Enable access to coprocessor 6 for dealing with IRQs. + * From RMK: + * Basically, the Intel documentation here is poor. It appears that + * you need to set the bit to be able to access the coprocessor from + * SVC mode. Whether that allows access from user space or not is + * unclear. + */ + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "orr %0, %0, %1\n\t" + "mcr p15, 0, %0, c15, c1, 0\n\t" + /* The action is delayed, so we have to do this: */ + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4" + : "=r" (tmp) : "i" (1 << 6) ); + + intctl_write0(0); // disable all interrupts + intctl_write1(0); + intstr_write0(0); // treat all as IRQ + intstr_write1(0); + if(machine_is_iq80331()) // all interrupts are inputs to chip + *IOP331_PCIIRSR = 0x0f; + + for(i = IOP331_IRQ_OFS; i < NR_IOP331_IRQS; i++) + { + set_irq_chip(i, (i < 32) ? &iop331_irqchip1 : &iop331_irqchip2); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } +} + diff --git a/arch/arm/mach-iop3xx/iop331-pci.c b/arch/arm/mach-iop3xx/iop331-pci.c new file mode 100644 index 0000000..44dd213 --- /dev/null +++ b/arch/arm/mach-iop3xx/iop331-pci.c @@ -0,0 +1,222 @@ +/* + * arch/arm/mach-iop3xx/iop331-pci.c + * + * PCI support for the Intel IOP331 chipset + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2003, 2004 Intel Corp. + * + * 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/pci.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/ioport.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach/pci.h> + +#include <asm/arch/iop331.h> + +#undef DEBUG +#undef DEBUG1 + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +#ifdef DEBUG1 +#define DBG1(x...) printk(x) +#else +#define DBG1(x...) do { } while (0) +#endif + +/* + * This routine builds either a type0 or type1 configuration command. If the + * bus is on the 80331 then a type0 made, else a type1 is created. + */ +static u32 iop331_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + if (sys->busnr == bus->number) + addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); + else + addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; + + addr |= PCI_FUNC(devfn) << 8 | (where & ~3); + + return addr; +} + +/* + * This routine checks the status of the last configuration cycle. If an error + * was detected it returns a 1, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop331_pci_status(void) +{ + unsigned int status; + int ret = 0; + + /* + * Check the status registers. + */ + status = *IOP331_ATUSR; + if (status & 0xf900) + { + DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); + *IOP331_ATUSR = status & 0xf900; + ret = 1; + } + status = *IOP331_ATUISR; + if (status & 0x679f) + { + DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); + *IOP331_ATUISR = status & 0x679f; + ret = 1; + } + return ret; +} + +/* + * Simply write the address register and read the configuration + * data. Note that the 4 nop's ensure that we are able to handle + * a delayed abort (in theory.) + */ +static inline u32 iop331_read(unsigned long addr) +{ + u32 val; + + __asm__ __volatile__( + "str %1, [%2]\n\t" + "ldr %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : "=r" (val) + : "r" (addr), "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); + + return val; +} + +/* + * The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop331_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = iop331_cfg_address(bus, devfn, where); + u32 val = iop331_read(addr) >> ((where & 3) * 8); + + if( iop331_pci_status() ) + val = 0xffffffff; + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop331_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop331_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop331_read(addr); + if (!iop331_pci_status() == 0) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + *IOP331_OCCDR = val | value << where; + } else { + asm volatile( + "str %1, [%2]\n\t" + "str %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : + : "r" (value), "r" (addr), + "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop331_ops = { + .read = iop331_read_config, + .write = iop331_write_config, +}; + +/* + * When a PCI device does not exist during config cycles, the XScale gets a + * bus error instead of returning 0xffffffff. This handler simply returns. + */ +int +iop331_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", + addr, fsr, regs->ARM_pc, regs->ARM_lr); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +/* + * Scan an IOP331 PCI bus. sys->bus defines which bus we scan. + */ +struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &iop331_ops, sys); +} + +void iop331_init(void) +{ + DBG1("PCI: Intel 80331 PCI init code.\n"); + DBG1("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD); + DBG1("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n", + *IOP331_OMWTVR0, + *IOP331_OIOWTVR); + DBG1("\tATU: IOP331_OMWTVR1=0x%04x\n", *IOP331_OMWTVR1); + DBG1("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR); + DBG1("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0); + DBG1("\tATU: IOP31_IABAR1=0x%08x IOP331_IALR1=0x%08x\n", *IOP331_IABAR1, *IOP331_IALR1); + DBG1("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR); + DBG1("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2); + DBG1("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3); + + hook_fault_code(16+6, iop331_pci_abort, SIGBUS, "imprecise external abort"); +} + diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c new file mode 100644 index 0000000..622e7914 --- /dev/null +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -0,0 +1,177 @@ +/* + * linux/arch/arm/mach-iop3xx/iop331-setup.c + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2004 Intel Corporation. + * + * 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/mm.h> +#include <linux/init.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/major.h> +#include <linux/fs.h> +#include <linux/device.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_core.h> + +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/mach/map.h> +#include <asm/setup.h> +#include <asm/system.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#define IOP331_UART_XTAL 33334000 + +/* + * Standard IO mapping for all IOP331 based systems + */ +static struct map_desc iop331_std_desc[] __initdata = { + /* virtual physical length type */ + + /* mem mapped registers */ + { IOP331_VIRT_MEM_BASE, IOP331_PHYS_MEM_BASE, 0x00002000, MT_DEVICE }, + + /* PCI IO space */ + { IOP331_PCI_LOWER_IO_VA, IOP331_PCI_LOWER_IO_PA, IOP331_PCI_IO_WINDOW_SIZE, MT_DEVICE } +}; + +static struct uart_port iop331_serial_ports[] = { + { + .membase = (char*)(IOP331_UART0_VIRT), + .mapbase = (IOP331_UART0_PHYS), + .irq = IRQ_IOP331_UART0, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IOP331_UART_XTAL, + .line = 0, + .type = PORT_XSCALE, + .fifosize = 32 + } , { + .membase = (char*)(IOP331_UART1_VIRT), + .mapbase = (IOP331_UART1_PHYS), + .irq = IRQ_IOP331_UART1, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IOP331_UART_XTAL, + .line = 1, + .type = PORT_XSCALE, + .fifosize = 32 + } +}; + +static struct resource iop33x_i2c_0_resources[] = { + [0] = { + .start = 0xfffff680, + .end = 0xfffff698, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_I2C_0, + .end = IRQ_IOP331_I2C_0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop33x_i2c_1_resources[] = { + [0] = { + .start = 0xfffff6a0, + .end = 0xfffff6b8, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_I2C_1, + .end = IRQ_IOP331_I2C_1, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device iop33x_i2c_0_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop33x_i2c_0_resources +}; + +static struct platform_device iop33x_i2c_1_controller = { + .name = "IOP3xx-I2C", + .id = 1, + .num_resources = 2, + .resource = iop33x_i2c_1_resources +}; + +static struct platform_device *iop33x_devices[] __initdata = { + &iop33x_i2c_0_controller, + &iop33x_i2c_1_controller +}; + +void __init iop33x_init(void) +{ + if(iop_is_331()) + { + platform_add_devices(iop33x_devices, + ARRAY_SIZE(iop33x_devices)); + } +} + +void __init iop331_map_io(void) +{ + iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc)); + early_serial_setup(&iop331_serial_ports[0]); + early_serial_setup(&iop331_serial_ports[1]); +} + +#ifdef CONFIG_ARCH_IOP331 +extern void iop331_init_irq(void); +extern struct sys_timer iop331_timer; +#endif + +#ifdef CONFIG_ARCH_IQ80331 +extern void iq80331_map_io(void); +#endif + +#ifdef CONFIG_MACH_IQ80332 +extern void iq80332_map_io(void); +#endif + +#if defined(CONFIG_ARCH_IQ80331) +MACHINE_START(IQ80331, "Intel IQ80331") + MAINTAINER("Intel Corp.") + BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical + //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS) + MAPIO(iq80331_map_io) + INITIRQ(iop331_init_irq) + .timer = &iop331_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(iop33x_init) +MACHINE_END + +#elif defined(CONFIG_MACH_IQ80332) +MACHINE_START(IQ80332, "Intel IQ80332") + MAINTAINER("Intel Corp.") + BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical + //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS) + MAPIO(iq80332_map_io) + INITIRQ(iop331_init_irq) + .timer = &iop331_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(iop33x_init) +MACHINE_END + +#else +#error No machine descriptor defined for this IOP3XX implementation +#endif + + diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c new file mode 100644 index 0000000..e016967 --- /dev/null +++ b/arch/arm/mach-iop3xx/iop331-time.c @@ -0,0 +1,107 @@ +/* + * arch/arm/mach-iop3xx/iop331-time.c + * + * Timer code for IOP331 based systems + * + * Author: Dave Jiang <dave.jiang@intel.com> + * + * Copyright 2003 Intel Corp. + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/time.h> +#include <linux/init.h> +#include <linux/timex.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/mach-types.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> + +static inline unsigned long get_elapsed(void) +{ + return LATCH - *IOP331_TU_TCR0; +} + +static unsigned long iop331_gettimeoffset(void) +{ + unsigned long elapsed, usec; + u32 tisr1, tisr2; + + /* + * If an interrupt was pending before we read the timer, + * we've already wrapped. Factor this into the time. + * If an interrupt was pending after we read the timer, + * it may have wrapped between checking the interrupt + * status and reading the timer. Re-read the timer to + * be sure its value is after the wrap. + */ + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); + elapsed = get_elapsed(); + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); + + if(tisr1 & 1) + elapsed += LATCH; + else if (tisr2 & 1) + elapsed = LATCH + get_elapsed(); + + /* + * Now convert them to usec. + */ + usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH; + + return usec; +} + +static irqreturn_t +iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 tisr; + + write_seqlock(&xtime_lock); + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); + tisr |= 1; + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +static struct irqaction iop331_timer_irq = { + .name = "IOP331 Timer Tick", + .handler = iop331_timer_interrupt, + .flags = SA_INTERRUPT +}; + +static void __init iop331_timer_init(void) +{ + u32 timer_ctl; + + setup_irq(IRQ_IOP331_TIMER0, &iop331_timer_irq); + + timer_ctl = IOP331_TMR_EN | IOP331_TMR_PRIVILEGED | IOP331_TMR_RELOAD | + IOP331_TMR_RATIO_1_1; + + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); + + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); + +} + +struct sys_timer iop331_timer = { + .init = iop331_timer_init, + .offset = iop331_gettimeoffset, +}; diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c new file mode 100644 index 0000000..b01042f --- /dev/null +++ b/arch/arm/mach-iop3xx/iq31244-mm.c @@ -0,0 +1,44 @@ +/* + * linux/arch/arm/mach-iop3xx/mm.c + * + * Low level memory initialization for iq80321 platform + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * + * 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. + * + */ + +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> + +#include <asm/mach/map.h> +#include <asm/mach-types.h> + + +/* + * IQ80321 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ +static struct map_desc iq31244_io_desc[] __initdata = { + /* virtual physical length type */ + + /* on-board devices */ + { IQ31244_UART, IQ31244_UART, 0x00100000, MT_DEVICE } +}; + +void __init iq31244_map_io(void) +{ + iop321_map_io(); + + iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc)); +} diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c new file mode 100644 index 0000000..f997daa --- /dev/null +++ b/arch/arm/mach-iop3xx/iq31244-pci.c @@ -0,0 +1,129 @@ +/* + * arch/arm/mach-iop3xx/iq80321-pci.c + * + * PCI support for the Intel IQ80321 reference board + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * 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/pci.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ31244_INTA +#define INTB IRQ_IQ31244_INTB +#define INTC IRQ_IQ31244_INTC +#define INTD IRQ_IQ31244_INTD + +#define INTE IRQ_IQ31244_I82546 + +static inline int __init +iq31244_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ +#ifdef CONFIG_ARCH_EP80219 + {INTB, INTB, INTB, INTB}, /* CFlash */ + {INTE, INTE, INTE, INTE}, /* 82551 Pro 100 */ + {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ + {INTC, INTC, INTC, INTC}, /* SATA */ +#else + {INTB, INTB, INTB, INTB}, /* CFlash */ + {INTC, INTC, INTC, INTC}, /* SATA */ + {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ + {INTE, INTE, INTE, INTE}, /* 82546 GigE */ +#endif // CONFIG_ARCH_EP80219 + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(0, 7); +} + +static int iq31244_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + memset(res, 0, sizeof(struct resource) * 2); + + res[0].start = IOP321_PCI_LOWER_IO_VA; + res[0].end = IOP321_PCI_UPPER_IO_VA; + res[0].name = "IQ31244 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP321_PCI_LOWER_MEM_PA; + res[1].end = IOP321_PCI_UPPER_MEM_PA; + res[1].name = "IQ31244 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP321_PCI_MEM_OFFSET; + sys->io_offset = IOP321_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq31244_preinit(void) +{ + iop321_init(); +} + +static struct hw_pci iq31244_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq31244_setup, + .scan = iop321_scan_bus, + .preinit = iq31244_preinit, + .map_irq = iq31244_map_irq +}; + +static int __init iq31244_pci_init(void) +{ + if (machine_is_iq31244()) + pci_common_init(&iq31244_pci); + return 0; +} + +subsys_initcall(iq31244_pci_init); + + + + diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c new file mode 100644 index 0000000..1580c7e --- /dev/null +++ b/arch/arm/mach-iop3xx/iq80321-mm.c @@ -0,0 +1,44 @@ +/* + * linux/arch/arm/mach-iop3xx/mm.c + * + * Low level memory initialization for iq80321 platform + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * + * 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. + * + */ + +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> + +#include <asm/mach/map.h> +#include <asm/mach-types.h> + + +/* + * IQ80321 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ +static struct map_desc iq80321_io_desc[] __initdata = { + /* virtual physical length type */ + + /* on-board devices */ + { IQ80321_UART, IQ80321_UART, 0x00100000, MT_DEVICE } +}; + +void __init iq80321_map_io(void) +{ + iop321_map_io(); + + iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc)); +} diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c new file mode 100644 index 0000000..79fea3d --- /dev/null +++ b/arch/arm/mach-iop3xx/iq80321-pci.c @@ -0,0 +1,123 @@ +/* + * arch/arm/mach-iop3xx/iq80321-pci.c + * + * PCI support for the Intel IQ80321 reference board + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * 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/pci.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80321_INTA +#define INTB IRQ_IQ80321_INTB +#define INTC IRQ_IQ80321_INTC +#define INTD IRQ_IQ80321_INTD + +#define INTE IRQ_IQ80321_I82544 + +static inline int __init +iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {INTE, INTE, INTE, INTE}, /* Gig-E */ + {-1, -1, -1, -1}, /* Unused */ + {INTC, INTD, INTA, INTB}, /* PCI-X Slot */ + {-1, -1, -1, -1}, + }; + + BUG_ON(pin < 1 || pin > 4); + +// return PCI_IRQ_TABLE_LOOKUP(4, 7); + return pci_irq_table[idsel%4][pin-1]; +} + +static int iq80321_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + memset(res, 0, sizeof(struct resource) * 2); + + res[0].start = IOP321_PCI_LOWER_IO_VA; + res[0].end = IOP321_PCI_UPPER_IO_VA; + res[0].name = "IQ80321 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP321_PCI_LOWER_MEM_PA; + res[1].end = IOP321_PCI_UPPER_MEM_PA; + res[1].name = "IQ80321 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP321_PCI_MEM_OFFSET; + sys->io_offset = IOP321_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80321_preinit(void) +{ + iop321_init(); +} + +static struct hw_pci iq80321_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80321_setup, + .scan = iop321_scan_bus, + .preinit = iq80321_preinit, + .map_irq = iq80321_map_irq +}; + +static int __init iq80321_pci_init(void) +{ + if (machine_is_iq80321()) + pci_common_init(&iq80321_pci); + return 0; +} + +subsys_initcall(iq80321_pci_init); + + + + diff --git a/arch/arm/mach-iop3xx/iq80331-mm.c b/arch/arm/mach-iop3xx/iq80331-mm.c new file mode 100644 index 0000000..ee8c333 --- /dev/null +++ b/arch/arm/mach-iop3xx/iq80331-mm.c @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/mach-iop3xx/mm.c + * + * Low level memory initialization for iq80331 platform + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2003 Intel Corp. + * + * 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. + * + */ + +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> + +#include <asm/mach/map.h> +#include <asm/mach-types.h> + + +/* + * IQ80331 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ + +void __init iq80331_map_io(void) +{ + iop331_map_io(); +} diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c new file mode 100644 index 0000000..f37a0e2 --- /dev/null +++ b/arch/arm/mach-iop3xx/iq80331-pci.c @@ -0,0 +1,119 @@ +/* + * arch/arm/mach-iop3xx/iq80331-pci.c + * + * PCI support for the Intel IQ80331 reference board + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2003, 2004 Intel Corp. + * + * 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/pci.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80331_INTA +#define INTB IRQ_IQ80331_INTB +#define INTC IRQ_IQ80331_INTC +#define INTD IRQ_IQ80331_INTD + +//#define INTE IRQ_IQ80331_I82544 + +static inline int __init +iq80331_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {INTB, INTC, INTD, INTA}, /* PCI-X Slot */ + {INTC, INTC, INTC, INTC}, /* GigE */ + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(1, 7); +} + +static int iq80331_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + memset(res, 0, sizeof(struct resource) * 2); + + res[0].start = IOP331_PCI_LOWER_IO_VA; + res[0].end = IOP331_PCI_UPPER_IO_VA; + res[0].name = "IQ80331 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP331_PCI_LOWER_MEM_PA; + res[1].end = IOP331_PCI_UPPER_MEM_PA; + res[1].name = "IQ80331 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP331_PCI_MEM_OFFSET; + sys->io_offset = IOP331_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80331_preinit(void) +{ + iop331_init(); +} + +static struct hw_pci iq80331_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80331_setup, + .scan = iop331_scan_bus, + .preinit = iq80331_preinit, + .map_irq = iq80331_map_irq +}; + +static int __init iq80331_pci_init(void) +{ + if (machine_is_iq80331()) + pci_common_init(&iq80331_pci); + return 0; +} + +subsys_initcall(iq80331_pci_init); + + + + diff --git a/arch/arm/mach-iop3xx/iq80332-mm.c b/arch/arm/mach-iop3xx/iq80332-mm.c new file mode 100644 index 0000000..084afcd --- /dev/null +++ b/arch/arm/mach-iop3xx/iq80332-mm.c @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/mach-iop3xx/mm.c + * + * Low level memory initialization for iq80332 platform + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2004 Intel Corp. + * + * 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. + * + */ + +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> + +#include <asm/mach/map.h> +#include <asm/mach-types.h> + + +/* + * IQ80332 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ + +void __init iq80332_map_io(void) +{ + iop331_map_io(); +} diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c new file mode 100644 index 0000000..b9807aa --- /dev/null +++ b/arch/arm/mach-iop3xx/iq80332-pci.c @@ -0,0 +1,125 @@ +/* + * arch/arm/mach-iop3xx/iq80332-pci.c + * + * PCI support for the Intel IQ80332 reference board + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2004 Intel Corp. + * + * 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/pci.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80332_INTA +#define INTB IRQ_IQ80332_INTB +#define INTC IRQ_IQ80332_INTC +#define INTD IRQ_IQ80332_INTD + +//#define INTE IRQ_IQ80332_I82544 + +static inline int __init +iq80332_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][8] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + {INTA, INTB, INTC, INTD}, /* PCI-X Slot */ + {-1, -1, -1, -1}, + {INTC, INTC, INTC, INTC}, /* GigE */ + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(1, 7); +} + +static int iq80332_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + memset(res, 0, sizeof(struct resource) * 2); + + res[0].start = IOP331_PCI_LOWER_IO_VA; + res[0].end = IOP331_PCI_UPPER_IO_VA; + res[0].name = "IQ80332 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP331_PCI_LOWER_MEM_PA; + res[1].end = IOP331_PCI_UPPER_MEM_PA; + res[1].name = "IQ80332 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP331_PCI_MEM_OFFSET; + sys->io_offset = IOP331_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80332_preinit(void) +{ + iop331_init(); +} + +static struct hw_pci iq80332_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80332_setup, + .scan = iop331_scan_bus, + .preinit = iq80332_preinit, + .map_irq = iq80332_map_irq +}; + +static int __init iq80332_pci_init(void) +{ + if (machine_is_iq80332()) + pci_common_init(&iq80332_pci); + return 0; +} + +subsys_initcall(iq80332_pci_init); + + + + diff --git a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig new file mode 100644 index 0000000..9361e05 --- /dev/null +++ b/arch/arm/mach-ixp2000/Kconfig @@ -0,0 +1,59 @@ + +if ARCH_IXP2000 + +config ARCH_SUPPORTS_BIG_ENDIAN + bool + default y + +menu "Intel IXP2400/2800 Implementation Options" + +comment "IXP2400/2800 Platforms" + +config ARCH_ENP2611 + bool "Support Radisys ENP-2611" + help + Say 'Y' here if you want your kernel to support the Radisys + ENP2611 PCI network processing card. For more information on + this card, see <file:Documentation/arm/ENP2611>. + +config ARCH_IXDP2400 + bool "Support Intel IXDP2400" + help + Say 'Y' here if you want your kernel to support the Intel + IXDP2400 reference platform. For more information on + this platform, see <file:Documentation/arm/IXP2000>. + +config ARCH_IXDP2800 + bool "Support Intel IXDP2800" + help + Say 'Y' here if you want your kernel to support the Intel + IXDP2800 reference platform. For more information on + this platform, see <file:Documentation/arm/IXP2000>. + +config ARCH_IXDP2X00 + bool + depends on ARCH_IXDP2400 || ARCH_IXDP2800 + default y + +config ARCH_IXDP2401 + bool "Support Intel IXDP2401" + help + Say 'Y' here if you want your kernel to support the Intel + IXDP2401 reference platform. For more information on + this platform, see <file:Documentation/arm/IXP2000>. + +config ARCH_IXDP2801 + bool "Support Intel IXDP2801" + help + Say 'Y' here if you want your kernel to support the Intel + IXDP2801 reference platform. For more information on + this platform, see <file:Documentation/arm/IXP2000>. + +config ARCH_IXDP2X01 + bool + depends on ARCH_IXDP2401 || ARCH_IXDP2801 + default y + +endmenu + +endif diff --git a/arch/arm/mach-ixp2000/Makefile b/arch/arm/mach-ixp2000/Makefile new file mode 100644 index 0000000..1e6139d --- /dev/null +++ b/arch/arm/mach-ixp2000/Makefile @@ -0,0 +1,14 @@ +# +# Makefile for the linux kernel. +# +obj-y := core.o pci.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_ENP2611) += enp2611.o +obj-$(CONFIG_ARCH_IXDP2400) += ixdp2400.o +obj-$(CONFIG_ARCH_IXDP2800) += ixdp2800.o +obj-$(CONFIG_ARCH_IXDP2X00) += ixdp2x00.o +obj-$(CONFIG_ARCH_IXDP2X01) += ixdp2x01.o + diff --git a/arch/arm/mach-ixp2000/Makefile.boot b/arch/arm/mach-ixp2000/Makefile.boot new file mode 100644 index 0000000..d84c580 --- /dev/null +++ b/arch/arm/mach-ixp2000/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 + diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c new file mode 100644 index 0000000..4f3c3d5c --- /dev/null +++ b/arch/arm/mach-ixp2000/core.c @@ -0,0 +1,390 @@ +/* + * arch/arm/mach-ixp2000/common.c + * + * Common routines used by all IXP2400/2800 based platforms. + * + * Author: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright 2004 (C) MontaVista Software, Inc. + * + * Based on work Copyright (C) 2002-2003 Intel Corporation + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/bitops.h> +#include <linux/serial_core.h> +#include <linux/mm.h> + +#include <asm/types.h> +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/tlbflush.h> +#include <asm/pgtable.h> + +#include <asm/mach/map.h> +#include <asm/mach/time.h> +#include <asm/mach/irq.h> + +static DEFINE_SPINLOCK(ixp2000_slowport_lock); +static unsigned long ixp2000_slowport_irq_flags; + +/************************************************************************* + * Slowport access routines + *************************************************************************/ +void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg) +{ + + spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags); + + old_cfg->CCR = *IXP2000_SLOWPORT_CCR; + old_cfg->WTC = *IXP2000_SLOWPORT_WTC2; + old_cfg->RTC = *IXP2000_SLOWPORT_RTC2; + old_cfg->PCR = *IXP2000_SLOWPORT_PCR; + old_cfg->ADC = *IXP2000_SLOWPORT_ADC; + + ixp2000_reg_write(IXP2000_SLOWPORT_CCR, new_cfg->CCR); + ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC); + ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC); + ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR); + ixp2000_reg_write(IXP2000_SLOWPORT_ADC, new_cfg->ADC); +} + +void ixp2000_release_slowport(struct slowport_cfg *old_cfg) +{ + ixp2000_reg_write(IXP2000_SLOWPORT_CCR, old_cfg->CCR); + ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC); + ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC); + ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR); + ixp2000_reg_write(IXP2000_SLOWPORT_ADC, old_cfg->ADC); + + spin_unlock_irqrestore(&ixp2000_slowport_lock, + ixp2000_slowport_irq_flags); +} + +/************************************************************************* + * Chip specific mappings shared by all IXP2000 systems + *************************************************************************/ +static struct map_desc ixp2000_io_desc[] __initdata = { + { + .virtual = IXP2000_CAP_VIRT_BASE, + .physical = IXP2000_CAP_PHYS_BASE, + .length = IXP2000_CAP_SIZE, + .type = MT_DEVICE + }, { + .virtual = IXP2000_INTCTL_VIRT_BASE, + .physical = IXP2000_INTCTL_PHYS_BASE, + .length = IXP2000_INTCTL_SIZE, + .type = MT_DEVICE + }, { + .virtual = IXP2000_PCI_CREG_VIRT_BASE, + .physical = IXP2000_PCI_CREG_PHYS_BASE, + .length = IXP2000_PCI_CREG_SIZE, + .type = MT_DEVICE + }, { + .virtual = IXP2000_PCI_CSR_VIRT_BASE, + .physical = IXP2000_PCI_CSR_PHYS_BASE, + .length = IXP2000_PCI_CSR_SIZE, + .type = MT_DEVICE + }, { + .virtual = IXP2000_PCI_IO_VIRT_BASE, + .physical = IXP2000_PCI_IO_PHYS_BASE, + .length = IXP2000_PCI_IO_SIZE, + .type = MT_DEVICE + }, { + .virtual = IXP2000_PCI_CFG0_VIRT_BASE, + .physical = IXP2000_PCI_CFG0_PHYS_BASE, + .length = IXP2000_PCI_CFG0_SIZE, + .type = MT_DEVICE + }, { + .virtual = IXP2000_PCI_CFG1_VIRT_BASE, + .physical = IXP2000_PCI_CFG1_PHYS_BASE, + .length = IXP2000_PCI_CFG1_SIZE, + .type = MT_DEVICE + } +}; + +static struct uart_port ixp2000_serial_port = { + .membase = (char *)(IXP2000_UART_VIRT_BASE + 3), + .mapbase = IXP2000_UART_PHYS_BASE + 3, + .irq = IRQ_IXP2000_UART, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = 50000000, + .line = 0, + .type = PORT_XSCALE, + .fifosize = 16 +}; + +void __init ixp2000_map_io(void) +{ + extern unsigned int processor_id; + + /* + * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE for + * tweaking the PMDs so XCB=101. On IXP2800s we use the normal + * PMD flags. + */ + if ((processor_id & 0xfffffff0) == 0x69054190) { + int i; + + printk(KERN_INFO "Enabling IXP2400 erratum #66 workaround\n"); + + for(i=0;i<ARRAY_SIZE(ixp2000_io_desc);i++) + ixp2000_io_desc[i].type = MT_IXP2000_DEVICE; + } + + iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); + early_serial_setup(&ixp2000_serial_port); + + /* Set slowport to 8-bit mode. */ + ixp2000_reg_write(IXP2000_SLOWPORT_FRM, 1); +} + +/************************************************************************* + * Timer-tick functions for IXP2000 + *************************************************************************/ +static unsigned ticks_per_jiffy; +static unsigned ticks_per_usec; +static unsigned next_jiffy_time; + +unsigned long ixp2000_gettimeoffset (void) +{ + unsigned long offset; + + offset = next_jiffy_time - *IXP2000_T4_CSR; + + return offset / ticks_per_usec; +} + +static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + /* clear timer 1 */ + ixp2000_reg_write(IXP2000_T1_CLR, 1); + + while ((next_jiffy_time - *IXP2000_T4_CSR) > ticks_per_jiffy) { + timer_tick(regs); + next_jiffy_time -= ticks_per_jiffy; + } + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction ixp2000_timer_irq = { + .name = "IXP2000 Timer Tick", + .flags = SA_INTERRUPT, + .handler = ixp2000_timer_interrupt +}; + +void __init ixp2000_init_time(unsigned long tick_rate) +{ + ixp2000_reg_write(IXP2000_T1_CLR, 0); + ixp2000_reg_write(IXP2000_T4_CLR, 0); + + ticks_per_jiffy = (tick_rate + HZ/2) / HZ; + ticks_per_usec = tick_rate / 1000000; + + ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1); + ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7)); + + /* + * We use T4 as a monotonic counter to track missed jiffies + */ + ixp2000_reg_write(IXP2000_T4_CLD, -1); + ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7)); + next_jiffy_time = 0xffffffff; + + /* register for interrupt */ + setup_irq(IRQ_IXP2000_TIMER1, &ixp2000_timer_irq); +} + +/************************************************************************* + * GPIO helpers + *************************************************************************/ +static unsigned long GPIO_IRQ_rising_edge; +static unsigned long GPIO_IRQ_falling_edge; +static unsigned long GPIO_IRQ_level_low; +static unsigned long GPIO_IRQ_level_high; + +void gpio_line_config(int line, int style) +{ + unsigned long flags; + + local_irq_save(flags); + + if(style == GPIO_OUT) { + /* if it's an output, it ain't an interrupt anymore */ + ixp2000_reg_write(IXP2000_GPIO_PDSR, (1 << line)); + GPIO_IRQ_falling_edge &= ~(1 << line); + GPIO_IRQ_rising_edge &= ~(1 << line); + GPIO_IRQ_level_low &= ~(1 << line); + GPIO_IRQ_level_high &= ~(1 << line); + ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); + ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge); + ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high); + ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low); + irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0; + } else if(style == GPIO_IN) { + ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line)); + } + + local_irq_restore(flags); +} + + +/************************************************************************* + * IRQ handling IXP2000 + *************************************************************************/ +static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + int i; + unsigned long status = *IXP2000_GPIO_INST; + + for (i = 0; i <= 7; i++) { + if (status & (1<<i)) { + desc = irq_desc + i + IRQ_IXP2000_GPIO0; + desc->handle(i + IRQ_IXP2000_GPIO0, desc, regs); + } + } +} + +static void ixp2000_GPIO_irq_mask_ack(unsigned int irq) +{ + ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); + ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0))); +} + +static void ixp2000_GPIO_irq_mask(unsigned int irq) +{ + ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); +} + +static void ixp2000_GPIO_irq_unmask(unsigned int irq) +{ + ixp2000_reg_write(IXP2000_GPIO_INSR, (1 << (irq - IRQ_IXP2000_GPIO0))); +} + +static struct irqchip ixp2000_GPIO_irq_chip = { + .ack = ixp2000_GPIO_irq_mask_ack, + .mask = ixp2000_GPIO_irq_mask, + .unmask = ixp2000_GPIO_irq_unmask +}; + +static void ixp2000_pci_irq_mask(unsigned int irq) +{ + unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE; + if (irq == IRQ_IXP2000_PCIA) + ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26))); + else if (irq == IRQ_IXP2000_PCIB) + ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27))); +} + +static void ixp2000_pci_irq_unmask(unsigned int irq) +{ + unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE; + if (irq == IRQ_IXP2000_PCIA) + ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 26))); + else if (irq == IRQ_IXP2000_PCIB) + ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27))); +} + +static struct irqchip ixp2000_pci_irq_chip = { + .ack = ixp2000_pci_irq_mask, + .mask = ixp2000_pci_irq_mask, + .unmask = ixp2000_pci_irq_unmask +}; + +static void ixp2000_irq_mask(unsigned int irq) +{ + ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, (1 << irq)); +} + +static void ixp2000_irq_unmask(unsigned int irq) +{ + ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq)); +} + +static struct irqchip ixp2000_irq_chip = { + .ack = ixp2000_irq_mask, + .mask = ixp2000_irq_mask, + .unmask = ixp2000_irq_unmask +}; + +void __init ixp2000_init_irq(void) +{ + int irq; + + /* + * Mask all sources + */ + ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, 0xffffffff); + ixp2000_reg_write(IXP2000_FIQ_ENABLE_CLR, 0xffffffff); + + /* clear all GPIO edge/level detects */ + ixp2000_reg_write(IXP2000_GPIO_REDR, 0); + ixp2000_reg_write(IXP2000_GPIO_FEDR, 0); + ixp2000_reg_write(IXP2000_GPIO_LSHR, 0); + ixp2000_reg_write(IXP2000_GPIO_LSLR, 0); + ixp2000_reg_write(IXP2000_GPIO_INCR, -1); + + /* clear PCI interrupt sources */ + ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, 0); + + /* + * Certain bits in the IRQ status register of the + * IXP2000 are reserved. Instead of trying to map + * things non 1:1 from bit position to IRQ number, + * we mark the reserved IRQs as invalid. This makes + * our mask/unmask code much simpler. + */ + for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { + if((1 << irq) & IXP2000_VALID_IRQ_MASK) { + set_irq_chip(irq, &ixp2000_irq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } else set_irq_flags(irq, 0); + } + + /* + * GPIO IRQs are invalid until someone sets the interrupt mode + * by calling gpio_line_set(); + */ + for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { + set_irq_chip(irq, &ixp2000_GPIO_irq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, 0); + } + set_irq_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler); + + /* + * Enable PCI irqs. The actual PCI[AB] decoding is done in + * entry-macro.S, so we don't need a chained handler for the + * PCI interrupt source. + */ + ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI)); + for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) { + set_irq_chip(irq, &ixp2000_pci_irq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } +} + diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c new file mode 100644 index 0000000..04b38bc --- /dev/null +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -0,0 +1,220 @@ +/* + * arch/arm/mach-ixp2000/enp2611.c + * + * Radisys ENP-2611 support. + * + * Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The + * original version carries the following notices: + * + * Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com> + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright (C) 2002-2003 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/bitops.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_core.h> +#include <linux/device.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +#include <asm/mach/pci.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> + +/************************************************************************* + * ENP-2611 timer tick configuration + *************************************************************************/ +static void __init enp2611_timer_init(void) +{ + ixp2000_init_time(50 * 1000 * 1000); +} + +static struct sys_timer enp2611_timer = { + .init = enp2611_timer_init, + .offset = ixp2000_gettimeoffset, +}; + + +/************************************************************************* + * ENP-2611 PCI + *************************************************************************/ +static int enp2611_pci_setup(int nr, struct pci_sys_data *sys) +{ + sys->mem_offset = 0xe0000000; + ixp2000_pci_setup(nr, sys); + return 1; +} + +static void __init enp2611_pci_preinit(void) +{ + ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); + ixp2000_pci_preinit(); +} + +static inline int enp2611_pci_valid_device(struct pci_bus *bus, + unsigned int devfn) +{ + /* The 82559 ethernet controller appears at both PCI:1:0:0 and + * PCI:1:2:0, so let's pretend the second one isn't there. + */ + if (bus->number == 0x01 && devfn == 0x10) + return 0; + + return 1; +} + +static int enp2611_pci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *value) +{ + if (enp2611_pci_valid_device(bus, devfn)) + return ixp2000_pci_read_config(bus, devfn, where, size, value); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static int enp2611_pci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 value) +{ + if (enp2611_pci_valid_device(bus, devfn)) + return ixp2000_pci_write_config(bus, devfn, where, size, value); + + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static struct pci_ops enp2611_pci_ops = { + .read = enp2611_pci_read_config, + .write = enp2611_pci_write_config +}; + +static struct pci_bus * __init enp2611_pci_scan_bus(int nr, + struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &enp2611_pci_ops, sys); +} + +static int __init enp2611_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 0) { + /* IXP2400. */ + irq = IRQ_IXP2000_PCIA; + } else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 1) { + /* 21555 non-transparent bridge. */ + irq = IRQ_IXP2000_PCIB; + } else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 4) { + /* PCI2050B transparent bridge. */ + irq = -1; + } else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 0) { + /* 82559 ethernet. */ + irq = IRQ_IXP2000_PCIA; + } else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 1) { + /* SPI-3 option board. */ + irq = IRQ_IXP2000_PCIB; + } else { + printk(KERN_ERR "enp2611_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +struct hw_pci enp2611_pci __initdata = { + .nr_controllers = 1, + .setup = enp2611_pci_setup, + .preinit = enp2611_pci_preinit, + .scan = enp2611_pci_scan_bus, + .map_irq = enp2611_pci_map_irq, +}; + +int __init enp2611_pci_init(void) +{ + if (machine_is_enp2611()) + pci_common_init(&enp2611_pci); + + return 0; +} + +subsys_initcall(enp2611_pci_init); + + +/************************************************************************* + * ENP-2611 Machine Intialization + *************************************************************************/ +static struct flash_platform_data enp2611_flash_platform_data = { + .map_name = "cfi_probe", + .width = 1, +}; + +static struct ixp2000_flash_data enp2611_flash_data = { + .platform_data = &enp2611_flash_platform_data, + .nr_banks = 1 +}; + +static struct resource enp2611_flash_resource = { + .start = 0xc4000000, + .end = 0xc4000000 + 0x00ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device enp2611_flash = { + .name = "IXP2000-Flash", + .id = 0, + .dev = { + .platform_data = &enp2611_flash_data, + }, + .num_resources = 1, + .resource = &enp2611_flash_resource, +}; + +static struct platform_device *enp2611_devices[] __initdata = { + &enp2611_flash +}; + +static void __init enp2611_init_machine(void) +{ + platform_add_devices(enp2611_devices, ARRAY_SIZE(enp2611_devices)); +} + + +MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board") + MAINTAINER("Lennert Buytenhek <buytenh@wantstofly.org>") + BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) + BOOT_PARAMS(0x00000100) + MAPIO(ixp2000_map_io) + INITIRQ(ixp2000_init_irq) + .timer = &enp2611_timer, + INIT_MACHINE(enp2611_init_machine) +MACHINE_END + + diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c new file mode 100644 index 0000000..df3ff26 --- /dev/null +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -0,0 +1,179 @@ +/* + * arch/arm/mach-ixp2000/ixdp2400.c + * + * IXDP2400 platform support + * + * Original Author: Naeem Afzal <naeem.m.afzal@intel.com> + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/device.h> +#include <linux/bitops.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/slab.h> +#include <linux/delay.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +#include <asm/mach/pci.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include <asm/mach/flash.h> +#include <asm/mach/arch.h> + +/************************************************************************* + * IXDP2400 timer tick + *************************************************************************/ +static void __init ixdp2400_timer_init(void) +{ + int numerator, denominator; + int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8}; + + numerator = (*(IXDP2400_CPLD_SYS_CLK_M) & 0xFF) *2; + denominator = denom_array[(*(IXDP2400_CPLD_SYS_CLK_N) & 0x7)]; + + ixp2000_init_time(((3125000 * numerator) / (denominator)) / 2); +} + +static struct sys_timer ixdp2400_timer = { + .init = ixdp2400_timer_init, + .offset = ixp2000_gettimeoffset, +}; + +/************************************************************************* + * IXDP2400 PCI + *************************************************************************/ +void __init ixdp2400_pci_preinit(void) +{ + ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); + ixp2000_pci_preinit(); +} + +int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys) +{ + sys->mem_offset = 0xe0000000; + + ixp2000_pci_setup(nr, sys); + + return 1; +} + +static int __init ixdp2400_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (ixdp2x00_master_npu()) { + + /* + * Root bus devices. Slave NPU is only one with interrupt. + * Everything else, we just return -1 b/c nothing else + * on the root bus has interrupts. + */ + if(!dev->bus->self) { + if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN ) + return IRQ_IXDP2400_INGRESS_NPU; + + return -1; + } + + /* + * Bridge behind the PMC slot. + * NOTE: Only INTA from the PMC slot is routed. VERY BAD. + */ + if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN && + dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN && + !dev->bus->parent->self->bus->parent) + return IRQ_IXDP2400_PMC; + + /* + * Device behind the first bridge + */ + if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) { + switch(dev->devfn) { + case IXDP2400_MASTER_ENET_DEVFN: + return IRQ_IXDP2400_ENET; + + case IXDP2400_MEDIA_DEVFN: + return IRQ_IXDP2400_MEDIA_PCI; + + case IXDP2400_SWITCH_FABRIC_DEVFN: + return IRQ_IXDP2400_SF_PCI; + + case IXDP2X00_PMC_DEVFN: + return IRQ_IXDP2400_PMC; + } + } + + return -1; + } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ +} + + +static void ixdp2400_pci_postinit(void) +{ + struct pci_dev *dev; + + if (ixdp2x00_master_npu()) { + dev = pci_find_slot(1, IXDP2400_SLAVE_ENET_DEVFN); + pci_remove_bus_device(dev); + } else { + dev = pci_find_slot(1, IXDP2400_MASTER_ENET_DEVFN); + pci_remove_bus_device(dev); + + ixdp2x00_slave_pci_postinit(); + } +} + +static struct hw_pci ixdp2400_pci __initdata = { + .nr_controllers = 1, + .setup = ixdp2400_pci_setup, + .preinit = ixdp2400_pci_preinit, + .postinit = ixdp2400_pci_postinit, + .scan = ixp2000_pci_scan_bus, + .map_irq = ixdp2400_pci_map_irq, +}; + +int __init ixdp2400_pci_init(void) +{ + if (machine_is_ixdp2400()) + pci_common_init(&ixdp2400_pci); + + return 0; +} + +subsys_initcall(ixdp2400_pci_init); + +void ixdp2400_init_irq(void) +{ + ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS); +} + +MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) + BOOT_PARAMS(0x00000100) + MAPIO(ixdp2x00_map_io) + INITIRQ(ixdp2400_init_irq) + .timer = &ixdp2400_timer, + INIT_MACHINE(ixdp2x00_init_machine) +MACHINE_END + diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c new file mode 100644 index 0000000..c4683aa --- /dev/null +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -0,0 +1,180 @@ +/* + * arch/arm/mach-ixp2000/ixdp2800.c + * + * IXDP2800 platform support + * + * Original Author: Jeffrey Daly <jeffrey.daly@intel.com> + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/device.h> +#include <linux/bitops.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/slab.h> +#include <linux/delay.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +#include <asm/mach/pci.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include <asm/mach/flash.h> +#include <asm/mach/arch.h> + + +void ixdp2400_init_irq(void) +{ + ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2400_NR_IRQS); +} + +/************************************************************************* + * IXDP2800 timer tick + *************************************************************************/ + +static void __init ixdp2800_timer_init(void) +{ + ixp2000_init_time(50000000); +} + +static struct sys_timer ixdp2800_timer = { + .init = ixdp2800_timer_init, + .offset = ixp2000_gettimeoffset, +}; + +/************************************************************************* + * IXDP2800 PCI + *************************************************************************/ +void __init ixdp2800_pci_preinit(void) +{ + printk("ixdp2x00_pci_preinit called\n"); + + *IXP2000_PCI_ADDR_EXT = 0x0000e000; + + *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff; + *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff; + + ixp2000_pci_preinit(); +} + +int ixdp2800_pci_setup(int nr, struct pci_sys_data *sys) +{ + sys->mem_offset = 0x00000000; + + ixp2000_pci_setup(nr, sys); + + return 1; +} + +static int __init ixdp2800_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (ixdp2x00_master_npu()) { + + /* + * Root bus devices. Slave NPU is only one with interrupt. + * Everything else, we just return -1 which is invalid. + */ + if(!dev->bus->self) { + if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN ) + return IRQ_IXDP2800_INGRESS_NPU; + + return -1; + } + + /* + * Bridge behind the PMC slot. + */ + if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN && + dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN && + !dev->bus->parent->self->bus->parent) + return IRQ_IXDP2800_PMC; + + /* + * Device behind the first bridge + */ + if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) { + switch(dev->devfn) { + case IXDP2X00_PMC_DEVFN: + return IRQ_IXDP2800_PMC; + + case IXDP2800_MASTER_ENET_DEVFN: + return IRQ_IXDP2800_EGRESS_ENET; + + case IXDP2800_SWITCH_FABRIC_DEVFN: + return IRQ_IXDP2800_FABRIC; + } + } + + return -1; + } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ +} + +static void ixdp2800_pci_postinit(void) +{ + struct pci_dev *dev; + + if (ixdp2x00_master_npu()) { + dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN); + pci_remove_bus_device(dev); + } else { + dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN); + pci_remove_bus_device(dev); + + ixdp2x00_slave_pci_postinit(); + } +} + +struct hw_pci ixdp2800_pci __initdata = { + .nr_controllers = 1, + .setup = ixdp2800_pci_setup, + .preinit = ixdp2800_pci_preinit, + .postinit = ixdp2800_pci_postinit, + .scan = ixp2000_pci_scan_bus, + .map_irq = ixdp2800_pci_map_irq, +}; + +int __init ixdp2800_pci_init(void) +{ + if (machine_is_ixdp2800()) + pci_common_init(&ixdp2800_pci); + + return 0; +} + +subsys_initcall(ixdp2800_pci_init); + +void ixdp2800_init_irq(void) +{ + ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2800_NR_IRQS); +} + +MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) + BOOT_PARAMS(0x00000100) + MAPIO(ixdp2x00_map_io) + INITIRQ(ixdp2800_init_irq) + .timer = &ixdp2800_timer, + INIT_MACHINE(ixdp2x00_init_machine) +MACHINE_END + diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c new file mode 100644 index 0000000..21c41fe --- /dev/null +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -0,0 +1,304 @@ +/* + * arch/arm/mach-ixp2000/ixdp2x00.c + * + * Code common to IXDP2400 and IXDP2800 platforms. + * + * Original Author: Naeem Afzal <naeem.m.afzal@intel.com> + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright (C) 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/device.h> +#include <linux/bitops.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/slab.h> +#include <linux/delay.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +#include <asm/mach/pci.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include <asm/mach/flash.h> +#include <asm/mach/arch.h> + +/************************************************************************* + * IXDP2x00 IRQ Initialization + *************************************************************************/ +static volatile unsigned long *board_irq_mask; +static volatile unsigned long *board_irq_stat; +static unsigned long board_irq_count; + +#ifdef CONFIG_ARCH_IXDP2400 +/* + * Slowport configuration for accessing CPLD registers on IXDP2x00 + */ +static struct slowport_cfg slowport_cpld_cfg = { + .CCR = SLOWPORT_CCR_DIV_2, + .WTC = 0x00000070, + .RTC = 0x00000070, + .PCR = SLOWPORT_MODE_FLASH, + .ADC = SLOWPORT_ADDR_WIDTH_24 | SLOWPORT_DATA_WIDTH_8 +}; +#endif + +static void ixdp2x00_irq_mask(unsigned int irq) +{ + unsigned long dummy; + static struct slowport_cfg old_cfg; + + /* + * This is ugly in common code but really don't know + * of a better way to handle it. :( + */ +#ifdef CONFIG_ARCH_IXDP2400 + if (machine_is_ixdp2400()) + ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg); +#endif + + dummy = *board_irq_mask; + dummy |= IXP2000_BOARD_IRQ_MASK(irq); + ixp2000_reg_write(board_irq_mask, dummy); + +#ifdef CONFIG_ARCH_IXDP2400 + if (machine_is_ixdp2400()) + ixp2000_release_slowport(&old_cfg); +#endif +} + +static void ixdp2x00_irq_unmask(unsigned int irq) +{ + unsigned long dummy; + static struct slowport_cfg old_cfg; + +#ifdef CONFIG_ARCH_IXDP2400 + if (machine_is_ixdp2400()) + ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg); +#endif + + dummy = *board_irq_mask; + dummy &= ~IXP2000_BOARD_IRQ_MASK(irq); + ixp2000_reg_write(board_irq_mask, dummy); + + if (machine_is_ixdp2400()) + ixp2000_release_slowport(&old_cfg); +} + +static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + volatile u32 ex_interrupt = 0; + static struct slowport_cfg old_cfg; + int i; + + desc->chip->mask(irq); + +#ifdef CONFIG_ARCH_IXDP2400 + if (machine_is_ixdp2400()) + ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg); +#endif + ex_interrupt = *board_irq_stat & 0xff; + if (machine_is_ixdp2400()) + ixp2000_release_slowport(&old_cfg); + + if(!ex_interrupt) { + printk(KERN_ERR "Spurious IXDP2x00 CPLD interrupt!\n"); + return; + } + + for(i = 0; i < board_irq_count; i++) { + if(ex_interrupt & (1 << i)) { + struct irqdesc *cpld_desc; + int cpld_irq = IXP2000_BOARD_IRQ(0) + i; + cpld_desc = irq_desc + cpld_irq; + cpld_desc->handle(cpld_irq, cpld_desc, regs); + } + } + + desc->chip->unmask(irq); +} + +static struct irqchip ixdp2x00_cpld_irq_chip = { + .ack = ixdp2x00_irq_mask, + .mask = ixdp2x00_irq_mask, + .unmask = ixdp2x00_irq_unmask +}; + +void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs) +{ + unsigned int irq; + + ixp2000_init_irq(); + + if (!ixdp2x00_master_npu()) + return; + + board_irq_stat = stat_reg; + board_irq_mask = mask_reg; + board_irq_count = nr_irqs; + + *board_irq_mask = 0xffffffff; + + for(irq = IXP2000_BOARD_IRQ(0); irq < IXP2000_BOARD_IRQ(board_irq_count); irq++) { + set_irq_chip(irq, &ixdp2x00_cpld_irq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } + + /* Hook into PCI interrupt */ + set_irq_chained_handler(IRQ_IXP2000_PCIB, &ixdp2x00_irq_handler); +} + +/************************************************************************* + * IXDP2x00 memory map + *************************************************************************/ +static struct map_desc ixdp2x00_io_desc __initdata = { + .virtual = IXDP2X00_VIRT_CPLD_BASE, + .physical = IXDP2X00_PHYS_CPLD_BASE, + .length = IXDP2X00_CPLD_SIZE, + .type = MT_DEVICE +}; + +void __init ixdp2x00_map_io(void) +{ + ixp2000_map_io(); + + iotable_init(&ixdp2x00_io_desc, 1); +} + +/************************************************************************* + * IXDP2x00-common PCI init + * + * The IXDP2[48]00 has a horrid PCI bus layout. Basically the board + * contains two NPUs (ingress and egress) connected over PCI, both running + * instances of the kernel. So far so good. Peers on the PCI bus running + * Linux is a common design in telecom systems. The problem is that instead + * of all the devices being controlled by a single host, different + * devices are controlles by different NPUs on the same bus, leading to + * multiple hosts on the bus. The exact bus layout looks like: + * + * Bus 0 + * Master NPU <-------------------+-------------------> Slave NPU + * | + * | + * P2P + * | + * + * Bus 1 | + * <--+------+---------+---------+------+--> + * | | | | | + * | | | | | + * ... Dev PMC Media Eth0 Eth1 ... + * + * The master controlls all but Eth1, which is controlled by the + * slave. What this means is that the both the master and the slave + * have to scan the bus, but only one of them can enumerate the bus. + * In addition, after the bus is scanned, each kernel must remove + * the device(s) it does not control from the PCI dev list otherwise + * a driver on each NPU will try to manage it and we will have horrible + * conflicts. Oh..and the slave NPU needs to see the master NPU + * for Intel's drivers to work properly. Closed source drivers... + * + * The way we deal with this is fairly simple but ugly: + * + * 1) Let master scan and enumerate the bus completely. + * 2) Master deletes Eth1 from device list. + * 3) Slave scans bus and then deletes all but Eth1 (Eth0 on slave) + * from device list. + * 4) Find HW designers and LART them. + * + * The boards also do not do normal PCI IRQ routing, or any sort of + * sensical swizzling, so we just need to check where on the bus a + * device sits and figure out to which CPLD pin the interrupt is routed. + * See ixdp2[48]00.c files. + * + *************************************************************************/ +void ixdp2x00_slave_pci_postinit(void) +{ + struct pci_dev *dev; + + /* + * Remove PMC device is there is one + */ + if((dev = pci_find_slot(1, IXDP2X00_PMC_DEVFN))) + pci_remove_bus_device(dev); + + dev = pci_find_slot(0, IXDP2X00_21555_DEVFN); + pci_remove_bus_device(dev); +} + +/************************************************************************** + * IXDP2x00 Machine Setup + *************************************************************************/ +static struct flash_platform_data ixdp2x00_platform_data = { + .map_name = "cfi_probe", + .width = 1, +}; + +static struct ixp2000_flash_data ixdp2x00_flash_data = { + .platform_data = &ixdp2x00_platform_data, + .nr_banks = 1 +}; + +static struct resource ixdp2x00_flash_resource = { + .start = 0xc4000000, + .end = 0xc4000000 + 0x00ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp2x00_flash = { + .name = "IXP2000-Flash", + .id = 0, + .dev = { + .platform_data = &ixdp2x00_flash_data, + }, + .num_resources = 1, + .resource = &ixdp2x00_flash_resource, +}; + +static struct ixp2000_i2c_pins ixdp2x00_i2c_gpio_pins = { + .sda_pin = IXDP2X00_GPIO_SDA, + .scl_pin = IXDP2X00_GPIO_SCL, +}; + +static struct platform_device ixdp2x00_i2c_controller = { + .name = "IXP2000-I2C", + .id = 0, + .dev = { + .platform_data = &ixdp2x00_i2c_gpio_pins, + }, + .num_resources = 0 +}; + +static struct platform_device *ixdp2x00_devices[] __initdata = { + &ixdp2x00_flash, + &ixdp2x00_i2c_controller +}; + +void __init ixdp2x00_init_machine(void) +{ + gpio_line_set(IXDP2X00_GPIO_I2C_ENABLE, 1); + gpio_line_config(IXDP2X00_GPIO_I2C_ENABLE, GPIO_OUT); + + platform_add_devices(ixdp2x00_devices, ARRAY_SIZE(ixdp2x00_devices)); +} + diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c new file mode 100644 index 0000000..e94dace --- /dev/null +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -0,0 +1,400 @@ +/* + * arch/arm/mach-ixp2000/ixdp2x01.c + * + * Code common to Intel IXDP2401 and IXDP2801 platforms + * + * Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com> + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright (C) 2002-2003 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/bitops.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_core.h> +#include <linux/device.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +#include <asm/mach/pci.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> + +/************************************************************************* + * IXDP2x01 IRQ Handling + *************************************************************************/ +static void ixdp2x01_irq_mask(unsigned int irq) +{ + ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, + IXP2000_BOARD_IRQ_MASK(irq)); +} + +static void ixdp2x01_irq_unmask(unsigned int irq) +{ + ixp2000_reg_write(IXDP2X01_INT_MASK_CLR_REG, + IXP2000_BOARD_IRQ_MASK(irq)); +} + +static u32 valid_irq_mask; + +static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + u32 ex_interrupt; + int i; + + desc->chip->mask(irq); + + ex_interrupt = *IXDP2X01_INT_STAT_REG & valid_irq_mask; + + if (!ex_interrupt) { + printk(KERN_ERR "Spurious IXDP2X01 CPLD interrupt!\n"); + return; + } + + for (i = 0; i < IXP2000_BOARD_IRQS; i++) { + if (ex_interrupt & (1 << i)) { + struct irqdesc *cpld_desc; + int cpld_irq = IXP2000_BOARD_IRQ(0) + i; + cpld_desc = irq_desc + cpld_irq; + cpld_desc->handle(cpld_irq, cpld_desc, regs); + } + } + + desc->chip->unmask(irq); +} + +static struct irqchip ixdp2x01_irq_chip = { + .mask = ixdp2x01_irq_mask, + .ack = ixdp2x01_irq_mask, + .unmask = ixdp2x01_irq_unmask +}; + +/* + * We only do anything if we are the master NPU on the board. + * The slave NPU only has the ethernet chip going directly to + * the PCIB interrupt input. + */ +void __init ixdp2x01_init_irq(void) +{ + int irq = 0; + + /* initialize chip specific interrupts */ + ixp2000_init_irq(); + + if (machine_is_ixdp2401()) + valid_irq_mask = IXDP2401_VALID_IRQ_MASK; + else + valid_irq_mask = IXDP2801_VALID_IRQ_MASK; + + /* Mask all interrupts from CPLD, disable simulation */ + ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff); + ixp2000_reg_write(IXDP2X01_INT_SIM_REG, 0); + + for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) { + if (irq & valid_irq_mask) { + set_irq_chip(irq, &ixdp2x01_irq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } else { + set_irq_flags(irq, 0); + } + } + + /* Hook into PCI interrupts */ + set_irq_chained_handler(IRQ_IXP2000_PCIB, &ixdp2x01_irq_handler); +} + + +/************************************************************************* + * IXDP2x01 memory map and serial ports + *************************************************************************/ +static struct map_desc ixdp2x01_io_desc __initdata = { + .virtual = IXDP2X01_VIRT_CPLD_BASE, + .physical = IXDP2X01_PHYS_CPLD_BASE, + .length = IXDP2X01_CPLD_REGION_SIZE, + .type = MT_DEVICE +}; + +static struct uart_port ixdp2x01_serial_ports[2] = { + { + .membase = (char *)(IXDP2X01_UART1_VIRT_BASE), + .mapbase = (unsigned long)IXDP2X01_UART1_PHYS_BASE, + .irq = IRQ_IXDP2X01_UART1, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM32, + .regshift = 2, + .uartclk = IXDP2X01_UART_CLK, + .line = 1, + .type = PORT_16550A, + .fifosize = 16 + }, { + .membase = (char *)(IXDP2X01_UART2_VIRT_BASE), + .mapbase = (unsigned long)IXDP2X01_UART2_PHYS_BASE, + .irq = IRQ_IXDP2X01_UART2, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM32, + .regshift = 2, + .uartclk = IXDP2X01_UART_CLK, + .line = 2, + .type = PORT_16550A, + .fifosize = 16 + }, +}; + +static void __init ixdp2x01_map_io(void) +{ + ixp2000_map_io(); + + iotable_init(&ixdp2x01_io_desc, 1); + + early_serial_setup(&ixdp2x01_serial_ports[0]); + early_serial_setup(&ixdp2x01_serial_ports[1]); +} + + +/************************************************************************* + * IXDP2x01 timer tick configuration + *************************************************************************/ +static unsigned int ixdp2x01_clock; + +static int __init ixdp2x01_clock_setup(char *str) +{ + ixdp2x01_clock = simple_strtoul(str, NULL, 10); + + return 1; +} + +__setup("ixdp2x01_clock=", ixdp2x01_clock_setup); + +static void __init ixdp2x01_timer_init(void) +{ + if (!ixdp2x01_clock) + ixdp2x01_clock = 50000000; + + ixp2000_init_time(ixdp2x01_clock); +} + +static struct sys_timer ixdp2x01_timer = { + .init = ixdp2x01_timer_init, + .offset = ixp2000_gettimeoffset, +}; + +/************************************************************************* + * IXDP2x01 PCI + *************************************************************************/ +void __init ixdp2x01_pci_preinit(void) +{ + ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000); + ixp2000_pci_preinit(); +} + +#define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) + +static int __init ixdp2x01_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + u8 bus = dev->bus->number; + u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin); + struct pci_bus *tmp_bus = dev->bus; + + /* Primary bus, no interrupts here */ + if (bus == 0) { + return -1; + } + + /* Lookup first leaf in bus tree */ + while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL)) { + tmp_bus = tmp_bus->parent; + } + + /* Select between known bridges */ + switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) { + /* Device is located after first MB bridge */ + case 0x0008: + if (tmp_bus == dev->bus) { + /* Device is located directy after first MB bridge */ + switch (devpin) { + case DEVPIN(1, 1): /* Onboard 82546 ch 0 */ + if (machine_is_ixdp2401()) + return IRQ_IXDP2401_INTA_82546; + return -1; + case DEVPIN(1, 2): /* Onboard 82546 ch 1 */ + if (machine_is_ixdp2401()) + return IRQ_IXDP2401_INTB_82546; + return -1; + case DEVPIN(0, 1): /* PMC INTA# */ + return IRQ_IXDP2X01_SPCI_PMC_INTA; + case DEVPIN(0, 2): /* PMC INTB# */ + return IRQ_IXDP2X01_SPCI_PMC_INTB; + case DEVPIN(0, 3): /* PMC INTC# */ + return IRQ_IXDP2X01_SPCI_PMC_INTC; + case DEVPIN(0, 4): /* PMC INTD# */ + return IRQ_IXDP2X01_SPCI_PMC_INTD; + } + } + break; + case 0x0010: + if (tmp_bus == dev->bus) { + /* Device is located directy after second MB bridge */ + /* Secondary bus of second bridge */ + switch (devpin) { + case DEVPIN(0, 1): /* DB#0 */ + return IRQ_IXDP2X01_SPCI_DB_0; + case DEVPIN(1, 1): /* DB#1 */ + return IRQ_IXDP2X01_SPCI_DB_1; + } + } else { + /* Device is located indirectly after second MB bridge */ + /* Not supported now */ + } + break; + } + + return -1; +} + + +static int ixdp2x01_pci_setup(int nr, struct pci_sys_data *sys) +{ + sys->mem_offset = 0xe0000000; + + if (machine_is_ixdp2801()) + sys->mem_offset -= ((*IXP2000_PCI_ADDR_EXT & 0xE000) << 16); + + return ixp2000_pci_setup(nr, sys); +} + +struct hw_pci ixdp2x01_pci __initdata = { + .nr_controllers = 1, + .setup = ixdp2x01_pci_setup, + .preinit = ixdp2x01_pci_preinit, + .scan = ixp2000_pci_scan_bus, + .map_irq = ixdp2x01_pci_map_irq, +}; + +int __init ixdp2x01_pci_init(void) +{ + + pci_common_init(&ixdp2x01_pci); + return 0; +} + +subsys_initcall(ixdp2x01_pci_init); + +/************************************************************************* + * IXDP2x01 Machine Intialization + *************************************************************************/ +static struct flash_platform_data ixdp2x01_flash_platform_data = { + .map_name = "cfi_probe", + .width = 1, +}; + +static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs) +{ + ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG, + ((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN)); + return (ofs & IXDP2X01_FLASH_WINDOW_MASK); +} + +static struct ixp2000_flash_data ixdp2x01_flash_data = { + .platform_data = &ixdp2x01_flash_platform_data, + .bank_setup = ixdp2x01_flash_bank_setup +}; + +static struct resource ixdp2x01_flash_resource = { + .start = 0xc4000000, + .end = 0xc4000000 + 0x01ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp2x01_flash = { + .name = "IXP2000-Flash", + .id = 0, + .dev = { + .platform_data = &ixdp2x01_flash_data, + }, + .num_resources = 1, + .resource = &ixdp2x01_flash_resource, +}; + +static struct ixp2000_i2c_pins ixdp2x01_i2c_gpio_pins = { + .sda_pin = IXDP2X01_GPIO_SDA, + .scl_pin = IXDP2X01_GPIO_SCL, +}; + +static struct platform_device ixdp2x01_i2c_controller = { + .name = "IXP2000-I2C", + .id = 0, + .dev = { + .platform_data = &ixdp2x01_i2c_gpio_pins, + }, + .num_resources = 0 +}; + +static struct platform_device *ixdp2x01_devices[] __initdata = { + &ixdp2x01_flash, + &ixdp2x01_i2c_controller +}; + +static void __init ixdp2x01_init_machine(void) +{ + ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG, + (IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN)); + + ixdp2x01_flash_data.nr_banks = + ((*IXDP2X01_CPLD_FLASH_REG & IXDP2X01_CPLD_FLASH_BANK_MASK) + 1); + + platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices)); +} + + +#ifdef CONFIG_ARCH_IXDP2401 +MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) + BOOT_PARAMS(0x00000100) + MAPIO(ixdp2x01_map_io) + INITIRQ(ixdp2x01_init_irq) + .timer = &ixdp2x01_timer, + INIT_MACHINE(ixdp2x01_init_machine) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_IXDP2801 +MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) + BOOT_PARAMS(0x00000100) + MAPIO(ixdp2x01_map_io) + INITIRQ(ixdp2x01_init_irq) + .timer = &ixdp2x01_timer, + INIT_MACHINE(ixdp2x01_init_machine) +MACHINE_END +#endif + + diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c new file mode 100644 index 0000000..831f8ff --- /dev/null +++ b/arch/arm/mach-ixp2000/pci.c @@ -0,0 +1,235 @@ +/* + * arch/arm/mach-ixp2000/pci.c + * + * PCI routines for IXDP2400/IXDP2800 boards + * + * Original Author: Naeem Afzal <naeem.m.afzal@intel.com> + * Maintained by: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright 2002 Intel Corp. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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. + */ + +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/interrupt.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/slab.h> +#include <linux/delay.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> + +#include <asm/mach/pci.h> + +static int pci_master_aborts = 0; + +static int clear_master_aborts(void); + +static u32 * +ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) +{ + u32 *paddress; + + if (PCI_SLOT(devfn) > 7) + return 0; + + /* Must be dword aligned */ + where &= ~3; + + /* + * For top bus, generate type 0, else type 1 + */ + if (!bus_nr) { + /* only bits[23:16] are used for IDSEL */ + paddress = (u32 *) (IXP2000_PCI_CFG0_VIRT_BASE + | (1 << (PCI_SLOT(devfn) + 16)) + | (PCI_FUNC(devfn) << 8) | where); + } else { + paddress = (u32 *) (IXP2000_PCI_CFG1_VIRT_BASE + | (bus_nr << 16) + | (PCI_SLOT(devfn) << 11) + | (PCI_FUNC(devfn) << 8) | where); + } + + return paddress; +} + +/* + * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes. + * 0 and 3 are not valid indexes... + */ +static u32 bytemask[] = { + /*0*/ 0, + /*1*/ 0xff, + /*2*/ 0xffff, + /*3*/ 0, + /*4*/ 0xffffffff, +}; + + +int ixp2000_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + u32 n; + u32 *addr; + + n = where % 4; + + addr = ixp2000_pci_config_addr(bus->number, devfn, where); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + + pci_master_aborts = 0; + *value = (*addr >> (8*n)) & bytemask[size]; + if (pci_master_aborts) { + pci_master_aborts = 0; + *value = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + return PCIBIOS_SUCCESSFUL; +} + +/* + * We don't do error checks by callling clear_master_aborts() b/c the + * assumption is that the caller did a read first to make sure a device + * exists. + */ +int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + u32 mask; + u32 *addr; + u32 temp; + + mask = ~(bytemask[size] << ((where % 0x4) * 8)); + addr = ixp2000_pci_config_addr(bus->number, devfn, where); + if (!addr) + return PCIBIOS_DEVICE_NOT_FOUND; + temp = (u32) (value) << ((where % 0x4) * 8); + *addr = (*addr & mask) | temp; + + clear_master_aborts(); + + return PCIBIOS_SUCCESSFUL; +} + + +static struct pci_ops ixp2000_pci_ops = { + .read = ixp2000_pci_read_config, + .write = ixp2000_pci_write_config +}; + +struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata) +{ + return pci_scan_bus(sysdata->busnr, &ixp2000_pci_ops, sysdata); +} + + +int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + + volatile u32 temp; + unsigned long flags; + + pci_master_aborts = 1; + + local_irq_save(flags); + temp = *(IXP2000_PCI_CONTROL); + if (temp & ((1 << 8) | (1 << 5))) { + ixp2000_reg_write(IXP2000_PCI_CONTROL, temp); + } + + temp = *(IXP2000_PCI_CMDSTAT); + if (temp & (1 << 29)) { + while (temp & (1 << 29)) { + ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp); + temp = *(IXP2000_PCI_CMDSTAT); + } + } + local_irq_restore(flags); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +int +clear_master_aborts(void) +{ + volatile u32 temp; + unsigned long flags; + + local_irq_save(flags); + temp = *(IXP2000_PCI_CONTROL); + if (temp & ((1 << 8) | (1 << 5))) { + ixp2000_reg_write(IXP2000_PCI_CONTROL, temp); + } + + temp = *(IXP2000_PCI_CMDSTAT); + if (temp & (1 << 29)) { + while (temp & (1 << 29)) { + ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp); + temp = *(IXP2000_PCI_CMDSTAT); + } + } + local_irq_restore(flags); + + return 0; +} + +void __init +ixp2000_pci_preinit(void) +{ + hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, + "PCI config cycle to non-existent device"); +} + + +/* + * IXP2000 systems often have large resource requirements, so we just + * use our own resource space. + */ +static struct resource ixp2000_pci_mem_space = { + .start = 0x00000000, + .end = 0xffffffff, + .flags = IORESOURCE_MEM, + .name = "PCI Mem Space" +}; + +static struct resource ixp2000_pci_io_space = { + .start = 0x00000000, + .end = 0xffffffff, + .flags = IORESOURCE_IO, + .name = "PCI I/O Space" +}; + +int ixp2000_pci_setup(int nr, struct pci_sys_data *sys) +{ + if (nr >= 1) + return 0; + + sys->resource[0] = &ixp2000_pci_io_space; + sys->resource[1] = &ixp2000_pci_mem_space; + sys->resource[2] = NULL; + + return 1; +} + diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig new file mode 100644 index 0000000..aacb5f9 --- /dev/null +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -0,0 +1,127 @@ +if ARCH_IXP4XX + +config ARCH_SUPPORTS_BIG_ENDIAN + bool + default y + +menu "Intel IXP4xx Implementation Options" + +comment "IXP4xx Platforms" + +config ARCH_AVILA + bool "Avila" + help + Say 'Y' here if you want your kernel to support the Gateworks + Avila Network Platform. For more information on this platform, + see <file:Documentation/arm/IXP4xx>. + +config ARCH_ADI_COYOTE + bool "Coyote" + help + Say 'Y' here if you want your kernel to support the ADI + Engineering Coyote Gateway Reference Platform. For more + information on this platform, see <file:Documentation/arm/IXP4xx>. + +config ARCH_IXDP425 + bool "IXDP425" + help + Say 'Y' here if you want your kernel to support Intel's + IXDP425 Development Platform (Also known as Richfield). + For more information on this platform, see <file:Documentation/arm/IXP4xx>. + +config MACH_IXDPG425 + bool "IXDPG425" + help + Say 'Y' here if you want your kernel to support Intel's + IXDPG425 Development Platform (Also known as Montajade). + For more information on this platform, see <file:Documentation/arm/IXP4xx>. + +config MACH_IXDP465 + bool "IXDP465" + help + Say 'Y' here if you want your kernel to support Intel's + IXDP465 Development Platform (Also known as BMP). + For more information on this platform, see Documentation/arm/IXP4xx. + + +# +# IXCDP1100 is the exact same HW as IXDP425, but with a different machine +# number from the bootloader due to marketing monkeys, so we just enable it +# by default if IXDP425 is enabled. +# +config ARCH_IXCDP1100 + bool + depends on ARCH_IXDP425 + default y + +config ARCH_PRPMC1100 + bool "PrPMC1100" + help + Say 'Y' here if you want your kernel to support the Motorola + PrPCM1100 Processor Mezanine Module. For more information on + this platform, see <file:Documentation/arm/IXP4xx>. + +# +# Avila and IXDP share the same source for now. Will change in future +# +config ARCH_IXDP4XX + bool + depends on ARCH_IXDP425 || ARCH_AVILA || MACH_IXDP465 + default y + +# +# Certain registers and IRQs are only enabled if supporting IXP465 CPUs +# +config CPU_IXP46X + bool + depends on MACH_IXDP465 + default y + +config MACH_GTWX5715 + bool "Gemtek WX5715 (Linksys WRV54G)" + depends on ARCH_IXP4XX + help + This board is currently inside the Linksys WRV54G Gateways. + + IXP425 - 266mhz + 32mb SDRAM + 8mb Flash + miniPCI slot 0 does not have a card connector soldered to the board + miniPCI slot 1 has an ISL3880 802.11g card (Prism54) + npe0 is connected to a Kendin KS8995M Switch (4 ports) + npe1 is the "wan" port + "Console" UART is available on J11 as console + "High Speed" UART is n/c (as far as I can tell) + 20 Pin ARM/Xscale JTAG interface on J2 + + +comment "IXP4xx Options" + +config IXP4XX_INDIRECT_PCI + bool "Use indirect PCI memory access" + help + IXP4xx provides two methods of accessing PCI memory space: + + 1) A direct mapped window from 0x48000000 to 0x4bffffff (64MB). + To access PCI via this space, we simply ioremap() the BAR + into the kernel and we can use the standard read[bwl]/write[bwl] + macros. This is the preferred method due to speed but it + limits the system to just 64MB of PCI memory. This can be + problamatic if using video cards and other memory-heavy devices. + + 2) If > 64MB of memory space is required, the IXP4xx can be + configured to use indirect registers to access PCI This allows + for up to 128MB (0x48000000 to 0x4fffffff) of memory on the bus. + The disadvantadge of this is that every PCI access requires + three local register accesses plus a spinlock, but in some + cases the performance hit is acceptable. In addition, you cannot + mmap() PCI devices in this case due to the indirect nature + of the PCI window. + + By default, the direct method is used. Choose this option if you + need to use the indirect method instead. If you don't know + what you need, leave this option unselected. + +endmenu + +endif diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile new file mode 100644 index 0000000..ddecbda --- /dev/null +++ b/arch/arm/mach-ixp4xx/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +obj-y += common.o common-pci.o + +obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o +obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o +obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o +obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o + diff --git a/arch/arm/mach-ixp4xx/Makefile.boot b/arch/arm/mach-ixp4xx/Makefile.boot new file mode 100644 index 0000000..d84c580 --- /dev/null +++ b/arch/arm/mach-ixp4xx/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 + diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c new file mode 100644 index 0000000..94bcdb93 --- /dev/null +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -0,0 +1,527 @@ +/* + * arch/arm/mach-ixp4xx/common-pci.c + * + * IXP4XX PCI routines for all platforms + * + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright (C) 2002 Intel Corporation. + * Copyright (C) 2003 Greg Ungerer <gerg@snapgear.com> + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * 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/sched.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/interrupt.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <asm/dma-mapping.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/sizes.h> +#include <asm/system.h> +#include <asm/mach/pci.h> +#include <asm/hardware.h> + + +/* + * IXP4xx PCI read function is dependent on whether we are + * running A0 or B0 (AppleGate) silicon. + */ +int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data); + +/* + * Base address for PCI regsiter region + */ +unsigned long ixp4xx_pci_reg_base = 0; + +/* + * PCI cfg an I/O routines are done by programming a + * command/byte enable register, and then read/writing + * the data from a data regsiter. We need to ensure + * these transactions are atomic or we will end up + * with corrupt data on the bus or in a driver. + */ +static DEFINE_SPINLOCK(ixp4xx_pci_lock); + +/* + * Read from PCI config space + */ +static void crp_read(u32 ad_cbe, u32 *data) +{ + unsigned long flags; + spin_lock_irqsave(&ixp4xx_pci_lock, flags); + *PCI_CRP_AD_CBE = ad_cbe; + *data = *PCI_CRP_RDATA; + spin_unlock_irqrestore(&ixp4xx_pci_lock, flags); +} + +/* + * Write to PCI config space + */ +static void crp_write(u32 ad_cbe, u32 data) +{ + unsigned long flags; + spin_lock_irqsave(&ixp4xx_pci_lock, flags); + *PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe; + *PCI_CRP_WDATA = data; + spin_unlock_irqrestore(&ixp4xx_pci_lock, flags); +} + +static inline int check_master_abort(void) +{ + /* check Master Abort bit after access */ + unsigned long isr = *PCI_ISR; + + if (isr & PCI_ISR_PFE) { + /* make sure the Master Abort bit is reset */ + *PCI_ISR = PCI_ISR_PFE; + pr_debug("%s failed\n", __FUNCTION__); + return 1; + } + + return 0; +} + +int ixp4xx_pci_read_errata(u32 addr, u32 cmd, u32* data) +{ + unsigned long flags; + int retval = 0; + int i; + + spin_lock_irqsave(&ixp4xx_pci_lock, flags); + + *PCI_NP_AD = addr; + + /* + * PCI workaround - only works if NP PCI space reads have + * no side effects!!! Read 8 times. last one will be good. + */ + for (i = 0; i < 8; i++) { + *PCI_NP_CBE = cmd; + *data = *PCI_NP_RDATA; + *data = *PCI_NP_RDATA; + } + + if(check_master_abort()) + retval = 1; + + spin_unlock_irqrestore(&ixp4xx_pci_lock, flags); + return retval; +} + +int ixp4xx_pci_read_no_errata(u32 addr, u32 cmd, u32* data) +{ + unsigned long flags; + int retval = 0; + + spin_lock_irqsave(&ixp4xx_pci_lock, flags); + + *PCI_NP_AD = addr; + + /* set up and execute the read */ + *PCI_NP_CBE = cmd; + + /* the result of the read is now in NP_RDATA */ + *data = *PCI_NP_RDATA; + + if(check_master_abort()) + retval = 1; + + spin_unlock_irqrestore(&ixp4xx_pci_lock, flags); + return retval; +} + +int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data) +{ + unsigned long flags; + int retval = 0; + + spin_lock_irqsave(&ixp4xx_pci_lock, flags); + + *PCI_NP_AD = addr; + + /* set up the write */ + *PCI_NP_CBE = cmd; + + /* execute the write by writing to NP_WDATA */ + *PCI_NP_WDATA = data; + + if(check_master_abort()) + retval = 1; + + spin_unlock_irqrestore(&ixp4xx_pci_lock, flags); + return retval; +} + +static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where) +{ + u32 addr; + if (!bus_num) { + /* type 0 */ + addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) | + (where & ~3); + } else { + /* type 1 */ + addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) | + ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1; + } + return addr; +} + +/* + * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes. + * 0 and 3 are not valid indexes... + */ +static u32 bytemask[] = { + /*0*/ 0, + /*1*/ 0xff, + /*2*/ 0xffff, + /*3*/ 0, + /*4*/ 0xffffffff, +}; + +static u32 local_byte_lane_enable_bits(u32 n, int size) +{ + if (size == 1) + return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL; + if (size == 2) + return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL; + if (size == 4) + return 0; + return 0xffffffff; +} + +static int local_read_config(int where, int size, u32 *value) +{ + u32 n, data; + pr_debug("local_read_config from %d size %d\n", where, size); + n = where % 4; + crp_read(where & ~3, &data); + *value = (data >> (8*n)) & bytemask[size]; + pr_debug("local_read_config read %#x\n", *value); + return PCIBIOS_SUCCESSFUL; +} + +static int local_write_config(int where, int size, u32 value) +{ + u32 n, byte_enables, data; + pr_debug("local_write_config %#x to %d size %d\n", value, where, size); + n = where % 4; + byte_enables = local_byte_lane_enable_bits(n, size); + if (byte_enables == 0xffffffff) + return PCIBIOS_BAD_REGISTER_NUMBER; + data = value << (8*n); + crp_write((where & ~3) | byte_enables, data); + return PCIBIOS_SUCCESSFUL; +} + +static u32 byte_lane_enable_bits(u32 n, int size) +{ + if (size == 1) + return (0xf & ~BIT(n)) << 4; + if (size == 2) + return (0xf & ~(BIT(n) | BIT(n+1))) << 4; + if (size == 4) + return 0; + return 0xffffffff; +} + +static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) +{ + u32 n, byte_enables, addr, data; + u8 bus_num = bus->number; + + pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size, + bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + *value = 0xffffffff; + n = where % 4; + byte_enables = byte_lane_enable_bits(n, size); + if (byte_enables == 0xffffffff) + return PCIBIOS_BAD_REGISTER_NUMBER; + + addr = ixp4xx_config_addr(bus_num, devfn, where); + if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = (data >> (8*n)) & bytemask[size]; + pr_debug("read_config_byte read %#x\n", *value); + return PCIBIOS_SUCCESSFUL; +} + +static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) +{ + u32 n, byte_enables, addr, data; + u8 bus_num = bus->number; + + pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where, + size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + n = where % 4; + byte_enables = byte_lane_enable_bits(n, size); + if (byte_enables == 0xffffffff) + return PCIBIOS_BAD_REGISTER_NUMBER; + + addr = ixp4xx_config_addr(bus_num, devfn, where); + data = value << (8*n); + if (ixp4xx_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops ixp4xx_ops = { + .read = ixp4xx_pci_read_config, + .write = ixp4xx_pci_write_config, +}; + +/* + * PCI abort handler + */ +static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + u32 isr, status; + + isr = *PCI_ISR; + local_read_config(PCI_STATUS, 2, &status); + pr_debug("PCI: abort_handler addr = %#lx, isr = %#x, " + "status = %#x\n", addr, isr, status); + + /* make sure the Master Abort bit is reset */ + *PCI_ISR = PCI_ISR_PFE; + status |= PCI_STATUS_REC_MASTER_ABORT; + local_write_config(PCI_STATUS, 2, status); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + + +/* + * Setup DMA mask to 64MB on PCI devices. Ignore all other devices. + */ +static int ixp4xx_pci_platform_notify(struct device *dev) +{ + if(dev->bus == &pci_bus_type) { + *dev->dma_mask = SZ_64M - 1; + dev->coherent_dma_mask = SZ_64M - 1; + dmabounce_register_dev(dev, 2048, 4096); + } + return 0; +} + +static int ixp4xx_pci_platform_notify_remove(struct device *dev) +{ + if(dev->bus == &pci_bus_type) { + dmabounce_unregister_dev(dev); + } + return 0; +} + +int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) +{ + return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M); +} + +void __init ixp4xx_pci_preinit(void) +{ + unsigned long processor_id; + + asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :); + + /* + * Determine which PCI read method to use. + * Rev 0 IXP425 requires workaround. + */ + if (!(processor_id & 0xf) && !cpu_is_ixp46x()) { + printk("PCI: IXP42x A0 silicon detected - " + "PCI Non-Prefetch Workaround Enabled\n"); + ixp4xx_pci_read = ixp4xx_pci_read_errata; + } else + ixp4xx_pci_read = ixp4xx_pci_read_no_errata; + + + /* hook in our fault handler for PCI errors */ + hook_fault_code(16+6, abort_handler, SIGBUS, "imprecise external abort"); + + pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n"); + + /* + * We use identity AHB->PCI address translation + * in the 0x48000000 to 0x4bffffff address space + */ + *PCI_PCIMEMBASE = 0x48494A4B; + + /* + * We also use identity PCI->AHB address translation + * in 4 16MB BARs that begin at the physical memory start + */ + *PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) + + ((PHYS_OFFSET & 0xFF000000) >> 8) + + ((PHYS_OFFSET & 0xFF000000) >> 16) + + ((PHYS_OFFSET & 0xFF000000) >> 24) + + 0x00010203; + + if (*PCI_CSR & PCI_CSR_HOST) { + printk("PCI: IXP4xx is host\n"); + + pr_debug("setup BARs in controller\n"); + + /* + * We configure the PCI inbound memory windows to be + * 1:1 mapped to SDRAM + */ + local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET + 0x00000000); + local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + 0x01000000); + local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + 0x02000000); + local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + 0x03000000); + + /* + * Enable CSR window at 0xff000000. + */ + local_write_config(PCI_BASE_ADDRESS_4, 4, 0xff000008); + + /* + * Enable the IO window to be way up high, at 0xfffffc00 + */ + local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01); + } else { + printk("PCI: IXP4xx is target - No bus scan performed\n"); + } + + printk("PCI: IXP4xx Using %s access for memory space\n", +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + "direct" +#else + "indirect" +#endif + ); + + pr_debug("clear error bits in ISR\n"); + *PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE; + + /* + * Set Initialize Complete in PCI Control Register: allow IXP4XX to + * respond to PCI configuration cycles. Specify that the AHB bus is + * operating in big endian mode. Set up byte lane swapping between + * little-endian PCI and the big-endian AHB bus + */ +#ifdef __ARMEB__ + *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS; +#else + *PCI_CSR = PCI_CSR_IC; +#endif + + pr_debug("DONE\n"); +} + +int ixp4xx_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if (nr >= 1) + return 0; + + res = kmalloc(sizeof(*res) * 2, GFP_KERNEL); + if (res == NULL) { + /* + * If we're out of memory this early, something is wrong, + * so we might as well catch it here. + */ + panic("PCI: unable to allocate resources?\n"); + } + memset(res, 0, sizeof(*res) * 2); + + local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + + res[0].name = "PCI I/O Space"; + res[0].start = 0x00001000; + res[0].end = 0xffff0000; + res[0].flags = IORESOURCE_IO; + + res[1].name = "PCI Memory Space"; + res[1].start = 0x48000000; +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + res[1].end = 0x4bffffff; +#else + res[1].end = 0x4fffffff; +#endif + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + platform_notify = ixp4xx_pci_platform_notify; + platform_notify_remove = ixp4xx_pci_platform_notify_remove; + + return 1; +} + +struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys); +} + +/* + * We override these so we properly do dmabounce otherwise drivers + * are able to set the dma_mask to 0xffffffff and we can no longer + * trap bounces. :( + * + * We just return true on everyhing except for < 64MB in which case + * we will fail miseralby and die since we can't handle that case. + */ +int +pci_set_dma_mask(struct pci_dev *dev, u64 mask) +{ + if (mask >= SZ_64M - 1 ) + return 0; + + return -EIO; +} + +int +pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask) +{ + if (mask >= SZ_64M - 1 ) + return 0; + + return -EIO; +} + +int +pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) +{ + if (mask >= SZ_64M - 1 ) + return 0; + + return -EIO; +} + +EXPORT_SYMBOL(pci_set_dma_mask); +EXPORT_SYMBOL(pci_dac_set_dma_mask); +EXPORT_SYMBOL(pci_set_consistent_dma_mask); +EXPORT_SYMBOL(ixp4xx_pci_read); +EXPORT_SYMBOL(ixp4xx_pci_write); + diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c new file mode 100644 index 0000000..267ba02 --- /dev/null +++ b/arch/arm/mach-ixp4xx/common.c @@ -0,0 +1,353 @@ +/* + * arch/arm/mach-ixp4xx/common.c + * + * Generic code shared across all IXP4XX platforms + * + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright 2002 (c) Intel Corporation + * Copyright 2003-2004 (c) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/serial.h> +#include <linux/sched.h> +#include <linux/tty.h> +#include <linux/serial_core.h> +#include <linux/bootmem.h> +#include <linux/interrupt.h> +#include <linux/bitops.h> +#include <linux/time.h> +#include <linux/timex.h> + +#include <asm/hardware.h> +#include <asm/uaccess.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/irq.h> + +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> + +enum ixp4xx_irq_type { + IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE +}; +static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type); + +/************************************************************************* + * GPIO acces functions + *************************************************************************/ + +/* + * Configure GPIO line for input, interrupt, or output operation + * + * TODO: Enable/disable the irq_desc based on interrupt or output mode. + * TODO: Should these be named ixp4xx_gpio_? + */ +void gpio_line_config(u8 line, u32 style) +{ + static const int gpio2irq[] = { + 6, 7, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 + }; + u32 enable; + volatile u32 *int_reg; + u32 int_style; + enum ixp4xx_irq_type irq_type; + + enable = *IXP4XX_GPIO_GPOER; + + if (style & IXP4XX_GPIO_OUT) { + enable &= ~((1) << line); + } else if (style & IXP4XX_GPIO_IN) { + enable |= ((1) << line); + + switch (style & IXP4XX_GPIO_INTSTYLE_MASK) + { + case (IXP4XX_GPIO_ACTIVE_HIGH): + int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH; + irq_type = IXP4XX_IRQ_LEVEL; + break; + case (IXP4XX_GPIO_ACTIVE_LOW): + int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW; + irq_type = IXP4XX_IRQ_LEVEL; + break; + case (IXP4XX_GPIO_RISING_EDGE): + int_style = IXP4XX_GPIO_STYLE_RISING_EDGE; + irq_type = IXP4XX_IRQ_EDGE; + break; + case (IXP4XX_GPIO_FALLING_EDGE): + int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE; + irq_type = IXP4XX_IRQ_EDGE; + break; + case (IXP4XX_GPIO_TRANSITIONAL): + int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL; + irq_type = IXP4XX_IRQ_EDGE; + break; + default: + int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH; + irq_type = IXP4XX_IRQ_LEVEL; + break; + } + + if (style & IXP4XX_GPIO_INTSTYLE_MASK) + ixp4xx_config_irq(gpio2irq[line], irq_type); + + if (line >= 8) { /* pins 8-15 */ + line -= 8; + int_reg = IXP4XX_GPIO_GPIT2R; + } + else { /* pins 0-7 */ + int_reg = IXP4XX_GPIO_GPIT1R; + } + + /* Clear the style for the appropriate pin */ + *int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR << + (line * IXP4XX_GPIO_STYLE_SIZE)); + + /* Set the new style */ + *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); + } + + *IXP4XX_GPIO_GPOER = enable; +} + +EXPORT_SYMBOL(gpio_line_config); + +/************************************************************************* + * IXP4xx chipset I/O mapping + *************************************************************************/ +static struct map_desc ixp4xx_io_desc[] __initdata = { + { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */ + .virtual = IXP4XX_PERIPHERAL_BASE_VIRT, + .physical = IXP4XX_PERIPHERAL_BASE_PHYS, + .length = IXP4XX_PERIPHERAL_REGION_SIZE, + .type = MT_DEVICE + }, { /* Expansion Bus Config Registers */ + .virtual = IXP4XX_EXP_CFG_BASE_VIRT, + .physical = IXP4XX_EXP_CFG_BASE_PHYS, + .length = IXP4XX_EXP_CFG_REGION_SIZE, + .type = MT_DEVICE + }, { /* PCI Registers */ + .virtual = IXP4XX_PCI_CFG_BASE_VIRT, + .physical = IXP4XX_PCI_CFG_BASE_PHYS, + .length = IXP4XX_PCI_CFG_REGION_SIZE, + .type = MT_DEVICE + } +}; + +void __init ixp4xx_map_io(void) +{ + iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc)); +} + + +/************************************************************************* + * IXP4xx chipset IRQ handling + * + * TODO: GPIO IRQs should be marked invalid until the user of the IRQ + * (be it PCI or something else) configures that GPIO line + * as an IRQ. + **************************************************************************/ +static void ixp4xx_irq_mask(unsigned int irq) +{ + if (cpu_is_ixp46x() && irq >= 32) + *IXP4XX_ICMR2 &= ~(1 << (irq - 32)); + else + *IXP4XX_ICMR &= ~(1 << irq); +} + +static void ixp4xx_irq_unmask(unsigned int irq) +{ + if (cpu_is_ixp46x() && irq >= 32) + *IXP4XX_ICMR2 |= (1 << (irq - 32)); + else + *IXP4XX_ICMR |= (1 << irq); +} + +static void ixp4xx_irq_ack(unsigned int irq) +{ + static int irq2gpio[32] = { + -1, -1, -1, -1, -1, -1, 0, 1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, -1, -1, + }; + int line = (irq < 32) ? irq2gpio[irq] : -1; + + if (line >= 0) + gpio_line_isr_clear(line); +} + +/* + * Level triggered interrupts on GPIO lines can only be cleared when the + * interrupt condition disappears. + */ +static void ixp4xx_irq_level_unmask(unsigned int irq) +{ + ixp4xx_irq_ack(irq); + ixp4xx_irq_unmask(irq); +} + +static struct irqchip ixp4xx_irq_level_chip = { + .ack = ixp4xx_irq_mask, + .mask = ixp4xx_irq_mask, + .unmask = ixp4xx_irq_level_unmask, +}; + +static struct irqchip ixp4xx_irq_edge_chip = { + .ack = ixp4xx_irq_ack, + .mask = ixp4xx_irq_mask, + .unmask = ixp4xx_irq_unmask, +}; + +static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type) +{ + switch (type) { + case IXP4XX_IRQ_LEVEL: + set_irq_chip(irq, &ixp4xx_irq_level_chip); + set_irq_handler(irq, do_level_IRQ); + break; + case IXP4XX_IRQ_EDGE: + set_irq_chip(irq, &ixp4xx_irq_edge_chip); + set_irq_handler(irq, do_edge_IRQ); + break; + } + set_irq_flags(irq, IRQF_VALID); +} + +void __init ixp4xx_init_irq(void) +{ + int i = 0; + + /* Route all sources to IRQ instead of FIQ */ + *IXP4XX_ICLR = 0x0; + + /* Disable all interrupt */ + *IXP4XX_ICMR = 0x0; + + if (cpu_is_ixp46x()) { + /* Route upper 32 sources to IRQ instead of FIQ */ + *IXP4XX_ICLR2 = 0x00; + + /* Disable upper 32 interrupts */ + *IXP4XX_ICMR2 = 0x00; + } + + /* Default to all level triggered */ + for(i = 0; i < NR_IRQS; i++) + ixp4xx_config_irq(i, IXP4XX_IRQ_LEVEL); +} + + +/************************************************************************* + * IXP4xx timer tick + * We use OS timer1 on the CPU for the timer tick and the timestamp + * counter as a source of real clock ticks to account for missed jiffies. + *************************************************************************/ + +static unsigned volatile last_jiffy_time; + +#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) + +/* IRQs are disabled before entering here from do_gettimeofday() */ +static unsigned long ixp4xx_gettimeoffset(void) +{ + u32 elapsed; + + elapsed = *IXP4XX_OSTS - last_jiffy_time; + + return elapsed / CLOCK_TICKS_PER_USEC; +} + +static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + /* Clear Pending Interrupt by writing '1' to it */ + *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; + + /* + * Catch up with the real idea of time + */ + while ((*IXP4XX_OSTS - last_jiffy_time) > LATCH) { + timer_tick(regs); + last_jiffy_time += LATCH; + } + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction ixp4xx_timer_irq = { + .name = "IXP4xx Timer Tick", + .flags = SA_INTERRUPT, + .handler = ixp4xx_timer_interrupt +}; + +static void __init ixp4xx_timer_init(void) +{ + /* Clear Pending Interrupt by writing '1' to it */ + *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; + + /* Setup the Timer counter value */ + *IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; + + /* Reset time-stamp counter */ + *IXP4XX_OSTS = 0; + last_jiffy_time = 0; + + /* Connect the interrupt handler and enable the interrupt */ + setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); +} + +struct sys_timer ixp4xx_timer = { + .init = ixp4xx_timer_init, + .offset = ixp4xx_gettimeoffset, +}; + +static struct resource ixp46x_i2c_resources[] = { + [0] = { + .start = 0xc8011000, + .end = 0xc801101c, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IXP4XX_I2C, + .end = IRQ_IXP4XX_I2C, + .flags = IORESOURCE_IRQ + } +}; + +/* + * I2C controller. The IXP46x uses the same block as the IOP3xx, so + * we just use the same device name. + */ +static struct platform_device ixp46x_i2c_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = ixp46x_i2c_resources +}; + +static struct platform_device *ixp46x_devices[] __initdata = { + &ixp46x_i2c_controller +}; + +void __init ixp4xx_sys_init(void) +{ + if (cpu_is_ixp46x()) { + platform_add_devices(ixp46x_devices, + ARRAY_SIZE(ixp46x_devices)); + } +} + diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c new file mode 100644 index 0000000..afafb42 --- /dev/null +++ b/arch/arm/mach-ixp4xx/coyote-pci.c @@ -0,0 +1,70 @@ +/* + * arch/arch/mach-ixp4xx/coyote-pci.c + * + * PCI setup routines for ADI Engineering Coyote platform + * + * Copyright (C) 2002 Jungo Software Technologies. + * Copyright (C) 2003 MontaVista Softwrae, Inc. + * + * Maintainer: Deepak Saxena <dsaxena@mvista.com> + * + * 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/pci.h> +#include <linux/init.h> + +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/irq.h> + +#include <asm/mach/pci.h> + +extern void ixp4xx_pci_preinit(void); +extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); +extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); + +void __init coyote_pci_preinit(void) +{ + gpio_line_config(COYOTE_PCI_SLOT0_PIN, + IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW); + + gpio_line_config(COYOTE_PCI_SLOT1_PIN, + IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW); + + gpio_line_isr_clear(COYOTE_PCI_SLOT0_PIN); + gpio_line_isr_clear(COYOTE_PCI_SLOT1_PIN); + + ixp4xx_pci_preinit(); +} + +static int __init coyote_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (slot == COYOTE_PCI_SLOT0_DEVID) + return IRQ_COYOTE_PCI_SLOT0; + else if (slot == COYOTE_PCI_SLOT1_DEVID) + return IRQ_COYOTE_PCI_SLOT1; + else return -1; +} + +struct hw_pci coyote_pci __initdata = { + .nr_controllers = 1, + .preinit = coyote_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, + .map_irq = coyote_map_irq, +}; + +int __init coyote_pci_init(void) +{ + if (machine_is_adi_coyote()) + pci_common_init(&coyote_pci); + return 0; +} + +subsys_initcall(coyote_pci_init); diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c new file mode 100644 index 0000000..8a05a12 --- /dev/null +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -0,0 +1,130 @@ +/* + * arch/arm/mach-ixp4xx/coyote-setup.c + * + * Board setup for ADI Engineering and IXDGP425 boards + * + * Copyright (C) 2003-2005 MontaVista Software, Inc. + * + * Author: Deepak Saxena <dsaxena@plexity.net> + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> + +#include <asm/types.h> +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> + +void __init coyote_map_io(void) +{ + ixp4xx_map_io(); +} + +static struct flash_platform_data coyote_flash_data = { + .map_name = "cfi_probe", + .width = 2, +}; + +static struct resource coyote_flash_resource = { + .start = COYOTE_FLASH_BASE, + .end = COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device coyote_flash = { + .name = "IXP4XX-Flash", + .id = 0, + .dev = { + .platform_data = &coyote_flash_data, + }, + .num_resources = 1, + .resource = &coyote_flash_resource, +}; + +static struct resource coyote_uart_resource = { + .start = IXP4XX_UART2_BASE_PHYS, + .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, +}; + +static struct plat_serial8250_port coyote_uart_data = { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, +}; + +static struct platform_device coyote_uart = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = &coyote_uart_data, + }, + .num_resources = 1, + .resource = &coyote_uart_resource, +}; + +static struct platform_device *coyote_devices[] __initdata = { + &coyote_flash, + &coyote_uart +}; + +static void __init coyote_init(void) +{ + *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE; + *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; + + if (machine_is_ixdpg425()) { + coyote_uart_data.membase = + (char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET); + coyote_uart_data.mapbase = IXP4XX_UART1_BASE_PHYS; + coyote_uart_data.irq = IRQ_IXP4XX_UART1; + } + + + ixp4xx_sys_init(); + platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices)); +} + +#ifdef CONFIG_ARCH_ADI_COYOTE +MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, + IXP4XX_PERIPHERAL_BASE_VIRT) + MAPIO(coyote_map_io) + INITIRQ(ixp4xx_init_irq) + .timer = &ixp4xx_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(coyote_init) +MACHINE_END +#endif + +/* + * IXDPG425 is identical to Coyote except for which serial port + * is connected. + */ +#ifdef CONFIG_MACH_IXDPG425 +MACHINE_START(IXDPG425, "Intel IXDPG425") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, + IXP4XX_PERIPHERAL_BASE_VIRT) + MAPIO(coyote_map_io) + INITIRQ(ixp4xx_init_irq) + .timer = &ixp4xx_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(coyote_init) +MACHINE_END +#endif + diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c new file mode 100644 index 0000000..b180358 --- /dev/null +++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c @@ -0,0 +1,101 @@ +/* + * arch/arm/mach-ixp4xx/gtwx5715-pci.c + * + * Gemtek GTWX5715 (Linksys WRV54G) board setup + * + * Copyright (C) 2004 George T. Joseph + * Derived from Coyote + * + * 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/pci.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/arch/gtwx5715.h> +#include <asm/mach/pci.h> + +extern void ixp4xx_pci_preinit(void); +extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); +extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); + + /* + * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h + * Slot 0 isn't actually populated with a card connector but + * we initialize it anyway in case a future version has the + * slot populated or someone with good soldering skills has + * some free time. + */ + + +static void gtwx5715_init_gpio(u8 pin, u32 style) +{ + gpio_line_config(pin, style | IXP4XX_GPIO_ACTIVE_LOW); + + if (style & IXP4XX_GPIO_IN) gpio_line_isr_clear(pin); +} + +void __init gtwx5715_pci_preinit(void) +{ + gtwx5715_init_gpio(GTWX5715_PCI_SLOT0_INTA_GPIO, IXP4XX_GPIO_IN); + gtwx5715_init_gpio(GTWX5715_PCI_SLOT1_INTA_GPIO, IXP4XX_GPIO_IN); + + ixp4xx_pci_preinit(); +} + + +static int __init gtwx5715_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int rc; + static int gtwx5715_irqmap + [GTWX5715_PCI_SLOT_COUNT] + [GTWX5715_PCI_INT_PIN_COUNT] = { + {GTWX5715_PCI_SLOT0_INTA_IRQ, GTWX5715_PCI_SLOT0_INTB_IRQ}, + {GTWX5715_PCI_SLOT1_INTA_IRQ, GTWX5715_PCI_SLOT1_INTB_IRQ}, +}; + + if (slot >= GTWX5715_PCI_SLOT_COUNT || + pin >= GTWX5715_PCI_INT_PIN_COUNT) rc = -1; + else + rc = gtwx5715_irqmap[slot][pin-1]; + + printk("%s: Mapped slot %d pin %d to IRQ %d\n", __FUNCTION__,slot, pin, rc); + return(rc); +} + +struct hw_pci gtwx5715_pci __initdata = { + .nr_controllers = 1, + .preinit = gtwx5715_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, + .map_irq = gtwx5715_map_irq, +}; + +int __init gtwx5715_pci_init(void) +{ + if (machine_is_gtwx5715()) + { + pci_common_init(>wx5715_pci); + } + + return 0; +} + +subsys_initcall(gtwx5715_pci_init); diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c new file mode 100644 index 0000000..e77c86e --- /dev/null +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -0,0 +1,153 @@ +/* + * arch/arm/mach-ixp4xx/gtwx5715-setup.c + * + * Gemtek GTWX5715 (Linksys WRV54G) board settup + * + * Copyright (C) 2004 George T. Joseph + * Derived from Coyote + * + * 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 <linux/device.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> + +#include <asm/types.h> +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/arch/gtwx5715.h> + +/* + * Xscale UART registers are 32 bits wide with only the least + * significant 8 bits having any meaning. From a configuration + * perspective, this means 2 things... + * + * Setting .regshift = 2 so that the standard 16550 registers + * line up on every 4th byte. + * + * Shifting the register start virtual address +3 bytes when + * compiled big-endian. Since register writes are done on a + * single byte basis, if the shift isn't done the driver will + * write the value into the most significant byte of the register, + * which is ignored, instead of the least significant. + */ + +#ifdef __ARMEB__ +#define REG_OFFSET 3 +#else +#define REG_OFFSET 0 +#endif + +/* + * Only the second or "console" uart is connected on the gtwx5715. + */ + +static struct resource gtwx5715_uart_resources[] = { + { + .start = IXP4XX_UART2_BASE_PHYS, + .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_IXP4XX_UART2, + .end = IRQ_IXP4XX_UART2, + .flags = IORESOURCE_IRQ, + }, + { }, +}; + + +static struct plat_serial8250_port gtwx5715_uart_platform_data[] = { + { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { }, +}; + +static struct platform_device gtwx5715_uart_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = gtwx5715_uart_platform_data, + }, + .num_resources = 2, + .resource = gtwx5715_uart_resources, +}; + + +void __init gtwx5715_map_io(void) +{ + ixp4xx_map_io(); +} + +static struct flash_platform_data gtwx5715_flash_data = { + .map_name = "cfi_probe", + .width = 2, +}; + +static struct resource gtwx5715_flash_resource = { + .start = GTWX5715_FLASH_BASE, + .end = GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device gtwx5715_flash = { + .name = "IXP4XX-Flash", + .id = 0, + .dev = { + .platform_data = >wx5715_flash_data, + }, + .num_resources = 1, + .resource = >wx5715_flash_resource, +}; + +static struct platform_device *gtwx5715_devices[] __initdata = { + >wx5715_uart_device, + >wx5715_flash, +}; + +static void __init gtwx5715_init(void) +{ + platform_add_devices(gtwx5715_devices, ARRAY_SIZE(gtwx5715_devices)); +} + + +MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)") + MAINTAINER("George Joseph") + BOOT_MEM(PHYS_OFFSET, IXP4XX_UART2_BASE_PHYS, + IXP4XX_UART2_BASE_VIRT) + MAPIO(gtwx5715_map_io) + INITIRQ(ixp4xx_init_irq) + .timer = &ixp4xx_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(gtwx5715_init) +MACHINE_END + + diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c new file mode 100644 index 0000000..c2ab9eb --- /dev/null +++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -0,0 +1,84 @@ +/* + * arch/arm/mach-ixp4xx/ixdp425-pci.c + * + * IXDP425 board-level PCI initialization + * + * Copyright (C) 2002 Intel Corporation. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * 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/config.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/delay.h> + +#include <asm/mach/pci.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +void __init ixdp425_pci_preinit(void) +{ + gpio_line_config(IXDP425_PCI_INTA_PIN, + IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW); + gpio_line_config(IXDP425_PCI_INTB_PIN, + IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW); + gpio_line_config(IXDP425_PCI_INTC_PIN, + IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW); + gpio_line_config(IXDP425_PCI_INTD_PIN, + IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW); + + gpio_line_isr_clear(IXDP425_PCI_INTA_PIN); + gpio_line_isr_clear(IXDP425_PCI_INTB_PIN); + gpio_line_isr_clear(IXDP425_PCI_INTC_PIN); + gpio_line_isr_clear(IXDP425_PCI_INTD_PIN); + + ixp4xx_pci_preinit(); +} + +static int __init ixdp425_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + static int pci_irq_table[IXDP425_PCI_IRQ_LINES] = { + IRQ_IXDP425_PCI_INTA, + IRQ_IXDP425_PCI_INTB, + IRQ_IXDP425_PCI_INTC, + IRQ_IXDP425_PCI_INTD + }; + + int irq = -1; + + if (slot >= 1 && slot <= IXDP425_PCI_MAX_DEV && + pin >= 1 && pin <= IXDP425_PCI_IRQ_LINES) { + irq = pci_irq_table[(slot + pin - 2) % 4]; + } + + return irq; +} + +struct hw_pci ixdp425_pci __initdata = { + .nr_controllers = 1, + .preinit = ixdp425_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, + .map_irq = ixdp425_map_irq, +}; + +int __init ixdp425_pci_init(void) +{ + if (machine_is_ixdp425() || machine_is_ixcdp1100() || + machine_is_avila() || machine_is_ixdp465()) + pci_common_init(&ixdp425_pci); + return 0; +} + +subsys_initcall(ixdp425_pci_init); + diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c new file mode 100644 index 0000000..77346c1 --- /dev/null +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -0,0 +1,181 @@ +/* + * arch/arm/mach-ixp4xx/ixdp425-setup.c + * + * IXDP425/IXCDP1100 board-setup + * + * Copyright (C) 2003-2005 MontaVista Software, Inc. + * + * Author: Deepak Saxena <dsaxena@plexity.net> + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> + +#include <asm/types.h> +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> + +void __init ixdp425_map_io(void) +{ + ixp4xx_map_io(); +} + +static struct flash_platform_data ixdp425_flash_data = { + .map_name = "cfi_probe", + .width = 2, +}; + +static struct resource ixdp425_flash_resource = { + .start = IXDP425_FLASH_BASE, + .end = IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ixdp425_flash = { + .name = "IXP4XX-Flash", + .id = 0, + .dev = { + .platform_data = &ixdp425_flash_data, + }, + .num_resources = 1, + .resource = &ixdp425_flash_resource, +}; + +static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = { + .sda_pin = IXDP425_SDA_PIN, + .scl_pin = IXDP425_SCL_PIN, +}; + +static struct platform_device ixdp425_i2c_controller = { + .name = "IXP4XX-I2C", + .id = 0, + .dev = { + .platform_data = &ixdp425_i2c_gpio_pins, + }, + .num_resources = 0 +}; + +static struct resource ixdp425_uart_resources[] = { + { + .start = IXP4XX_UART1_BASE_PHYS, + .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM + }, + { + .start = IXP4XX_UART2_BASE_PHYS, + .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM + } +}; + +static struct plat_serial8250_port ixdp425_uart_data[] = { + { + .mapbase = IXP4XX_UART1_BASE_PHYS, + .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART1, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART1, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + } +}; + +static struct platform_device ixdp425_uart = { + .name = "serial8250", + .id = 0, + .dev.platform_data = ixdp425_uart_data, + .num_resources = 2, + .resource = ixdp425_uart_resources +}; + +static struct platform_device *ixdp425_devices[] __initdata = { + &ixdp425_i2c_controller, + &ixdp425_flash, + &ixdp425_uart +}; + + +static void __init ixdp425_init(void) +{ + ixp4xx_sys_init(); + + /* + * IXP465 has 32MB window + */ + if (machine_is_ixdp465()) { + ixdp425_flash_resource.end += IXDP425_FLASH_SIZE; + } + + platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices)); +} + +MACHINE_START(IXDP425, "Intel IXDP425 Development Platform") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, + IXP4XX_PERIPHERAL_BASE_VIRT) + MAPIO(ixdp425_map_io) + INITIRQ(ixp4xx_init_irq) + .timer = &ixp4xx_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(ixdp425_init) +MACHINE_END + +MACHINE_START(IXDP465, "Intel IXDP465 Development Platform") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, + IXP4XX_PERIPHERAL_BASE_VIRT) + MAPIO(ixdp425_map_io) + INITIRQ(ixp4xx_init_irq) + .timer = &ixp4xx_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(ixdp425_init) +MACHINE_END + +MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, + IXP4XX_PERIPHERAL_BASE_VIRT) + MAPIO(ixdp425_map_io) + INITIRQ(ixp4xx_init_irq) + .timer = &ixp4xx_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(ixdp425_init) +MACHINE_END + +/* + * Avila is functionally equivalent to IXDP425 except that it adds + * a CF IDE slot hanging off the expansion bus. When we have a + * driver for IXP4xx CF IDE with driver model support we'll move + * Avila to it's own setup file. + */ +#ifdef CONFIG_ARCH_AVILA +MACHINE_START(AVILA, "Gateworks Avila Network Platform") + MAINTAINER("Deepak Saxena <dsaxena@plexity.net>") + BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, + IXP4XX_PERIPHERAL_BASE_VIRT) + MAPIO(ixdp425_map_io) + INITIRQ(ixp4xx_init_irq) + .timer = &ixp4xx_timer, + BOOT_PARAMS(0x0100) + INIT_MACHINE(ixdp425_init) +MACHINE_END +#endif + diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c new file mode 100644 index 0000000..ce4563f --- /dev/null +++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c @@ -0,0 +1,66 @@ +/* + * arch/arch/mach-ixp4xx/ixdpg425-pci.c + * + * PCI setup routines for Intel IXDPG425 Platform + * + * Copyright (C) 2004 MontaVista Softwrae, Inc. + * + * Maintainer: Deepak Saxena <dsaxena@plexity.net> + * + * 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/pci.h> +#include <linux/init.h> + +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/irq.h> + +#include <asm/mach/pci.h> + +extern void ixp4xx_pci_preinit(void); +extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); +extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); + +void __init ixdpg425_pci_preinit(void) +{ + gpio_line_config(6, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW); + gpio_line_config(7, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW); + + gpio_line_isr_clear(6); + gpio_line_isr_clear(7); + + ixp4xx_pci_preinit(); +} + +static int __init ixdpg425_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (slot == 12 || slot == 13) + return IRQ_IXP4XX_GPIO7; + else if (slot == 14) + return IRQ_IXP4XX_GPIO6; + else return -1; +} + +struct hw_pci ixdpg425_pci __initdata = { + .nr_controllers = 1, + .preinit = ixdpg425_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, + .map_irq = ixdpg425_map_irq, +}; + +int __init ixdpg425_pci_init(void) +{ + if (machine_is_ixdpg425()) + pci_common_init(&ixdpg425_pci); + return 0; +} + +subsys_initcall(ixdpg425_pci_init); diff --git a/arch/arm/mach-l7200/Makefile b/arch/arm/mach-l7200/Makefile new file mode 100644 index 0000000..4bd8ebd --- /dev/null +++ b/arch/arm/mach-l7200/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := core.o +obj-m := +obj-n := +obj- := + diff --git a/arch/arm/mach-l7200/Makefile.boot b/arch/arm/mach-l7200/Makefile.boot new file mode 100644 index 0000000..6c72ecb --- /dev/null +++ b/arch/arm/mach-l7200/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y := 0xf0008000 + diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c new file mode 100644 index 0000000..606ca95 --- /dev/null +++ b/arch/arm/mach-l7200/core.c @@ -0,0 +1,89 @@ +/* + * linux/arch/arm/mm/mm-lusl7200.c + * + * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) + * + * Extra MM routines for L7200 architecture + */ +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/page.h> + +#include <asm/mach/map.h> +#include <asm/arch/hardware.h> + +/* + * IRQ base register + */ +#define IRQ_BASE (IO_BASE_2 + 0x1000) + +/* + * Normal IRQ registers + */ +#define IRQ_STATUS (*(volatile unsigned long *) (IRQ_BASE + 0x000)) +#define IRQ_RAWSTATUS (*(volatile unsigned long *) (IRQ_BASE + 0x004)) +#define IRQ_ENABLE (*(volatile unsigned long *) (IRQ_BASE + 0x008)) +#define IRQ_ENABLECLEAR (*(volatile unsigned long *) (IRQ_BASE + 0x00c)) +#define IRQ_SOFT (*(volatile unsigned long *) (IRQ_BASE + 0x010)) +#define IRQ_SOURCESEL (*(volatile unsigned long *) (IRQ_BASE + 0x018)) + +/* + * Fast IRQ registers + */ +#define FIQ_STATUS (*(volatile unsigned long *) (IRQ_BASE + 0x100)) +#define FIQ_RAWSTATUS (*(volatile unsigned long *) (IRQ_BASE + 0x104)) +#define FIQ_ENABLE (*(volatile unsigned long *) (IRQ_BASE + 0x108)) +#define FIQ_ENABLECLEAR (*(volatile unsigned long *) (IRQ_BASE + 0x10c)) +#define FIQ_SOFT (*(volatile unsigned long *) (IRQ_BASE + 0x110)) +#define FIQ_SOURCESEL (*(volatile unsigned long *) (IRQ_BASE + 0x118)) + +static void l7200_mask_irq(unsigned int irq) +{ + IRQ_ENABLECLEAR = 1 << irq; +} + +static void l7200_unmask_irq(unsigned int irq) +{ + IRQ_ENABLE = 1 << irq; +} + +static void __init l7200_init_irq(void) +{ + int irq; + + IRQ_ENABLECLEAR = 0xffffffff; /* clear all interrupt enables */ + FIQ_ENABLECLEAR = 0xffffffff; /* clear all fast interrupt enables */ + + for (irq = 0; irq < NR_IRQS; irq++) { + irq_desc[irq].valid = 1; + irq_desc[irq].probe_ok = 1; + irq_desc[irq].mask_ack = l7200_mask_irq; + irq_desc[irq].mask = l7200_mask_irq; + irq_desc[irq].unmask = l7200_unmask_irq; + } + + init_FIQ(); +} + +static struct map_desc l7200_io_desc[] __initdata = { + { IO_BASE, IO_START, IO_SIZE, MT_DEVICE }, + { IO_BASE_2, IO_START_2, IO_SIZE_2, MT_DEVICE }, + { AUX_BASE, AUX_START, AUX_SIZE, MT_DEVICE }, + { FLASH1_BASE, FLASH1_START, FLASH1_SIZE, MT_DEVICE }, + { FLASH2_BASE, FLASH2_START, FLASH2_SIZE, MT_DEVICE } +}; + +static void __init l7200_map_io(void) +{ + iotable_init(l7200_io_desc, ARRAY_SIZE(l7200_io_desc)); +} + +MACHINE_START(L7200, "LinkUp Systems L7200") + MAINTAINER("Steve Hill / Scott McConnell") + BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000) + MAPIO(l7200_map_io) + INITIRQ(l7200_init_irq) +MACHINE_END + diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig new file mode 100644 index 0000000..8a17867a --- /dev/null +++ b/arch/arm/mach-lh7a40x/Kconfig @@ -0,0 +1,70 @@ +if ARCH_LH7A40X + +menu "LH7A40X Implementations" + +config MACH_KEV7A400 + bool "KEV7A400" + select ARCH_LH7A400 + help + Say Y here if you are using the Sharp KEV7A400 development + board. This hardware is discontinued, so I'd be very + suprised if you wanted this option. + +config MACH_LPD7A400 + bool "LPD7A400 Card Engine" + select ARCH_LH7A400 +# select IDE_POLL + help + Say Y here if you are using Logic Product Development's + LPD7A400 CardEngine. For the time being, the LPD7A400 and + LPD7A404 options are mutually exclusive. + +config MACH_LPD7A404 + bool "LPD7A404 Card Engine" + select ARCH_LH7A404 +# select IDE_POLL + help + Say Y here if you are using Logic Product Development's + LPD7A404 CardEngine. For the time being, the LPD7A400 and + LPD7A404 options are mutually exclusive. + +config ARCH_LH7A400 + bool + +config ARCH_LH7A404 + bool + +config LH7A40X_CONTIGMEM + bool "Disable NUMA Support" + depends on ARCH_LH7A40X + help + Say Y here if your bootloader sets the SROMLL bit(s) in + the SDRAM controller, organizing memory as a contiguous + array. This option will disable CONFIG_DISCONTIGMEM and + force the kernel to manage all memory in one node. + + Setting this option incorrectly may prevent the kernel from + booting. It is OK to leave it N. + + For more information, consult + <file:Documentation/arm/Sharp-LH/SDRAM>. + +config LH7A40X_ONE_BANK_PER_NODE + bool "Optimize NUMA Node Tables for Size" + depends on ARCH_LH7A40X && !LH7A40X_CONTIGMEM + help + Say Y here to produce compact memory node tables. By + default pairs of adjacent physical RAM banks are managed + together in a single node, incurring some wasted overhead + in the node tables, however also maintaining compatibility + with systems where physical memory is truly contiguous. + + Setting this option incorrectly may prevent the kernel from + booting. It is OK to leave it N. + + For more information, consult + <file:Documentation/arm/Sharp-LH/SDRAM>. + +endmenu + +endif diff --git a/arch/arm/mach-lh7a40x/Makefile b/arch/arm/mach-lh7a40x/Makefile new file mode 100644 index 0000000..e90512d --- /dev/null +++ b/arch/arm/mach-lh7a40x/Makefile @@ -0,0 +1,14 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := time.o +obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o +obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o +obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o + +obj-m := +obj-n := +obj- := diff --git a/arch/arm/mach-lh7a40x/Makefile.boot b/arch/arm/mach-lh7a40x/Makefile.boot new file mode 100644 index 0000000..af941be --- /dev/null +++ b/arch/arm/mach-lh7a40x/Makefile.boot @@ -0,0 +1,4 @@ + zreladdr-y := 0xc0008000 +params_phys-y := 0xc0000100 +initrd_phys-y := 0xc4000000 + diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c new file mode 100644 index 0000000..be5d17f --- /dev/null +++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c @@ -0,0 +1,111 @@ +/* arch/arm/mach-lh7a40x/arch-kev7a400.c + * + * Copyright (C) 2004 Logic Product Development + * + * 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/tty.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/interrupt.h> + +#include <asm/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/mach/map.h> + +#include "common.h" + + /* This function calls the board specific IRQ initialization function. */ + +static struct map_desc kev7a400_io_desc[] __initdata = { + { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, + { CPLD_VIRT, CPLD_PHYS, CPLD_SIZE, MT_DEVICE }, +}; + +void __init kev7a400_map_io(void) +{ + iotable_init (kev7a400_io_desc, ARRAY_SIZE (kev7a400_io_desc)); +} + +static u16 CPLD_IRQ_mask; /* Mask for CPLD IRQs, 1 == unmasked */ + +static void kev7a400_ack_cpld_irq (u32 irq) +{ + CPLD_CL_INT = 1 << (irq - IRQ_KEV7A400_CPLD); +} + +static void kev7a400_mask_cpld_irq (u32 irq) +{ + CPLD_IRQ_mask &= ~(1 << (irq - IRQ_KEV7A400_CPLD)); + CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; +} + +static void kev7a400_unmask_cpld_irq (u32 irq) +{ + CPLD_IRQ_mask |= 1 << (irq - IRQ_KEV7A400_CPLD); + CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; +} + +static struct irqchip kev7a400_cpld_chip = { + .ack = kev7a400_ack_cpld_irq, + .mask = kev7a400_mask_cpld_irq, + .unmask = kev7a400_unmask_cpld_irq, +}; + + +static void kev7a400_cpld_handler (unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + u32 mask = CPLD_LATCHED_INTS; + irq = IRQ_KEV7A400_CPLD; + for (; mask; mask >>= 1, ++irq) { + if (mask & 1) + desc[irq].handle (irq, desc, regs); + } +} + +void __init lh7a40x_init_board_irq (void) +{ + int irq; + + for (irq = IRQ_KEV7A400_CPLD; + irq < IRQ_KEV7A400_CPLD + NR_IRQ_BOARD; ++irq) { + set_irq_chip (irq, &kev7a400_cpld_chip); + set_irq_handler (irq, do_edge_IRQ); + set_irq_flags (irq, IRQF_VALID); + } + set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler); + + /* Clear all CPLD interrupts */ + CPLD_CL_INT = 0xff; /* CPLD_INTR_MMC_CD | CPLD_INTR_ETH_INT; */ + + GPIO_GPIOINTEN = 0; /* Disable all GPIO interrupts */ + barrier(); + +#if 0 + GPIO_INTTYPE1 + = (GPIO_INTR_PCC1_CD | GPIO_INTR_PCC1_CD); /* Edge trig. */ + GPIO_INTTYPE2 = 0; /* Falling edge & low-level */ + GPIO_GPIOFEOI = 0xff; /* Clear all GPIO interrupts */ + GPIO_GPIOINTEN = 0xff; /* Enable all GPIO interrupts */ + + init_FIQ(); +#endif +} + +MACHINE_START (KEV7A400, "Sharp KEV7a400") + MAINTAINER ("Marc Singer") + BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) + BOOT_PARAMS (0xc0000100) + MAPIO (kev7a400_map_io) + INITIRQ (lh7a400_init_irq) + .timer = &lh7a40x_timer, +MACHINE_END diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c new file mode 100644 index 0000000..c823447 --- /dev/null +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c @@ -0,0 +1,286 @@ +/* arch/arm/mach-lh7a40x/arch-lpd7a40x.c + * + * Copyright (C) 2004 Logic Product Development + * + * 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/tty.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/interrupt.h> + +#include <asm/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/mach/map.h> + +#include "common.h" + +static struct resource smc91x_resources[] = { + [0] = { + .start = CPLD00_PHYS, + .end = CPLD00_PHYS + CPLD00_SIZE - 1, /* Only needs 16B */ + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = IRQ_LPD7A40X_ETH_INT, + .end = IRQ_LPD7A40X_ETH_INT, + .flags = IORESOURCE_IRQ, + }, + +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct resource lh7a40x_usbclient_resources[] = { + [0] = { + .start = USB_PHYS, + .end = (USB_PHYS + 0xFF), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USBINTR, + .end = IRQ_USBINTR, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL; + +static struct platform_device lh7a40x_usbclient_device = { + .name = "lh7a40x_udc", + .id = 0, + .dev = { + .dma_mask = &lh7a40x_usbclient_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + }, + .num_resources = ARRAY_SIZE (lh7a40x_usbclient_resources), + .resource = lh7a40x_usbclient_resources, +}; + +#if defined (CONFIG_ARCH_LH7A404) + +static struct resource lh7a404_usbhost_resources [] = { + [0] = { + .start = USBH_PHYS, + .end = (USBH_PHYS + 0xFF), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USHINTR, + .end = IRQ_USHINTR, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 lh7a404_usbhost_dma_mask = 0xffffffffUL; + +static struct platform_device lh7a404_usbhost_device = { + .name = "lh7a404-ohci", + .id = 0, + .dev = { + .dma_mask = &lh7a404_usbhost_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + }, + .num_resources = ARRAY_SIZE (lh7a404_usbhost_resources), + .resource = lh7a404_usbhost_resources, +}; + +#endif + +static struct platform_device *lpd7a40x_devs[] __initdata = { + &smc91x_device, + &lh7a40x_usbclient_device, +#if defined (CONFIG_ARCH_LH7A404) + &lh7a404_usbhost_device, +#endif +}; + +extern void lpd7a400_map_io (void); + +static void __init lpd7a40x_init (void) +{ + CPLD_CONTROL |= (1<<6); /* Mask USB1 connection IRQ */ + CPLD_CONTROL &= ~(0 + | (1<<1) /* Disable LCD */ + | (1<<0) /* Enable WLAN */ + ); + + platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs)); +} + +static void lh7a40x_ack_cpld_irq (u32 irq) +{ + /* CPLD doesn't have ack capability */ +} + +static void lh7a40x_mask_cpld_irq (u32 irq) +{ + switch (irq) { + case IRQ_LPD7A40X_ETH_INT: + CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4; + break; + case IRQ_LPD7A400_TS: + CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8; + break; + } +} + +static void lh7a40x_unmask_cpld_irq (u32 irq) +{ + switch (irq) { + case IRQ_LPD7A40X_ETH_INT: + CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4; + break; + case IRQ_LPD7A400_TS: + CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8; + break; + } +} + +static struct irqchip lpd7a40x_cpld_chip = { + .ack = lh7a40x_ack_cpld_irq, + .mask = lh7a40x_mask_cpld_irq, + .unmask = lh7a40x_unmask_cpld_irq, +}; + +static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask = CPLD_INTERRUPTS; + + desc->chip->ack (irq); + + if ((mask & 0x1) == 0) /* WLAN */ + IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT); + + if ((mask & 0x2) == 0) /* Touch */ + IRQ_DISPATCH (IRQ_LPD7A400_TS); + + desc->chip->unmask (irq); /* Level-triggered need this */ +} + + +void __init lh7a40x_init_board_irq (void) +{ + int irq; + + /* Rev A (v2.8): PF0, PF1, PF2, and PF3 are available IRQs. + PF7 supports the CPLD. + Rev B (v3.4): PF0, PF1, and PF2 are available IRQs. + PF3 supports the CPLD. + (Some) LPD7A404 prerelease boards report a version + number of 0x16, but we force an override since the + hardware is of the newer variety. + */ + + unsigned char cpld_version = CPLD_REVISION; + int pinCPLD = (cpld_version == 0x28) ? 7 : 3; + +#if defined CONFIG_MACH_LPD7A404 + cpld_version = 0x34; /* Coerce LPD7A404 to RevB */ +#endif + + /* First, configure user controlled GPIOF interrupts */ + + GPIO_PFDD &= ~0x0f; /* PF0-3 are inputs */ + GPIO_INTTYPE1 &= ~0x0f; /* PF0-3 are level triggered */ + GPIO_INTTYPE2 &= ~0x0f; /* PF0-3 are active low */ + barrier (); + GPIO_GPIOFINTEN |= 0x0f; /* Enable PF0, PF1, PF2, and PF3 IRQs */ + + /* Then, configure CPLD interrupt */ + + CPLD_INTERRUPTS = 0x9c; /* Disable all CPLD interrupts */ + GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ + GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */ + GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ + barrier (); + GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ + + /* Cascade CPLD interrupts */ + + for (irq = IRQ_BOARD_START; + irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { + set_irq_chip (irq, &lpd7a40x_cpld_chip); + set_irq_handler (irq, do_edge_IRQ); + set_irq_flags (irq, IRQF_VALID); + } + + set_irq_chained_handler ((cpld_version == 0x28) + ? IRQ_CPLD_V28 + : IRQ_CPLD_V34, + lpd7a40x_cpld_handler); +} + +static struct map_desc lpd7a400_io_desc[] __initdata = { + { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, + /* Mapping added to work around chip select problems */ + { IOBARRIER_VIRT, IOBARRIER_PHYS, IOBARRIER_SIZE, MT_DEVICE }, + { CF_VIRT, CF_PHYS, CF_SIZE, MT_DEVICE }, + /* This mapping is redundant since the smc driver performs another. */ +/* { CPLD00_VIRT, CPLD00_PHYS, CPLD00_SIZE, MT_DEVICE }, */ + { CPLD02_VIRT, CPLD02_PHYS, CPLD02_SIZE, MT_DEVICE }, + { CPLD06_VIRT, CPLD06_PHYS, CPLD06_SIZE, MT_DEVICE }, + { CPLD08_VIRT, CPLD08_PHYS, CPLD08_SIZE, MT_DEVICE }, + { CPLD0C_VIRT, CPLD0C_PHYS, CPLD0C_SIZE, MT_DEVICE }, + { CPLD0E_VIRT, CPLD0E_PHYS, CPLD0E_SIZE, MT_DEVICE }, + { CPLD10_VIRT, CPLD10_PHYS, CPLD10_SIZE, MT_DEVICE }, + { CPLD12_VIRT, CPLD12_PHYS, CPLD12_SIZE, MT_DEVICE }, + { CPLD14_VIRT, CPLD14_PHYS, CPLD14_SIZE, MT_DEVICE }, + { CPLD16_VIRT, CPLD16_PHYS, CPLD16_SIZE, MT_DEVICE }, + { CPLD18_VIRT, CPLD18_PHYS, CPLD18_SIZE, MT_DEVICE }, + { CPLD1A_VIRT, CPLD1A_PHYS, CPLD1A_SIZE, MT_DEVICE }, +}; + +void __init +lpd7a400_map_io(void) +{ + iotable_init (lpd7a400_io_desc, ARRAY_SIZE (lpd7a400_io_desc)); + + /* Fixup (improve) Static Memory Controller settings */ + SMC_BCR0 = 0x200039af; /* Boot Flash */ + SMC_BCR6 = 0x1000fbe0; /* CPLD */ + SMC_BCR7 = 0x1000b2c2; /* Compact Flash */ +} + +#ifdef CONFIG_MACH_LPD7A400 + +MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") + MAINTAINER ("Marc Singer") + BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) + BOOT_PARAMS (0xc0000100) + MAPIO (lpd7a400_map_io) + INITIRQ (lh7a400_init_irq) + .timer = &lh7a40x_timer, + INIT_MACHINE (lpd7a40x_init) +MACHINE_END + +#endif + +#ifdef CONFIG_MACH_LPD7A404 + +MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") + MAINTAINER ("Marc Singer") + BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) + BOOT_PARAMS (0xc0000100) + MAPIO (lpd7a400_map_io) + INITIRQ (lh7a404_init_irq) + .timer = &lh7a40x_timer, + INIT_MACHINE (lpd7a40x_init) +MACHINE_END + +#endif diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h new file mode 100644 index 0000000..beda7c2 --- /dev/null +++ b/arch/arm/mach-lh7a40x/common.h @@ -0,0 +1,16 @@ +/* arch/arm/mach-lh7a40x/common.h + * + * Copyright (C) 2004 Marc Singer + * + * 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. + * + */ + +extern struct sys_timer lh7a40x_timer; + +extern void lh7a400_init_irq (void); +extern void lh7a404_init_irq (void); + +#define IRQ_DISPATCH(irq) irq_desc[irq].handle ((irq), &irq_desc[irq], regs) diff --git a/arch/arm/mach-lh7a40x/irq-kev7a400.c b/arch/arm/mach-lh7a40x/irq-kev7a400.c new file mode 100644 index 0000000..691bb09 --- /dev/null +++ b/arch/arm/mach-lh7a40x/irq-kev7a400.c @@ -0,0 +1,92 @@ +/* arch/arm/mach-lh7a40x/irq-kev7a400.c + * + * Copyright (C) 2004 Coastal Environmental Systems + * + * 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/interrupt.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/mach/hardware.h> +#include <asm/mach/irqs.h> + + + /* KEV7a400 CPLD IRQ handling */ + +static u16 CPLD_IRQ_mask; /* Mask for CPLD IRQs, 1 == unmasked */ + +static void +lh7a400_ack_cpld_irq (u32 irq) +{ + CPLD_CL_INT = 1 << (irq - IRQ_KEV7A400_CPLD); +} + +static void +lh7a400_mask_cpld_irq (u32 irq) +{ + CPLD_IRQ_mask &= ~(1 << (irq - IRQ_KEV7A400_CPLD)); + CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; +} + +static void +lh7a400_unmask_cpld_irq (u32 irq) +{ + CPLD_IRQ_mask |= 1 << (irq - IRQ_KEV7A400_CPLD); + CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; +} + +static struct +irqchip lh7a400_cpld_chip = { + .ack = lh7a400_ack_cpld_irq, + .mask = lh7a400_mask_cpld_irq, + .unmask = lh7a400_unmask_cpld_irq, +}; + +static void +lh7a400_cpld_handler (unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + u32 mask = CPLD_LATCHED_INTS; + irq = IRQ_KEV_7A400_CPLD; + for (; mask; mask >>= 1, ++irq) { + if (mask & 1) + desc[irq].handle (irq, desc, regs); + } +} + + /* IRQ initialization */ + +void __init +lh7a400_init_board_irq (void) +{ + int irq; + + for (irq = IRQ_KEV7A400_CPLD; + irq < IRQ_KEV7A400_CPLD + NR_IRQ_KEV7A400_CPLD; ++irq) { + set_irq_chip (irq, &lh7a400_cpld_chip); + set_irq_handler (irq, do_edge_IRQ); + set_irq_flags (irq, IRQF_VALID); + } + set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler); + + /* Clear all CPLD interrupts */ + CPLD_CL_INT = 0xff; /* CPLD_INTR_MMC_CD | CPLD_INTR_ETH_INT; */ + + /* *** FIXME CF enabled in ide-probe.c */ + + GPIO_GPIOINTEN = 0; /* Disable all GPIO interrupts */ + barrier(); + GPIO_INTTYPE1 + = (GPIO_INTR_PCC1_CD | GPIO_INTR_PCC1_CD); /* Edge trig. */ + GPIO_INTTYPE2 = 0; /* Falling edge & low-level */ + GPIO_GPIOFEOI = 0xff; /* Clear all GPIO interrupts */ + GPIO_GPIOINTEN = 0xff; /* Enable all GPIO interrupts */ + + init_FIQ(); +} diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c new file mode 100644 index 0000000..f334d81 --- /dev/null +++ b/arch/arm/mach-lh7a40x/irq-lh7a400.c @@ -0,0 +1,90 @@ +/* arch/arm/mach-lh7a40x/irq-lh7a400.c + * + * Copyright (C) 2004 Coastal Environmental Systems + * + * 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/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/arch/irq.h> +#include <asm/arch/irqs.h> + + + /* CPU IRQ handling */ + +static void lh7a400_mask_irq (u32 irq) +{ + INTC_INTENC = (1 << irq); +} + +static void lh7a400_unmask_irq (u32 irq) +{ + INTC_INTENS = (1 << irq); +} + +static void lh7a400_ack_gpio_irq (u32 irq) +{ + GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq)); + INTC_INTENC = (1 << irq); +} + +static struct irqchip lh7a400_internal_chip = { + .ack = lh7a400_mask_irq, /* Level triggering -> mask is ack */ + .mask = lh7a400_mask_irq, + .unmask = lh7a400_unmask_irq, +}; + +static struct irqchip lh7a400_gpio_chip = { + .ack = lh7a400_ack_gpio_irq, + .mask = lh7a400_mask_irq, + .unmask = lh7a400_unmask_irq, +}; + + + /* IRQ initialization */ + +void __init lh7a400_init_irq (void) +{ + int irq; + + INTC_INTENC = 0xffffffff; /* Disable all interrupts */ + GPIO_GPIOFINTEN = 0x00; /* Disable all GPIOF interrupts */ + barrier (); + + for (irq = 0; irq < NR_IRQS; ++irq) { + switch (irq) { + case IRQ_GPIO0INTR: + case IRQ_GPIO1INTR: + case IRQ_GPIO2INTR: + case IRQ_GPIO3INTR: + case IRQ_GPIO4INTR: + case IRQ_GPIO5INTR: + case IRQ_GPIO6INTR: + case IRQ_GPIO7INTR: + set_irq_chip (irq, &lh7a400_gpio_chip); + set_irq_handler (irq, do_level_IRQ); /* OK default */ + break; + default: + set_irq_chip (irq, &lh7a400_internal_chip); + set_irq_handler (irq, do_level_IRQ); + } + set_irq_flags (irq, IRQF_VALID); + } + + lh7a40x_init_board_irq (); + +/* *** FIXME: the LH7a400 does use FIQ interrupts in some cases. For + the time being, these are not initialized. */ + +/* init_FIQ(); */ +} diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c new file mode 100644 index 0000000..122fada --- /dev/null +++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c @@ -0,0 +1,158 @@ +/* arch/arm/mach-lh7a40x/irq-lh7a404.c + * + * Copyright (C) 2004 Logic Product Development + * + * 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/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/arch/irq.h> +#include <asm/arch/irqs.h> + +#define USE_PRIORITIES + +/* See Documentation/arm/Sharp-LH/VectoredInterruptController for more + * information on using the vectored interrupt controller's + * prioritizing feature. */ + +static unsigned char irq_pri_vic1[] = { +#if defined (USE_PRIORITIES) +IRQ_GPIO3INTR, +#endif +}; +static unsigned char irq_pri_vic2[] = { +#if defined (USE_PRIORITIES) + IRQ_T3UI, IRQ_GPIO7INTR, + IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR, +#endif +}; + + /* CPU IRQ handling */ + +static void lh7a404_vic1_mask_irq (u32 irq) +{ + VIC1_INTENCLR = (1 << irq); +} + +static void lh7a404_vic1_unmask_irq (u32 irq) +{ + VIC1_INTEN = (1 << irq); +} + +static void lh7a404_vic2_mask_irq (u32 irq) +{ + VIC2_INTENCLR = (1 << (irq - 32)); +} + +static void lh7a404_vic2_unmask_irq (u32 irq) +{ + VIC2_INTEN = (1 << (irq - 32)); +} + +static void lh7a404_vic1_ack_gpio_irq (u32 irq) +{ + GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq)); + VIC1_INTENCLR = (1 << irq); +} + +static void lh7a404_vic2_ack_gpio_irq (u32 irq) +{ + GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (irq)); + VIC2_INTENCLR = (1 << irq); +} + +static struct irqchip lh7a404_vic1_chip = { + .ack = lh7a404_vic1_mask_irq, /* Because level-triggered */ + .mask = lh7a404_vic1_mask_irq, + .unmask = lh7a404_vic1_unmask_irq, +}; + +static struct irqchip lh7a404_vic2_chip = { + .ack = lh7a404_vic2_mask_irq, /* Because level-triggered */ + .mask = lh7a404_vic2_mask_irq, + .unmask = lh7a404_vic2_unmask_irq, +}; + +static struct irqchip lh7a404_gpio_vic1_chip = { + .ack = lh7a404_vic1_ack_gpio_irq, + .mask = lh7a404_vic1_mask_irq, + .unmask = lh7a404_vic1_unmask_irq, +}; + +static struct irqchip lh7a404_gpio_vic2_chip = { + .ack = lh7a404_vic2_ack_gpio_irq, + .mask = lh7a404_vic2_mask_irq, + .unmask = lh7a404_vic2_unmask_irq, +}; + + /* IRQ initialization */ + +void __init lh7a404_init_irq (void) +{ + int irq; + + VIC1_INTENCLR = 0xffffffff; + VIC2_INTENCLR = 0xffffffff; + VIC1_INTSEL = 0; /* All IRQs */ + VIC2_INTSEL = 0; /* All IRQs */ + VIC1_NVADDR = VA_VIC1DEFAULT; + VIC2_NVADDR = VA_VIC2DEFAULT; + VIC1_VECTADDR = 0; + VIC2_VECTADDR = 0; + + GPIO_GPIOFINTEN = 0x00; /* Disable all GPIOF interrupts */ + barrier (); + + /* Install prioritized interrupts, if there are any. */ + /* The | 0x20*/ + for (irq = 0; irq < 16; ++irq) { + (&VIC1_VAD0)[irq] + = (irq < ARRAY_SIZE (irq_pri_vic1)) + ? (irq_pri_vic1[irq] | VA_VECTORED) : 0; + (&VIC1_VECTCNTL0)[irq] + = (irq < ARRAY_SIZE (irq_pri_vic1)) + ? (irq_pri_vic1[irq] | VIC_CNTL_ENABLE) : 0; + (&VIC2_VAD0)[irq] + = (irq < ARRAY_SIZE (irq_pri_vic2)) + ? (irq_pri_vic2[irq] | VA_VECTORED) : 0; + (&VIC2_VECTCNTL0)[irq] + = (irq < ARRAY_SIZE (irq_pri_vic2)) + ? (irq_pri_vic2[irq] | VIC_CNTL_ENABLE) : 0; + } + + for (irq = 0; irq < NR_IRQS; ++irq) { + switch (irq) { + case IRQ_GPIO0INTR: + case IRQ_GPIO1INTR: + case IRQ_GPIO2INTR: + case IRQ_GPIO3INTR: + case IRQ_GPIO4INTR: + case IRQ_GPIO5INTR: + case IRQ_GPIO6INTR: + case IRQ_GPIO7INTR: + set_irq_chip (irq, irq < 32 + ? &lh7a404_gpio_vic1_chip + : &lh7a404_gpio_vic2_chip); + set_irq_handler (irq, do_level_IRQ); /* OK default */ + break; + default: + set_irq_chip (irq, irq < 32 + ? &lh7a404_vic1_chip + : &lh7a404_vic2_chip); + set_irq_handler (irq, do_level_IRQ); + } + set_irq_flags (irq, IRQF_VALID); + } + + lh7a40x_init_board_irq (); +} diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c new file mode 100644 index 0000000..6262d44 --- /dev/null +++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c @@ -0,0 +1,128 @@ +/* arch/arm/mach-lh7a40x/irq-lpd7a40x.c + * + * Copyright (C) 2004 Coastal Environmental Systems + * Copyright (C) 2004 Logic Product Development + * + * 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/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/arch/irqs.h> + + +static void lh7a40x_ack_cpld_irq (u32 irq) +{ + /* CPLD doesn't have ack capability */ +} + +static void lh7a40x_mask_cpld_irq (u32 irq) +{ + switch (irq) { + case IRQ_LPD7A40X_ETH_INT: + CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4; + break; + case IRQ_LPD7A400_TS: + CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8; + break; + } +} + +static void lh7a40x_unmask_cpld_irq (u32 irq) +{ + switch (irq) { + case IRQ_LPD7A40X_ETH_INT: + CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4; + break; + case IRQ_LPD7A400_TS: + CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8; + break; + } +} + +static struct irqchip lh7a40x_cpld_chip = { + .ack = lh7a40x_ack_cpld_irq, + .mask = lh7a40x_mask_cpld_irq, + .unmask = lh7a40x_unmask_cpld_irq, +}; + +static void lh7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask = CPLD_INTERRUPTS; + + desc->chip->ack (irq); + + if ((mask & 0x1) == 0) /* WLAN */ + IRQ_DISPATCH (IRQ_LPD7A40X_ETH_INT); + + if ((mask & 0x2) == 0) /* Touch */ + IRQ_DISPATCH (IRQ_LPD7A400_TS); + + desc->chip->unmask (irq); /* Level-triggered need this */ +} + + + /* IRQ initialization */ + +void __init lh7a40x_init_board_irq (void) +{ + int irq; + + /* Rev A (v2.8): PF0, PF1, PF2, and PF3 are available IRQs. + PF7 supports the CPLD. + Rev B (v3.4): PF0, PF1, and PF2 are available IRQs. + PF3 supports the CPLD. + (Some) LPD7A404 prerelease boards report a version + number of 0x16, but we force an override since the + hardware is of the newer variety. + */ + + unsigned char cpld_version = CPLD_REVISION; + int pinCPLD; + +#if defined CONFIG_MACH_LPD7A404 + cpld_version = 0x34; /* Override, for now */ +#endif + pinCPLD = (cpld_version == 0x28) ? 7 : 3; + + /* First, configure user controlled GPIOF interrupts */ + + GPIO_PFDD &= ~0x0f; /* PF0-3 are inputs */ + GPIO_INTTYPE1 &= ~0x0f; /* PF0-3 are level triggered */ + GPIO_INTTYPE2 &= ~0x0f; /* PF0-3 are active low */ + barrier (); + GPIO_GPIOFINTEN |= 0x0f; /* Enable PF0, PF1, PF2, and PF3 IRQs */ + + /* Then, configure CPLD interrupt */ + + CPLD_INTERRUPTS = 0x0c; /* Disable all CPLD interrupts */ + GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ + GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */ + GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ + barrier (); + GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ + + /* Cascade CPLD interrupts */ + + for (irq = IRQ_BOARD_START; + irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { + set_irq_chip (irq, &lh7a40x_cpld_chip); + set_irq_handler (irq, do_edge_IRQ); + set_irq_flags (irq, IRQF_VALID); + } + + set_irq_chained_handler ((cpld_version == 0x28) + ? IRQ_CPLD_V28 + : IRQ_CPLD_V34, + lh7a40x_cpld_handler); +} diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c new file mode 100644 index 0000000..51e1c81 --- /dev/null +++ b/arch/arm/mach-lh7a40x/time.c @@ -0,0 +1,75 @@ +/* + * arch/arm/mach-lh7a40x/time.c + * + * Copyright (C) 2004 Logic Product Development + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/time.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/leds.h> + +#include <asm/mach/time.h> +#include "common.h" + +#if HZ < 100 +# define TIMER_CONTROL TIMER_CONTROL2 +# define TIMER_LOAD TIMER_LOAD2 +# define TIMER_CONSTANT (508469/HZ) +# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC | TIMER_C_508KHZ) +# define TIMER_EOI TIMER_EOI2 +# define TIMER_IRQ IRQ_T2UI +#else +# define TIMER_CONTROL TIMER_CONTROL3 +# define TIMER_LOAD TIMER_LOAD3 +# define TIMER_CONSTANT (3686400/HZ) +# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC) +# define TIMER_EOI TIMER_EOI3 +# define TIMER_IRQ IRQ_T3UI +#endif + +static irqreturn_t +lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + TIMER_EOI = 0; + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction lh7a40x_timer_irq = { + .name = "LHA740x Timer Tick", + .flags = SA_INTERRUPT, + .handler = lh7a40x_timer_interrupt +}; + +static void __init lh7a40x_timer_init(void) +{ + /* Stop/disable all timers */ + TIMER_CONTROL1 = 0; + TIMER_CONTROL2 = 0; + TIMER_CONTROL3 = 0; + + setup_irq (TIMER_IRQ, &lh7a40x_timer_irq); + + TIMER_LOAD = TIMER_CONSTANT; + TIMER_CONTROL = TIMER_MODE; +} + +struct sys_timer lh7a40x_timer = { + .init = &lh7a40x_timer_init, +}; diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig new file mode 100644 index 0000000..9e42efa --- /dev/null +++ b/arch/arm/mach-omap/Kconfig @@ -0,0 +1,221 @@ +if ARCH_OMAP + +menu "TI OMAP Implementations" + +comment "OMAP Core Type" + +config ARCH_OMAP730 + depends on ARCH_OMAP + bool "OMAP730 Based System" + select ARCH_OMAP_OTG + +config ARCH_OMAP1510 + depends on ARCH_OMAP + default y + bool "OMAP1510 Based System" + +config ARCH_OMAP16XX + depends on ARCH_OMAP + bool "OMAP16XX Based System" + select ARCH_OMAP_OTG + +config ARCH_OMAP_OTG + bool + +comment "OMAP Board Type" + +config MACH_OMAP_INNOVATOR + bool "TI Innovator" + depends on ARCH_OMAP1510 || ARCH_OMAP16XX + help + TI OMAP 1510 or 1610 Innovator board support. Say Y here if you + have such a board. + +config MACH_OMAP_H2 + bool "TI H2 Support" + depends on ARCH_OMAP16XX + help + TI OMAP 1610/1611B H2 board support. Say Y here if you have such + a board. + +config MACH_OMAP_H3 + bool "TI H3 Support" + depends on ARCH_OMAP16XX + help + TI OMAP 1710 H3 board support. Say Y here if you have such + a board. + +config MACH_OMAP_H4 + bool "TI H4 Support" + depends on ARCH_OMAP16XX + help + TI OMAP 1610 H4 board support. Say Y here if you have such + a board. + +config MACH_OMAP_OSK + bool "TI OSK Support" + depends on ARCH_OMAP16XX + help + TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here + if you have such a board. + +config MACH_OMAP_PERSEUS2 + bool "TI Perseus2" + depends on ARCH_OMAP730 + help + Support for TI OMAP 730 Perseus2 board. Say Y here if you have such + a board. + +config MACH_VOICEBLUE + bool "Voiceblue" + depends on ARCH_OMAP1510 + help + Support for Voiceblue GSM/VoIP gateway. Say Y here if you have such + board. + +config MACH_NETSTAR + bool "NetStar" + depends on ARCH_OMAP1510 + help + Support for NetStar PBX. Say Y here if you have such a board. + +config MACH_OMAP_GENERIC + bool "Generic OMAP board" + depends on ARCH_OMAP1510 || ARCH_OMAP16XX + help + Support for generic OMAP-1510, 1610 or 1710 board with + no FPGA. Can be used as template for porting Linux to + custom OMAP boards. Say Y here if you have a custom + board. + +comment "OMAP Feature Selections" + +#config OMAP_BOOT_TAG +# bool "OMAP bootloader information passing" +# depends on ARCH_OMAP +# default n +# help +# Say Y, if you have a bootloader which passes information +# about your board and its peripheral configuration. + +config OMAP_MUX + bool "OMAP multiplexing support" + depends on ARCH_OMAP + default y + help + Pin multiplexing support for OMAP boards. If your bootloader + sets the multiplexing correctly, say N. Otherwise, or if unsure, + say Y. + +config OMAP_MUX_DEBUG + bool "Multiplexing debug output" + depends on OMAP_MUX + default n + help + Makes the multiplexing functions print out a lot of debug info. + This is useful if you want to find out the correct values of the + multiplexing registers. + +config OMAP_MUX_WARNINGS + bool "Warn about pins the bootloader didn't set up" + depends on OMAP_MUX + default y + help + Choose Y here to warn whenever driver initialization logic needs + to change the pin multiplexing setup. When there are no warnings + printed, it's safe to deselect OMAP_MUX for your product. + +choice + prompt "System timer" + default OMAP_MPU_TIMER + +config OMAP_MPU_TIMER + bool "Use mpu timer" + help + Select this option if you want to use the OMAP mpu timer. This + timer provides more intra-tick resolution than the 32KHz timer, + but consumes more power. + +config OMAP_32K_TIMER + bool "Use 32KHz timer" + depends on ARCH_OMAP16XX + help + Select this option if you want to enable the OMAP 32KHz timer. + This timer saves power compared to the OMAP_MPU_TIMER, and has + support for no tick during idle. The 32KHz timer provides less + intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is + currently only available for OMAP-16xx. + +endchoice + +config OMAP_32K_TIMER_HZ + int "Kernel internal timer frequency for 32KHz timer" + range 32 1024 + depends on OMAP_32K_TIMER + default "128" + help + Kernel internal timer frequency should be a divisor of 32768, + such as 64 or 128. + +choice + prompt "Low-level debug console UART" + depends on ARCH_OMAP + default OMAP_LL_DEBUG_UART1 + +config OMAP_LL_DEBUG_UART1 + bool "UART1" + +config OMAP_LL_DEBUG_UART2 + bool "UART2" + +config OMAP_LL_DEBUG_UART3 + bool "UART3" + +endchoice + +config OMAP_ARM_195MHZ + bool "OMAP ARM 195 MHz CPU" + depends on ARCH_OMAP730 + help + Enable 195MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_192MHZ + bool "OMAP ARM 192 MHz CPU" + depends on ARCH_OMAP16XX + help + Enable 192MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_182MHZ + bool "OMAP ARM 182 MHz CPU" + depends on ARCH_OMAP730 + help + Enable 182MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_168MHZ + bool "OMAP ARM 168 MHz CPU" + depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730 + help + Enable 168MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_120MHZ + bool "OMAP ARM 120 MHz CPU" + depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730 + help + Enable 120MHz clock for OMAP CPU. If unsure, say N. + +config OMAP_ARM_60MHZ + bool "OMAP ARM 60 MHz CPU" + depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730 + default y + help + Enable 60MHz clock for OMAP CPU. If unsure, say Y. + +config OMAP_ARM_30MHZ + bool "OMAP ARM 30 MHz CPU" + depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730 + help + Enable 30MHz clock for OMAP CPU. If unsure, say N. + +endmenu + +endif diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile new file mode 100644 index 0000000..4cafb11 --- /dev/null +++ b/arch/arm/mach-omap/Makefile @@ -0,0 +1,40 @@ +# +# Makefile for the linux kernel. +# + +# Common support +obj-y := common.o time.o irq.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o +obj-m := +obj-n := +obj- := +led-y := leds.o + +# Specific board support +obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o +obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o +obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o +obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o +obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o +obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o +obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o +obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o + +# OCPI interconnect support for 1710, 1610 and 5912 +obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o + +# LEDs support +led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o +led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o +led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o +obj-$(CONFIG_LEDS) += $(led-y) + +# Power Management +obj-$(CONFIG_PM) += pm.o sleep.o + +ifeq ($(CONFIG_ARCH_OMAP1510),y) +# Innovator-1510 FPGA +obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o +endif + +# kgdb support +obj-$(CONFIG_KGDB_SERIAL) += kgdb-serial.o diff --git a/arch/arm/mach-omap/Makefile.boot b/arch/arm/mach-omap/Makefile.boot new file mode 100644 index 0000000..fee1a6a --- /dev/null +++ b/arch/arm/mach-omap/Makefile.boot @@ -0,0 +1,4 @@ + zreladdr-y := 0x10008000 +params_phys-y := 0x10000100 +initrd_phys-y := 0x10800000 + diff --git a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap/board-generic.c new file mode 100644 index 0000000..2102a2c --- /dev/null +++ b/arch/arm/mach-omap/board-generic.c @@ -0,0 +1,98 @@ +/* + * linux/arch/arm/mach-omap/board-generic.c + * + * Modified from board-innovator1510.c + * + * Code for generic OMAP board. Should work on many OMAP systems where + * the device drivers take care of all the necessary hardware initialization. + * Do not put any board specific code to this file; create a new machine + * type if you need custom low-level initializations. + * + * 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/init.h> +#include <linux/device.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> +#include <asm/arch/usb.h> +#include <asm/arch/board.h> + +#include "common.h" + +static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; + +static void __init omap_generic_init_irq(void) +{ + omap_init_irq(); +} + +/* assume no Mini-AB port */ + +#ifdef CONFIG_ARCH_OMAP1510 +static struct omap_usb_config generic1510_usb_config __initdata = { + .register_host = 1, + .register_dev = 1, + .hmc_mode = 16, + .pins[0] = 3, +}; +#endif + +#if defined(CONFIG_ARCH_OMAP16XX) +static struct omap_usb_config generic1610_usb_config __initdata = { + .register_host = 1, + .register_dev = 1, + .hmc_mode = 16, + .pins[0] = 6, +}; +#endif + +static struct omap_board_config_kernel generic_config[] = { + { OMAP_TAG_USB, NULL }, +}; + +static void __init omap_generic_init(void) +{ + /* + * Make sure the serial ports are muxed on at this point. + * You have to mux them off in device drivers later on + * if not needed. + */ +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + generic_config[0].data = &generic1510_usb_config; + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (!cpu_is_omap1510()) { + generic_config[0].data = &generic1610_usb_config; + } +#endif + omap_board_config = generic_config; + omap_board_config_size = ARRAY_SIZE(generic_config); + omap_serial_init(generic_serial_ports); +} + +static void __init omap_generic_map_io(void) +{ + omap_map_io(); +} + +MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") + MAINTAINER("Tony Lindgren <tony@atomide.com>") + BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) + BOOT_PARAMS(0x10000100) + MAPIO(omap_generic_map_io) + INITIRQ(omap_generic_init_irq) + INIT_MACHINE(omap_generic_init) + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap/board-h2.c b/arch/arm/mach-omap/board-h2.c new file mode 100644 index 0000000..1f06783 --- /dev/null +++ b/arch/arm/mach-omap/board-h2.c @@ -0,0 +1,187 @@ +/* + * linux/arch/arm/mach-omap/board-h2.c + * + * Board specific inits for OMAP-1610 H2 + * + * Copyright (C) 2001 RidgeRun, Inc. + * Author: Greg Lonnon <glonnon@ridgerun.com> + * + * Copyright (C) 2002 MontaVista Software, Inc. + * + * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6 + * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com> + * + * H2 specific changes and cleanup + * Copyright (C) 2004 Nokia Corporation by Imre Deak <imre.deak@nokia.com> + * + * 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/init.h> +#include <linux/device.h> +#include <linux/delay.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/tc.h> +#include <asm/arch/usb.h> + +#include "common.h" + +extern int omap_gpio_init(void); + +static int __initdata h2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; + +static struct mtd_partition h2_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "bootloader", + .offset = 0, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* file system */ + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct flash_platform_data h2_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = h2_partitions, + .nr_parts = ARRAY_SIZE(h2_partitions), +}; + +static struct resource h2_flash_resource = { + .start = OMAP_CS2B_PHYS, + .end = OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device h2_flash_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &h2_flash_data, + }, + .num_resources = 1, + .resource = &h2_flash_resource, +}; + +static struct resource h2_smc91x_resources[] = { + [0] = { + .start = OMAP1610_ETHR_START, /* Physical */ + .end = OMAP1610_ETHR_START + 0xf, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(0), + .end = OMAP_GPIO_IRQ(0), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device h2_smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(h2_smc91x_resources), + .resource = h2_smc91x_resources, +}; + +static struct platform_device *h2_devices[] __initdata = { + &h2_flash_device, + &h2_smc91x_device, +}; + +static void __init h2_init_smc91x(void) +{ + if ((omap_request_gpio(0)) < 0) { + printk("Error requesting gpio 0 for smc91x irq\n"); + return; + } + omap_set_gpio_edge_ctrl(0, OMAP_GPIO_FALLING_EDGE); +} + +void h2_init_irq(void) +{ + omap_init_irq(); + omap_gpio_init(); + h2_init_smc91x(); +} + +static struct omap_usb_config h2_usb_config __initdata = { + /* usb1 has a Mini-AB port and external isp1301 transceiver */ + .otg = 2, + +#ifdef CONFIG_USB_GADGET_OMAP + .hmc_mode = 19, // 0:host(off) 1:dev|otg 2:disabled + // .hmc_mode = 21, // 0:host(off) 1:dev(loopback) 2:host(loopback) +#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + /* needs OTG cable, or NONSTANDARD (B-to-MiniB) */ + .hmc_mode = 20, // 1:dev|otg(off) 1:host 2:disabled +#endif + + .pins[1] = 3, +}; + +static struct omap_mmc_config h2_mmc_config __initdata = { + .mmc_blocks = 1, + .mmc1_power_pin = -1, /* tps65010 gpio3 */ + .mmc1_switch_pin = OMAP_MPUIO(1), +}; + +static struct omap_board_config_kernel h2_config[] = { + { OMAP_TAG_USB, &h2_usb_config }, + { OMAP_TAG_MMC, &h2_mmc_config }, +}; + +static void __init h2_init(void) +{ + platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); + omap_board_config = h2_config; + omap_board_config_size = ARRAY_SIZE(h2_config); +} + +static void __init h2_map_io(void) +{ + omap_map_io(); + omap_serial_init(h2_serial_ports); +} + +MACHINE_START(OMAP_H2, "TI-H2") + MAINTAINER("Imre Deak <imre.deak@nokia.com>") + BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) + BOOT_PARAMS(0x10000100) + MAPIO(h2_map_io) + INITIRQ(h2_init_irq) + INIT_MACHINE(h2_init) + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap/board-h3.c b/arch/arm/mach-omap/board-h3.c new file mode 100644 index 0000000..486a5a0 --- /dev/null +++ b/arch/arm/mach-omap/board-h3.c @@ -0,0 +1,205 @@ +/* + * linux/arch/arm/mach-omap/board-h3.c + * + * This file contains OMAP1710 H3 specific code. + * + * Copyright (C) 2004 Texas Instruments, Inc. + * Copyright (C) 2002 MontaVista Software, Inc. + * Copyright (C) 2001 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com + * + * 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/types.h> +#include <linux/init.h> +#include <linux/major.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/setup.h> +#include <asm/page.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/irqs.h> +#include <asm/arch/mux.h> +#include <asm/arch/tc.h> +#include <asm/arch/usb.h> + +#include "common.h" + +extern int omap_gpio_init(void); + +static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; + +static struct mtd_partition h3_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "bootloader", + .offset = 0, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* file system */ + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct flash_platform_data h3_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = h3_partitions, + .nr_parts = ARRAY_SIZE(h3_partitions), +}; + +static struct resource h3_flash_resource = { + .start = OMAP_CS2B_PHYS, + .end = OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &h3_flash_data, + }, + .num_resources = 1, + .resource = &h3_flash_resource, +}; + +static struct resource smc91x_resources[] = { + [0] = { + .start = OMAP1710_ETHR_START, /* Physical */ + .end = OMAP1710_ETHR_START + 0xf, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(40), + .end = OMAP_GPIO_IRQ(40), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +#define GPTIMER_BASE 0xFFFB1400 +#define GPTIMER_REGS(x) (0xFFFB1400 + (x * 0x800)) +#define GPTIMER_REGS_SIZE 0x46 + +static struct resource intlat_resources[] = { + [0] = { + .start = GPTIMER_REGS(0), /* Physical */ + .end = GPTIMER_REGS(0) + GPTIMER_REGS_SIZE, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_1610_GPTIMER1, + .end = INT_1610_GPTIMER1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device intlat_device = { + .name = "omap_intlat", + .id = 0, + .num_resources = ARRAY_SIZE(intlat_resources), + .resource = intlat_resources, +}; + +static struct platform_device *devices[] __initdata = { + &flash_device, + &smc91x_device, + &intlat_device, +}; + +static struct omap_usb_config h3_usb_config __initdata = { + /* usb1 has a Mini-AB port and external isp1301 transceiver */ + .otg = 2, + +#ifdef CONFIG_USB_GADGET_OMAP + .hmc_mode = 19, /* 0:host(off) 1:dev|otg 2:disabled */ +#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + /* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */ + .hmc_mode = 20, /* 1:dev|otg(off) 1:host 2:disabled */ +#endif + + .pins[1] = 3, +}; + +static struct omap_board_config_kernel h3_config[] = { + { OMAP_TAG_USB, &h3_usb_config }, +}; + +static void __init h3_init(void) +{ + (void) platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static void __init h3_init_smc91x(void) +{ + omap_cfg_reg(W15_1710_GPIO40); + if (omap_request_gpio(40) < 0) { + printk("Error requesting gpio 40 for smc91x irq\n"); + return; + } + omap_set_gpio_edge_ctrl(40, OMAP_GPIO_FALLING_EDGE); +} + +void h3_init_irq(void) +{ + omap_init_irq(); + omap_gpio_init(); + h3_init_smc91x(); +} + +static void __init h3_map_io(void) +{ + omap_map_io(); + omap_serial_init(h3_serial_ports); +} + +MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") + MAINTAINER("Texas Instruments, Inc.") + BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) + BOOT_PARAMS(0x10000100) + MAPIO(h3_map_io) + INITIRQ(h3_init_irq) + INIT_MACHINE(h3_init) + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c new file mode 100644 index 0000000..57cf4da --- /dev/null +++ b/arch/arm/mach-omap/board-innovator.c @@ -0,0 +1,280 @@ +/* + * linux/arch/arm/mach-omap/board-innovator.c + * + * Board specific inits for OMAP-1510 and OMAP-1610 Innovator + * + * Copyright (C) 2001 RidgeRun, Inc. + * Author: Greg Lonnon <glonnon@ridgerun.com> + * + * Copyright (C) 2002 MontaVista Software, Inc. + * + * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6 + * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com> + * + * 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/init.h> +#include <linux/device.h> +#include <linux/delay.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> + +#include <asm/arch/fpga.h> +#include <asm/arch/gpio.h> +#include <asm/arch/tc.h> +#include <asm/arch/usb.h> + +#include "common.h" + +static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; + +static struct mtd_partition innovator_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "bootloader", + .offset = 0, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* rest of flash1 is a file system */ + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = SZ_16M - SZ_2M - 2 * SZ_128K, + .mask_flags = 0 + }, + /* file system */ + { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + } +}; + +static struct flash_platform_data innovator_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = innovator_partitions, + .nr_parts = ARRAY_SIZE(innovator_partitions), +}; + +static struct resource innovator_flash_resource = { + .start = OMAP_CS0_PHYS, + .end = OMAP_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device innovator_flash_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &innovator_flash_data, + }, + .num_resources = 1, + .resource = &innovator_flash_resource, +}; + +#ifdef CONFIG_ARCH_OMAP1510 + +/* Only FPGA needs to be mapped here. All others are done with ioremap */ +static struct map_desc innovator1510_io_desc[] __initdata = { +{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE, + MT_DEVICE }, +}; + +static struct resource innovator1510_smc91x_resources[] = { + [0] = { + .start = OMAP1510_FPGA_ETHR_START, /* Physical */ + .end = OMAP1510_FPGA_ETHR_START + 0xf, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP1510_INT_ETHER, + .end = OMAP1510_INT_ETHER, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device innovator1510_smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(innovator1510_smc91x_resources), + .resource = innovator1510_smc91x_resources, +}; + +static struct platform_device *innovator1510_devices[] __initdata = { + &innovator_flash_device, + &innovator1510_smc91x_device, +}; + +#endif /* CONFIG_ARCH_OMAP1510 */ + +#ifdef CONFIG_ARCH_OMAP16XX + +static struct resource innovator1610_smc91x_resources[] = { + [0] = { + .start = INNOVATOR1610_ETHR_START, /* Physical */ + .end = INNOVATOR1610_ETHR_START + 0xf, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(0), + .end = OMAP_GPIO_IRQ(0), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device innovator1610_smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(innovator1610_smc91x_resources), + .resource = innovator1610_smc91x_resources, +}; + +static struct platform_device *innovator1610_devices[] __initdata = { + &innovator_flash_device, + &innovator1610_smc91x_device, +}; + +#endif /* CONFIG_ARCH_OMAP16XX */ + +static void __init innovator_init_smc91x(void) +{ + if (cpu_is_omap1510()) { + fpga_write(fpga_read(OMAP1510_FPGA_RST) & ~1, + OMAP1510_FPGA_RST); + udelay(750); + } else { + if ((omap_request_gpio(0)) < 0) { + printk("Error requesting gpio 0 for smc91x irq\n"); + return; + } + omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE); + } +} + +void innovator_init_irq(void) +{ + omap_init_irq(); + omap_gpio_init(); +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + omap1510_fpga_init_irq(); + } +#endif + innovator_init_smc91x(); +} + +#ifdef CONFIG_ARCH_OMAP1510 +static struct omap_usb_config innovator1510_usb_config __initdata = { + /* for bundled non-standard host and peripheral cables */ + .hmc_mode = 4, + + .register_host = 1, + .pins[1] = 6, + .pins[2] = 6, /* Conflicts with UART2 */ + + .register_dev = 1, + .pins[0] = 2, +}; +#endif + +#ifdef CONFIG_ARCH_OMAP16XX +static struct omap_usb_config h2_usb_config __initdata = { + /* usb1 has a Mini-AB port and external isp1301 transceiver */ + .otg = 2, + +#ifdef CONFIG_USB_GADGET_OMAP + .hmc_mode = 19, // 0:host(off) 1:dev|otg 2:disabled + // .hmc_mode = 21, // 0:host(off) 1:dev(loopback) 2:host(loopback) +#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + /* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */ + .hmc_mode = 20, // 1:dev|otg(off) 1:host 2:disabled +#endif + + .pins[1] = 3, +}; +#endif + +static struct omap_board_config_kernel innovator_config[] = { + { OMAP_TAG_USB, NULL }, +}; + +static void __init innovator_init(void) +{ +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices)); + } +#endif +#ifdef CONFIG_ARCH_OMAP16XX + if (!cpu_is_omap1510()) { + platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices)); + } +#endif + +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) + innovator_config[0].data = &innovator1510_usb_config; +#endif +#ifdef CONFIG_ARCH_OMAP16XX + if (cpu_is_omap1610()) + innovator_config[0].data = &h2_usb_config; +#endif + omap_board_config = innovator_config; + omap_board_config_size = ARRAY_SIZE(innovator_config); +} + +static void __init innovator_map_io(void) +{ + omap_map_io(); + +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc)); + udelay(10); /* Delay needed for FPGA */ + + /* Dump the Innovator FPGA rev early - useful info for support. */ + printk("Innovator FPGA Rev %d.%d Board Rev %d\n", + fpga_read(OMAP1510_FPGA_REV_HIGH), + fpga_read(OMAP1510_FPGA_REV_LOW), + fpga_read(OMAP1510_FPGA_BOARD_REV)); + } +#endif + omap_serial_init(innovator_serial_ports); +} + +MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") + MAINTAINER("MontaVista Software, Inc.") + BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) + BOOT_PARAMS(0x10000100) + MAPIO(innovator_map_io) + INITIRQ(innovator_init_irq) + INIT_MACHINE(innovator_init) + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap/board-netstar.c b/arch/arm/mach-omap/board-netstar.c new file mode 100644 index 0000000..54acbd2 --- /dev/null +++ b/arch/arm/mach-omap/board-netstar.c @@ -0,0 +1,151 @@ +/* + * Modified from board-generic.c + * + * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz> + * + * Code for Netstar OMAP board. + * + * 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/delay.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/notifier.h> +#include <linux/reboot.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> +#include <asm/arch/usb.h> + +#include "common.h" + +extern void __init omap_init_time(void); +extern int omap_gpio_init(void); + +static struct resource netstar_smc91x_resources[] = { + [0] = { + .start = OMAP_CS1_PHYS + 0x300, + .end = OMAP_CS1_PHYS + 0x300 + 16, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(8), + .end = OMAP_GPIO_IRQ(8), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device netstar_smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(netstar_smc91x_resources), + .resource = netstar_smc91x_resources, +}; + +static struct platform_device *netstar_devices[] __initdata = { + &netstar_smc91x_device, +}; + +static void __init netstar_init_irq(void) +{ + omap_init_irq(); + omap_gpio_init(); +} + +static void __init netstar_init(void) +{ + /* green LED */ + omap_request_gpio(4); + omap_set_gpio_direction(4, 0); + /* smc91x reset */ + omap_request_gpio(7); + omap_set_gpio_direction(7, 0); + omap_set_gpio_dataout(7, 1); + udelay(2); /* wait at least 100ns */ + omap_set_gpio_dataout(7, 0); + mdelay(50); /* 50ms until PHY ready */ + /* smc91x interrupt pin */ + omap_request_gpio(8); + omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE); + + omap_request_gpio(12); + omap_request_gpio(13); + omap_request_gpio(14); + omap_request_gpio(15); + omap_set_gpio_edge_ctrl(12, OMAP_GPIO_FALLING_EDGE); + omap_set_gpio_edge_ctrl(13, OMAP_GPIO_FALLING_EDGE); + omap_set_gpio_edge_ctrl(14, OMAP_GPIO_FALLING_EDGE); + omap_set_gpio_edge_ctrl(15, OMAP_GPIO_FALLING_EDGE); + + platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices)); + + /* Switch on green LED */ + omap_set_gpio_dataout(4, 0); + /* Switch off red LED */ + omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ + omap_writeb(0x80, OMAP_LPG1_LCR); +} + +static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; + +static void __init netstar_map_io(void) +{ + omap_map_io(); + omap_serial_init(omap_serial_ports); +} + +#define MACHINE_PANICED 1 +#define MACHINE_REBOOTING 2 +#define MACHINE_REBOOT 4 +static unsigned long machine_state; + +static int panic_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + if (test_and_set_bit(MACHINE_PANICED, &machine_state)) + return NOTIFY_DONE; + + /* Switch off green LED */ + omap_set_gpio_dataout(4, 1); + /* Flash red LED */ + omap_writeb(0x78, OMAP_LPG1_LCR); + omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */ + + return NOTIFY_DONE; +} + +static struct notifier_block panic_block = { + .notifier_call = panic_event, +}; + +static int __init netstar_late_init(void) +{ + /* TODO: Setup front panel switch here */ + + /* Setup panic notifier */ + notifier_chain_register(&panic_notifier_list, &panic_block); + + return 0; +} + +postcore_initcall(netstar_late_init); + +MACHINE_START(NETSTAR, "NetStar OMAP5910") + MAINTAINER("Ladislav Michl <michl@2n.cz>") + BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) + BOOT_PARAMS(0x10000100) + MAPIO(netstar_map_io) + INITIRQ(netstar_init_irq) + INIT_MACHINE(netstar_init) + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c new file mode 100644 index 0000000..a951fc8 --- /dev/null +++ b/arch/arm/mach-omap/board-osk.c @@ -0,0 +1,169 @@ +/* + * linux/arch/arm/mach-omap/board-osk.c + * + * Board specific init for OMAP5912 OSK + * + * Written by Dirk Behme <dirk.behme@de.bosch.com> + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/usb.h> +#include <asm/arch/mux.h> +#include <asm/arch/tc.h> + +#include "common.h" + +static struct map_desc osk5912_io_desc[] __initdata = { +{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE, + MT_DEVICE }, +}; + +static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0}; + +static struct resource osk5912_smc91x_resources[] = { + [0] = { + .start = OMAP_OSK_ETHR_START, /* Physical */ + .end = OMAP_OSK_ETHR_START + 0xf, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(0), + .end = OMAP_GPIO_IRQ(0), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device osk5912_smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(osk5912_smc91x_resources), + .resource = osk5912_smc91x_resources, +}; + +static struct resource osk5912_cf_resources[] = { + [0] = { + .start = OMAP_GPIO_IRQ(62), + .end = OMAP_GPIO_IRQ(62), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device osk5912_cf_device = { + .name = "omap_cf", + .id = -1, + .dev = { + .platform_data = (void *) 2 /* CS2 */, + }, + .num_resources = ARRAY_SIZE(osk5912_cf_resources), + .resource = osk5912_cf_resources, +}; + +static struct platform_device *osk5912_devices[] __initdata = { + &osk5912_smc91x_device, + &osk5912_cf_device, +}; + +static void __init osk_init_smc91x(void) +{ + if ((omap_request_gpio(0)) < 0) { + printk("Error requesting gpio 0 for smc91x irq\n"); + return; + } + omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE); + + /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ + EMIFS_CCS(1) |= 0x2; +} + +static void __init osk_init_cf(void) +{ + omap_cfg_reg(M7_1610_GPIO62); + if ((omap_request_gpio(62)) < 0) { + printk("Error requesting gpio 62 for CF irq\n"); + return; + } + /* it's really active-low */ + omap_set_gpio_edge_ctrl(62, OMAP_GPIO_FALLING_EDGE); +} + +void osk_init_irq(void) +{ + omap_init_irq(); + omap_gpio_init(); + osk_init_smc91x(); + osk_init_cf(); +} + +static struct omap_usb_config osk_usb_config __initdata = { + /* has usb host connector (A) ... for development it can also + * be used, with a NONSTANDARD gender-bending cable/dongle, as + * a peripheral. + */ +#ifdef CONFIG_USB_GADGET_OMAP + .register_dev = 1, + .hmc_mode = 0, +#else + .register_host = 1, + .hmc_mode = 16, + .rwc = 1, +#endif + .pins[0] = 2, +}; + +static struct omap_board_config_kernel osk_config[] = { + { OMAP_TAG_USB, &osk_usb_config }, +}; + +static void __init osk_init(void) +{ + platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); + omap_board_config = osk_config; + omap_board_config_size = ARRAY_SIZE(osk_config); + USB_TRANSCEIVER_CTRL_REG |= (3 << 1); +} + +static void __init osk_map_io(void) +{ + omap_map_io(); + iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc)); + omap_serial_init(osk_serial_ports); +} + +MACHINE_START(OMAP_OSK, "TI-OSK") + MAINTAINER("Dirk Behme <dirk.behme@de.bosch.com>") + BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) + BOOT_PARAMS(0x10000100) + MAPIO(osk_map_io) + INITIRQ(osk_init_irq) + INIT_MACHINE(osk_init) + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c new file mode 100644 index 0000000..64515ae --- /dev/null +++ b/arch/arm/mach-omap/board-perseus2.c @@ -0,0 +1,189 @@ +/* + * linux/arch/arm/mach-omap/board-perseus2.c + * + * Modified from board-generic.c + * + * Original OMAP730 support by Jean Pihet <j-pihet@ti.com> + * Updated for 2.6 by Kevin Hilman <kjh@hilman.org> + * + * 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/init.h> +#include <linux/device.h> +#include <linux/delay.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> +#include <asm/arch/fpga.h> + +#include "common.h" + +static struct resource smc91x_resources[] = { + [0] = { + .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */ + .end = H2P2_DBG_FPGA_ETHR_START + 0xf, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_730_MPU_EXT_NIRQ, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __initdata p2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 0}; + +static struct mtd_partition p2_partitions[] = { + /* bootloader (U-Boot, etc) in first sector */ + { + .name = "bootloader", + .offset = 0, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader params in the next sector */ + { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_128K, + .mask_flags = 0, + }, + /* kernel */ + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + .mask_flags = 0 + }, + /* rest of flash is a file system */ + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0 + }, +}; + +static struct flash_platform_data p2_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = p2_partitions, + .nr_parts = ARRAY_SIZE(p2_partitions), +}; + +static struct resource p2_flash_resource = { + .start = OMAP_FLASH_0_START, + .end = OMAP_FLASH_0_START + OMAP_FLASH_0_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device p2_flash_device = { + .name = "omapflash", + .id = 0, + .dev = { + .platform_data = &p2_flash_data, + }, + .num_resources = 1, + .resource = &p2_flash_resource, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct platform_device *devices[] __initdata = { + &p2_flash_device, + &smc91x_device, +}; + +static void __init omap_perseus2_init(void) +{ + (void) platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static void __init perseus2_init_smc91x(void) +{ + fpga_write(1, H2P2_DBG_FPGA_LAN_RESET); + mdelay(50); + fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1, + H2P2_DBG_FPGA_LAN_RESET); + mdelay(50); +} + +void omap_perseus2_init_irq(void) +{ + omap_init_irq(); + omap_gpio_init(); + perseus2_init_smc91x(); +} + +/* Only FPGA needs to be mapped here. All others are done with ioremap */ +static struct map_desc omap_perseus2_io_desc[] __initdata = { + {H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE, + MT_DEVICE}, +}; + +static void __init omap_perseus2_map_io(void) +{ + omap_map_io(); + iotable_init(omap_perseus2_io_desc, + ARRAY_SIZE(omap_perseus2_io_desc)); + + /* Early, board-dependent init */ + + /* + * Hold GSM Reset until needed + */ + omap_writew(omap_readw(OMAP730_DSP_M_CTL) & ~1, OMAP730_DSP_M_CTL); + + /* + * UARTs -> done automagically by 8250 driver + */ + + /* + * CSx timings, GPIO Mux ... setup + */ + + /* Flash: CS0 timings setup */ + omap_writel(0x0000fff3, OMAP730_FLASH_CFG_0); + omap_writel(0x00000088, OMAP730_FLASH_ACFG_0); + + /* + * Ethernet support trough the debug board + * CS1 timings setup + */ + omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1); + omap_writel(0x00000000, OMAP730_FLASH_ACFG_1); + + /* + * Configure MPU_EXT_NIRQ IO in IO_CONF9 register, + * It is used as the Ethernet controller interrupt + */ + omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9); + omap_serial_init(p2_serial_ports); +} + +MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") + MAINTAINER("Kevin Hilman <kjh@hilman.org>") + BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) + BOOT_PARAMS(0x10000100) + MAPIO(omap_perseus2_map_io) + INITIRQ(omap_perseus2_init_irq) + INIT_MACHINE(omap_perseus2_init) + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap/board-voiceblue.c b/arch/arm/mach-omap/board-voiceblue.c new file mode 100644 index 0000000..f1a5bff --- /dev/null +++ b/arch/arm/mach-omap/board-voiceblue.c @@ -0,0 +1,256 @@ +/* + * linux/arch/arm/mach-omap/board-voiceblue.c + * + * Modified from board-generic.c + * + * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz> + * + * Code for OMAP5910 based VoiceBlue board (VoIP to GSM gateway). + * + * 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/delay.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/notifier.h> +#include <linux/reboot.h> +#include <linux/serial_8250.h> +#include <linux/serial_reg.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/tc.h> +#include <asm/arch/mux.h> +#include <asm/arch/usb.h> + +#include "common.h" + +extern void omap_init_time(void); +extern int omap_gpio_init(void); + +static struct plat_serial8250_port voiceblue_ports[] = { + { + .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x40000), + .irq = OMAP_GPIO_IRQ(12), + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 1, + .uartclk = 3686400, + }, + { + .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x50000), + .irq = OMAP_GPIO_IRQ(13), + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 1, + .uartclk = 3686400, + }, + { + .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x60000), + .irq = OMAP_GPIO_IRQ(14), + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 1, + .uartclk = 3686400, + }, + { + .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x70000), + .irq = OMAP_GPIO_IRQ(15), + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 1, + .uartclk = 3686400, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 1, + .dev = { + .platform_data = voiceblue_ports, + }, +}; + +static int __init ext_uart_init(void) +{ + return platform_device_register(&serial_device); +} +arch_initcall(ext_uart_init); + +static struct resource voiceblue_smc91x_resources[] = { + [0] = { + .start = OMAP_CS2_PHYS + 0x300, + .end = OMAP_CS2_PHYS + 0x300 + 16, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(8), + .end = OMAP_GPIO_IRQ(8), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device voiceblue_smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(voiceblue_smc91x_resources), + .resource = voiceblue_smc91x_resources, +}; + +static struct platform_device *voiceblue_devices[] __initdata = { + &voiceblue_smc91x_device, +}; + +static struct omap_usb_config voiceblue_usb_config __initdata = { + .hmc_mode = 3, + .register_host = 1, + .register_dev = 1, + .pins[0] = 2, + .pins[1] = 6, + .pins[2] = 6, +}; + +static struct omap_board_config_kernel voiceblue_config[] = { + { OMAP_TAG_USB, &voiceblue_usb_config }, +}; + +static void __init voiceblue_init_irq(void) +{ + omap_init_irq(); + omap_gpio_init(); +} + +static void __init voiceblue_init(void) +{ + /* There is a good chance board is going up, so enable Power LED + * (it is connected through invertor) */ + omap_writeb(0x00, OMAP_LPG1_LCR); + /* Watchdog */ + omap_request_gpio(0); + /* smc91x reset */ + omap_request_gpio(7); + omap_set_gpio_direction(7, 0); + omap_set_gpio_dataout(7, 1); + udelay(2); /* wait at least 100ns */ + omap_set_gpio_dataout(7, 0); + mdelay(50); /* 50ms until PHY ready */ + /* smc91x interrupt pin */ + omap_request_gpio(8); + omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE); + /* 16C554 reset*/ + omap_request_gpio(6); + omap_set_gpio_direction(6, 0); + omap_set_gpio_dataout(6, 0); + /* 16C554 interrupt pins */ + omap_request_gpio(12); + omap_request_gpio(13); + omap_request_gpio(14); + omap_request_gpio(15); + omap_set_gpio_edge_ctrl(12, OMAP_GPIO_RISING_EDGE); + omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE); + omap_set_gpio_edge_ctrl(14, OMAP_GPIO_RISING_EDGE); + omap_set_gpio_edge_ctrl(15, OMAP_GPIO_RISING_EDGE); + + platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); + omap_board_config = voiceblue_config; + omap_board_config_size = ARRAY_SIZE(voiceblue_config); +} + +static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1}; + +static void __init voiceblue_map_io(void) +{ + omap_map_io(); + omap_serial_init(omap_serial_ports); +} + +#define MACHINE_PANICED 1 +#define MACHINE_REBOOTING 2 +#define MACHINE_REBOOT 4 +static unsigned long machine_state; + +static int panic_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + if (test_and_set_bit(MACHINE_PANICED, &machine_state)) + return NOTIFY_DONE; + + /* Flash Power LED + * (TODO: Enable clock right way (enabled in bootloader already)) */ + omap_writeb(0x78, OMAP_LPG1_LCR); + + return NOTIFY_DONE; +} + +static struct notifier_block panic_block = { + .notifier_call = panic_event, +}; + +static int __init setup_notifier(void) +{ + /* Setup panic notifier */ + notifier_chain_register(&panic_notifier_list, &panic_block); + + return 0; +} + +postcore_initcall(setup_notifier); + +static int wdt_gpio_state; + +void voiceblue_wdt_enable(void) +{ + omap_set_gpio_direction(0, 0); + omap_set_gpio_dataout(0, 0); + omap_set_gpio_dataout(0, 1); + omap_set_gpio_dataout(0, 0); + wdt_gpio_state = 0; +} + +void voiceblue_wdt_disable(void) +{ + omap_set_gpio_dataout(0, 0); + omap_set_gpio_dataout(0, 1); + omap_set_gpio_dataout(0, 0); + omap_set_gpio_direction(0, 1); +} + +void voiceblue_wdt_ping(void) +{ + if (test_bit(MACHINE_REBOOT, &machine_state)) + return; + + wdt_gpio_state = !wdt_gpio_state; + omap_set_gpio_dataout(0, wdt_gpio_state); +} + +void voiceblue_reset(void) +{ + set_bit(MACHINE_REBOOT, &machine_state); + voiceblue_wdt_enable(); + while (1) ; +} + +EXPORT_SYMBOL(voiceblue_wdt_enable); +EXPORT_SYMBOL(voiceblue_wdt_disable); +EXPORT_SYMBOL(voiceblue_wdt_ping); + +MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") + MAINTAINER("Ladislav Michl <michl@2n.cz>") + BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) + BOOT_PARAMS(0x10000100) + MAPIO(voiceblue_map_io) + INITIRQ(voiceblue_init_irq) + INIT_MACHINE(voiceblue_init) + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/mach-omap/clock.c b/arch/arm/mach-omap/clock.c new file mode 100644 index 0000000..e91186b --- /dev/null +++ b/arch/arm/mach-omap/clock.c @@ -0,0 +1,1076 @@ +/* + * linux/arch/arm/mach-omap/clock.c + * + * Copyright (C) 2004 Nokia corporation + * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> + +#include <asm/semaphore.h> +#include <asm/hardware/clock.h> +#include <asm/arch/board.h> +#include <asm/arch/usb.h> + +#include "clock.h" + +static LIST_HEAD(clocks); +static DECLARE_MUTEX(clocks_sem); +static DEFINE_SPINLOCK(clockfw_lock); +static void propagate_rate(struct clk * clk); +/* External clock (MCLK & BCLK) functions */ +static int set_ext_clk_rate(struct clk * clk, unsigned long rate); +static long round_ext_clk_rate(struct clk * clk, unsigned long rate); +static void init_ext_clk(struct clk * clk); +/* MPU virtual clock functions */ +static int select_table_rate(struct clk * clk, unsigned long rate); +static long round_to_table_rate(struct clk * clk, unsigned long rate); +void clk_setdpll(__u16, __u16); + +struct mpu_rate rate_table[] = { + /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL + * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv + */ +#if defined(CONFIG_OMAP_ARM_216MHZ) + { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_195MHZ) + { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_192MHZ) + { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ + { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ + { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ + { 48000000, 12000000, 192000000, 0x0ccf, 0x2810 }, /* 4/4/4/4/8/8 */ + { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_182MHZ) + { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_168MHZ) + { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ +#endif +#if defined(CONFIG_OMAP_ARM_150MHZ) + { 150000000, 12000000, 150000000, 0x150a, 0x2cb0 }, /* 0/0/1/1/2/2 */ +#endif +#if defined(CONFIG_OMAP_ARM_120MHZ) + { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ +#endif +#if defined(CONFIG_OMAP_ARM_96MHZ) + { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */ +#endif +#if defined(CONFIG_OMAP_ARM_60MHZ) + { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */ +#endif +#if defined(CONFIG_OMAP_ARM_30MHZ) + { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */ +#endif + { 0, 0, 0, 0, 0 }, +}; + + +static void ckctl_recalc(struct clk * clk) +{ + int dsor; + + /* Calculate divisor encoded as 2-bit exponent */ + dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); + if (unlikely(clk->rate == clk->parent->rate / dsor)) + return; /* No change, quick exit */ + clk->rate = clk->parent->rate / dsor; + + if (unlikely(clk->flags & RATE_PROPAGATES)) + propagate_rate(clk); +} + + +static void followparent_recalc(struct clk * clk) +{ + clk->rate = clk->parent->rate; +} + + +static void watchdog_recalc(struct clk * clk) +{ + clk->rate = clk->parent->rate / 14; +} + + +static struct clk ck_ref = { + .name = "ck_ref", + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + ALWAYS_ENABLED, +}; + +static struct clk ck_dpll1 = { + .name = "ck_dpll1", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_PROPAGATES | ALWAYS_ENABLED, +}; + +static struct clk ck_dpll1out = { + .name = "ck_dpll1out", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP16XX, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_CKOUT_ARM, + .recalc = &followparent_recalc, +}; + +static struct clk arm_ck = { + .name = "arm_ck", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, + .rate_offset = CKCTL_ARMDIV_OFFSET, + .recalc = &ckctl_recalc, +}; + +static struct clk armper_ck = { + .name = "armper_ck", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_PERCK, + .rate_offset = CKCTL_PERDIV_OFFSET, + .recalc = &ckctl_recalc, +}; + +static struct clk arm_gpio_ck = { + .name = "arm_gpio_ck", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP1510, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_GPIOCK, + .recalc = &followparent_recalc, +}; + +static struct clk armxor_ck = { + .name = "armxor_ck", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_XORPCK, + .recalc = &followparent_recalc, +}; + +static struct clk armtim_ck = { + .name = "armtim_ck", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_TIMCK, + .recalc = &followparent_recalc, +}; + +static struct clk armwdt_ck = { + .name = "armwdt_ck", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_WDTCK, + .recalc = &watchdog_recalc, +}; + +static struct clk arminth_ck16xx = { + .name = "arminth_ck", + .parent = &arm_ck, + .flags = CLOCK_IN_OMAP16XX, + .recalc = &followparent_recalc, + /* Note: On 16xx the frequency can be divided by 2 by programming + * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 + * + * 1510 version is in TC clocks. + */ +}; + +static struct clk dsp_ck = { + .name = "dsp_ck", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL, + .enable_reg = ARM_CKCTL, + .enable_bit = EN_DSPCK, + .rate_offset = CKCTL_DSPDIV_OFFSET, + .recalc = &ckctl_recalc, +}; + +static struct clk dspmmu_ck = { + .name = "dspmmu_ck", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL | ALWAYS_ENABLED, + .rate_offset = CKCTL_DSPMMUDIV_OFFSET, + .recalc = &ckctl_recalc, +}; + +static struct clk tc_ck = { + .name = "tc_ck", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | + RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, + .rate_offset = CKCTL_TCDIV_OFFSET, + .recalc = &ckctl_recalc, +}; + +static struct clk arminth_ck1510 = { + .name = "arminth_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510, + .recalc = &followparent_recalc, + /* Note: On 1510 the frequency follows TC_CK + * + * 16xx version is in MPU clocks. + */ +}; + +static struct clk tipb_ck = { + .name = "tibp_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510, + .recalc = &followparent_recalc, +}; + +static struct clk l3_ocpi_ck = { + .name = "l3_ocpi_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, + .enable_reg = ARM_IDLECT3, + .enable_bit = EN_OCPI_CK, + .recalc = &followparent_recalc, +}; + +static struct clk tc1_ck = { + .name = "tc1_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, + .enable_reg = ARM_IDLECT3, + .enable_bit = EN_TC1_CK, + .recalc = &followparent_recalc, +}; + +static struct clk tc2_ck = { + .name = "tc2_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, + .enable_reg = ARM_IDLECT3, + .enable_bit = EN_TC2_CK, + .recalc = &followparent_recalc, +}; + +static struct clk dma_ck = { + .name = "dma_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .recalc = &followparent_recalc, +}; + +static struct clk dma_lcdfree_ck = { + .name = "dma_lcdfree_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, + .recalc = &followparent_recalc, +}; + +static struct clk api_ck = { + .name = "api_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_APICK, + .recalc = &followparent_recalc, +}; + +static struct clk lb_ck = { + .name = "lb_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_LBCK, + .recalc = &followparent_recalc, +}; + +static struct clk rhea1_ck = { + .name = "rhea1_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, + .recalc = &followparent_recalc, +}; + +static struct clk rhea2_ck = { + .name = "rhea2_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, + .recalc = &followparent_recalc, +}; + +static struct clk lcd_ck = { + .name = "lcd_ck", + .parent = &ck_dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | + RATE_CKCTL, + .enable_reg = ARM_IDLECT2, + .enable_bit = EN_LCDCK, + .rate_offset = CKCTL_LCDDIV_OFFSET, + .recalc = &ckctl_recalc, +}; + +static struct clk uart1_ck = { + .name = "uart1_ck", + /* Direct from ULPD, no parent */ + .rate = 48000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = MOD_CONF_CTRL_0, + .enable_bit = 29, + /* (Only on 1510) + * The "enable bit" actually chooses between 48MHz and 12MHz. + */ +}; + +static struct clk uart2_ck = { + .name = "uart2_ck", + /* Direct from ULPD, no parent */ + .rate = 48000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = MOD_CONF_CTRL_0, + .enable_bit = 30, + /* (for both 1510 and 16xx) + * The "enable bit" actually chooses between 48MHz and 12MHz/32kHz. + */ +}; + +static struct clk uart3_ck = { + .name = "uart3_ck", + /* Direct from ULPD, no parent */ + .rate = 48000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = MOD_CONF_CTRL_0, + .enable_bit = 31, + /* (Only on 1510) + * The "enable bit" actually chooses between 48MHz and 12MHz. + */ +}; + +static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ + .name = "usb_clko", + /* Direct from ULPD, no parent */ + .rate = 6000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = ULPD_CLOCK_CTRL, + .enable_bit = USB_MCLK_EN_BIT, +}; + +static struct clk usb_hhc_ck1510 = { + .name = "usb_hhc_ck", + /* Direct from ULPD, no parent */ + .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ + .flags = CLOCK_IN_OMAP1510 | + RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = MOD_CONF_CTRL_0, + .enable_bit = USB_HOST_HHC_UHOST_EN, +}; + +static struct clk usb_hhc_ck16xx = { + .name = "usb_hhc_ck", + /* Direct from ULPD, no parent */ + .rate = 48000000, + /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ + .flags = CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = OTG_BASE + 0x08 /* OTG_SYSCON_2 */, + .enable_bit = 8 /* UHOST_EN */, +}; + +static struct clk mclk_1510 = { + .name = "mclk", + /* Direct from ULPD, no parent. May be enabled by ext hardware. */ + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, +}; + +static struct clk mclk_16xx = { + .name = "mclk", + /* Direct from ULPD, no parent. May be enabled by ext hardware. */ + .flags = CLOCK_IN_OMAP16XX, + .enable_reg = COM_CLK_DIV_CTRL_SEL, + .enable_bit = COM_ULPD_PLL_CLK_REQ, + .set_rate = &set_ext_clk_rate, + .round_rate = &round_ext_clk_rate, + .init = &init_ext_clk, +}; + +static struct clk bclk_1510 = { + .name = "bclk", + /* Direct from ULPD, no parent. May be enabled by ext hardware. */ + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, +}; + +static struct clk bclk_16xx = { + .name = "bclk", + /* Direct from ULPD, no parent. May be enabled by ext hardware. */ + .flags = CLOCK_IN_OMAP16XX, + .enable_reg = SWD_CLK_DIV_CTRL_SEL, + .enable_bit = SWD_ULPD_PLL_CLK_REQ, + .set_rate = &set_ext_clk_rate, + .round_rate = &round_ext_clk_rate, + .init = &init_ext_clk, +}; + +static struct clk mmc1_ck = { + .name = "mmc1_ck", + /* Functional clock is direct from ULPD, interface clock is ARMPER */ + .parent = &armper_ck, + .rate = 48000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = MOD_CONF_CTRL_0, + .enable_bit = 23, +}; + +static struct clk mmc2_ck = { + .name = "mmc2_ck", + /* Functional clock is direct from ULPD, interface clock is ARMPER */ + .parent = &armper_ck, + .rate = 48000000, + .flags = CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, + .enable_reg = MOD_CONF_CTRL_0, + .enable_bit = 20, +}; + +static struct clk virtual_ck_mpu = { + .name = "mpu", + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + VIRTUAL_CLOCK | ALWAYS_ENABLED, + .parent = &arm_ck, /* Is smarter alias for */ + .recalc = &followparent_recalc, + .set_rate = &select_table_rate, + .round_rate = &round_to_table_rate, +}; + + +static struct clk * onchip_clks[] = { + /* non-ULPD clocks */ + &ck_ref, + &ck_dpll1, + /* CK_GEN1 clocks */ + &ck_dpll1out, + &arm_ck, + &armper_ck, + &arm_gpio_ck, + &armxor_ck, + &armtim_ck, + &armwdt_ck, + &arminth_ck1510, &arminth_ck16xx, + /* CK_GEN2 clocks */ + &dsp_ck, + &dspmmu_ck, + /* CK_GEN3 clocks */ + &tc_ck, + &tipb_ck, + &l3_ocpi_ck, + &tc1_ck, + &tc2_ck, + &dma_ck, + &dma_lcdfree_ck, + &api_ck, + &lb_ck, + &rhea1_ck, + &rhea2_ck, + &lcd_ck, + /* ULPD clocks */ + &uart1_ck, + &uart2_ck, + &uart3_ck, + &usb_clko, + &usb_hhc_ck1510, &usb_hhc_ck16xx, + &mclk_1510, &mclk_16xx, + &bclk_1510, &bclk_16xx, + &mmc1_ck, + &mmc2_ck, + /* Virtual clocks */ + &virtual_ck_mpu, +}; + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + down(&clocks_sem); + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + break; + } + } + up(&clocks_sem); + + return clk; +} +EXPORT_SYMBOL(clk_get); + + +void clk_put(struct clk *clk) +{ + if (clk && !IS_ERR(clk)) + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + + +int __clk_enable(struct clk *clk) +{ + __u16 regval16; + __u32 regval32; + + if (clk->flags & ALWAYS_ENABLED) + return 0; + + if (unlikely(clk->enable_reg == 0)) { + printk(KERN_ERR "clock.c: Enable for %s without enable code\n", + clk->name); + return 0; + } + + if (clk->flags & ENABLE_REG_32BIT) { + regval32 = omap_readl(clk->enable_reg); + regval32 |= (1 << clk->enable_bit); + omap_writel(regval32, clk->enable_reg); + } else { + regval16 = omap_readw(clk->enable_reg); + regval16 |= (1 << clk->enable_bit); + omap_writew(regval16, clk->enable_reg); + } + + return 0; +} + + +void __clk_disable(struct clk *clk) +{ + __u16 regval16; + __u32 regval32; + + if (clk->enable_reg == 0) + return; + + if (clk->flags & ENABLE_REG_32BIT) { + regval32 = omap_readl(clk->enable_reg); + regval32 &= ~(1 << clk->enable_bit); + omap_writel(regval32, clk->enable_reg); + } else { + regval16 = omap_readw(clk->enable_reg); + regval16 &= ~(1 << clk->enable_bit); + omap_writew(regval16, clk->enable_reg); + } +} + + +void __clk_unuse(struct clk *clk) +{ + if (clk->usecount > 0 && !(--clk->usecount)) { + __clk_disable(clk); + if (likely(clk->parent)) + __clk_unuse(clk->parent); + } +} + + +int __clk_use(struct clk *clk) +{ + int ret = 0; + if (clk->usecount++ == 0) { + if (likely(clk->parent)) + ret = __clk_use(clk->parent); + + if (unlikely(ret != 0)) { + clk->usecount--; + return ret; + } + + ret = __clk_enable(clk); + + if (unlikely(ret != 0) && clk->parent) { + __clk_unuse(clk->parent); + clk->usecount--; + } + } + + return ret; +} + + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&clockfw_lock, flags); + ret = __clk_enable(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + return ret; +} +EXPORT_SYMBOL(clk_enable); + + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + + spin_lock_irqsave(&clockfw_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + + +int clk_use(struct clk *clk) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&clockfw_lock, flags); + ret = __clk_use(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); + return ret; +} +EXPORT_SYMBOL(clk_use); + + +void clk_unuse(struct clk *clk) +{ + unsigned long flags; + + spin_lock_irqsave(&clockfw_lock, flags); + __clk_unuse(clk); + spin_unlock_irqrestore(&clockfw_lock, flags); +} +EXPORT_SYMBOL(clk_unuse); + + +int clk_get_usecount(struct clk *clk) +{ + return clk->usecount; +} +EXPORT_SYMBOL(clk_get_usecount); + + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + + +static __u16 verify_ckctl_value(__u16 newval) +{ + /* This function checks for following limitations set + * by the hardware (all conditions must be true): + * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2 + * ARM_CK >= TC_CK + * DSP_CK >= TC_CK + * DSPMMU_CK >= TC_CK + * + * In addition following rules are enforced: + * LCD_CK <= TC_CK + * ARMPER_CK <= TC_CK + * + * However, maximum frequencies are not checked for! + */ + __u8 per_exp; + __u8 lcd_exp; + __u8 arm_exp; + __u8 dsp_exp; + __u8 tc_exp; + __u8 dspmmu_exp; + + per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3; + lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3; + arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3; + dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3; + tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3; + dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3; + + if (dspmmu_exp < dsp_exp) + dspmmu_exp = dsp_exp; + if (dspmmu_exp > dsp_exp+1) + dspmmu_exp = dsp_exp+1; + if (tc_exp < arm_exp) + tc_exp = arm_exp; + if (tc_exp < dspmmu_exp) + tc_exp = dspmmu_exp; + if (tc_exp > lcd_exp) + lcd_exp = tc_exp; + if (tc_exp > per_exp) + per_exp = tc_exp; + + newval &= 0xf000; + newval |= per_exp << CKCTL_PERDIV_OFFSET; + newval |= lcd_exp << CKCTL_LCDDIV_OFFSET; + newval |= arm_exp << CKCTL_ARMDIV_OFFSET; + newval |= dsp_exp << CKCTL_DSPDIV_OFFSET; + newval |= tc_exp << CKCTL_TCDIV_OFFSET; + newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET; + + return newval; +} + + +static int calc_dsor_exp(struct clk *clk, unsigned long rate) +{ + /* Note: If target frequency is too low, this function will return 4, + * which is invalid value. Caller must check for this value and act + * accordingly. + * + * Note: This function does not check for following limitations set + * by the hardware (all conditions must be true): + * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2 + * ARM_CK >= TC_CK + * DSP_CK >= TC_CK + * DSPMMU_CK >= TC_CK + */ + unsigned long realrate; + struct clk * parent; + unsigned dsor_exp; + + if (unlikely(!(clk->flags & RATE_CKCTL))) + return -EINVAL; + + parent = clk->parent; + if (unlikely(parent == 0)) + return -EIO; + + realrate = parent->rate; + for (dsor_exp=0; dsor_exp<4; dsor_exp++) { + if (realrate <= rate) + break; + + realrate /= 2; + } + + return dsor_exp; +} + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + int dsor_exp; + + if (clk->flags & RATE_FIXED) + return clk->rate; + + if (clk->flags & RATE_CKCTL) { + dsor_exp = calc_dsor_exp(clk, rate); + if (dsor_exp < 0) + return dsor_exp; + if (dsor_exp > 3) + dsor_exp = 3; + return clk->parent->rate / (1 << dsor_exp); + } + + if(clk->round_rate != 0) + return clk->round_rate(clk, rate); + + return clk->rate; +} +EXPORT_SYMBOL(clk_round_rate); + + +static void propagate_rate(struct clk * clk) +{ + struct clk ** clkp; + + for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) { + if (likely((*clkp)->parent != clk)) continue; + if (likely((*clkp)->recalc)) + (*clkp)->recalc(*clkp); + } +} + + +static int select_table_rate(struct clk * clk, unsigned long rate) +{ + /* Find the highest supported frequency <= rate and switch to it */ + struct mpu_rate * ptr; + + if (clk != &virtual_ck_mpu) + return -EINVAL; + + for (ptr = rate_table; ptr->rate; ptr++) { + if (ptr->xtal != ck_ref.rate) + continue; + + /* DPLL1 cannot be reprogrammed without risking system crash */ + if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate) + continue; + + /* Can check only after xtal frequency check */ + if (ptr->rate <= rate) + break; + } + + if (!ptr->rate) + return -EINVAL; + + if (unlikely(ck_dpll1.rate == 0)) { + omap_writew(ptr->dpllctl_val, DPLL_CTL); + ck_dpll1.rate = ptr->pll_rate; + } + omap_writew(ptr->ckctl_val, ARM_CKCTL); + propagate_rate(&ck_dpll1); + return 0; +} + + +static long round_to_table_rate(struct clk * clk, unsigned long rate) +{ + /* Find the highest supported frequency <= rate */ + struct mpu_rate * ptr; + long highest_rate; + + if (clk != &virtual_ck_mpu) + return -EINVAL; + + highest_rate = -EINVAL; + + for (ptr = rate_table; ptr->rate; ptr++) { + if (ptr->xtal != ck_ref.rate) + continue; + + highest_rate = ptr->rate; + + /* Can check only after xtal frequency check */ + if (ptr->rate <= rate) + break; + } + + return highest_rate; +} + + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EINVAL; + int dsor_exp; + __u16 regval; + unsigned long flags; + + if (clk->flags & RATE_CKCTL) { + dsor_exp = calc_dsor_exp(clk, rate); + if (dsor_exp > 3) + dsor_exp = -EINVAL; + if (dsor_exp < 0) + return dsor_exp; + + spin_lock_irqsave(&clockfw_lock, flags); + regval = omap_readw(ARM_CKCTL); + regval &= ~(3 << clk->rate_offset); + regval |= dsor_exp << clk->rate_offset; + regval = verify_ckctl_value(regval); + omap_writew(regval, ARM_CKCTL); + clk->rate = clk->parent->rate / (1 << dsor_exp); + spin_unlock_irqrestore(&clockfw_lock, flags); + ret = 0; + } else if(clk->set_rate != 0) { + spin_lock_irqsave(&clockfw_lock, flags); + ret = clk->set_rate(clk, rate); + spin_unlock_irqrestore(&clockfw_lock, flags); + } + + if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) + propagate_rate(clk); + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + + +static unsigned calc_ext_dsor(unsigned long rate) +{ + unsigned dsor; + + /* MCLK and BCLK divisor selection is not linear: + * freq = 96MHz / dsor + * + * RATIO_SEL range: dsor <-> RATIO_SEL + * 0..6: (RATIO_SEL+2) <-> (dsor-2) + * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6) + * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9 + * can not be used. + */ + for (dsor = 2; dsor < 96; ++dsor) { + if ((dsor & 1) && dsor > 8) + continue; + if (rate >= 96000000 / dsor) + break; + } + return dsor; +} + + +static int set_ext_clk_rate(struct clk * clk, unsigned long rate) +{ + unsigned dsor; + __u16 ratio_bits; + + dsor = calc_ext_dsor(rate); + clk->rate = 96000000 / dsor; + if (dsor > 8) + ratio_bits = ((dsor - 8) / 2 + 6) << 2; + else + ratio_bits = (dsor - 2) << 2; + + ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd; + omap_writew(ratio_bits, clk->enable_reg); + + return 0; +} + + +static long round_ext_clk_rate(struct clk * clk, unsigned long rate) +{ + return 96000000 / calc_ext_dsor(rate); +} + + +static void init_ext_clk(struct clk * clk) +{ + unsigned dsor; + __u16 ratio_bits; + + /* Determine current rate and ensure clock is based on 96MHz APLL */ + ratio_bits = omap_readw(clk->enable_reg) & ~1; + omap_writew(ratio_bits, clk->enable_reg); + + ratio_bits = (ratio_bits & 0xfc) >> 2; + if (ratio_bits > 6) + dsor = (ratio_bits - 6) * 2 + 8; + else + dsor = ratio_bits + 2; + + clk-> rate = 96000000 / dsor; +} + + +int clk_register(struct clk *clk) +{ + down(&clocks_sem); + list_add(&clk->node, &clocks); + if (clk->init) + clk->init(clk); + up(&clocks_sem); + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + down(&clocks_sem); + list_del(&clk->node); + up(&clocks_sem); +} +EXPORT_SYMBOL(clk_unregister); + + + +int __init clk_init(void) +{ + struct clk ** clkp; + const struct omap_clock_config *info; + int crystal_type = 0; /* Default 12 MHz */ + + for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) { + if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) { + clk_register(*clkp); + continue; + } + + if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) { + clk_register(*clkp); + continue; + } + + if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) { + clk_register(*clkp); + continue; + } + } + + info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); + if (info != NULL) { + if (!cpu_is_omap1510()) + crystal_type = info->system_clock_type; + } + +#if defined(CONFIG_ARCH_OMAP730) + ck_ref.rate = 13000000; +#elif defined(CONFIG_ARCH_OMAP16XX) + if (crystal_type == 2) + ck_ref.rate = 19200000; +#endif + + /* We want to be in syncronous scalable mode */ + omap_writew(0x1000, ARM_SYSST); + + /* Find the highest supported frequency and enable it */ + if (select_table_rate(&virtual_ck_mpu, ~0)) { + printk(KERN_ERR "System frequencies not set. Check your config.\n"); + /* Guess sane values (60MHz) */ + omap_writew(0x2290, DPLL_CTL); + omap_writew(0x1005, ARM_CKCTL); + ck_dpll1.rate = 60000000; + propagate_rate(&ck_dpll1); + printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld/%ld/%ld\n", + ck_ref.rate, ck_dpll1.rate, arm_ck.rate); + } + + /* Cache rates for clocks connected to ck_ref (not dpll1) */ + propagate_rate(&ck_ref); + +#ifdef CONFIG_MACH_OMAP_PERSEUS2 + /* Select slicer output as OMAP input clock */ + omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); +#endif + + /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ + omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL); + + /* Put DSP/MPUI into reset until needed */ + omap_writew(0, ARM_RSTCT1); + omap_writew(1, ARM_RSTCT2); + omap_writew(0x400, ARM_IDLECT1); + + /* + * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8) + * of the ARM_IDLECT2 register must be set to zero. The power-on + * default value of this bit is one. + */ + omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */ + + /* + * Only enable those clocks we will need, let the drivers + * enable other clocks as necessary + */ + clk_use(&armper_ck); + clk_use(&armxor_ck); + clk_use(&armtim_ck); + + if (cpu_is_omap1510()) + clk_enable(&arm_gpio_ck); + + return 0; +} diff --git a/arch/arm/mach-omap/clock.h b/arch/arm/mach-omap/clock.h new file mode 100644 index 0000000..08c0ddd --- /dev/null +++ b/arch/arm/mach-omap/clock.h @@ -0,0 +1,112 @@ +/* + * linux/arch/arm/mach-omap/clock.h + * + * Copyright (C) 2004 Nokia corporation + * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> + * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc + * + * 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. + */ + +#ifndef __ARCH_ARM_OMAP_CLOCK_H +#define __ARCH_ARM_OMAP_CLOCK_H + +struct module; + +struct clk { + struct list_head node; + struct module *owner; + const char *name; + struct clk *parent; + unsigned long rate; + __s8 usecount; + __u16 flags; + __u32 enable_reg; + __u8 enable_bit; + __u8 rate_offset; + void (*recalc)(struct clk *); + int (*set_rate)(struct clk *, unsigned long); + long (*round_rate)(struct clk *, unsigned long); + void (*init)(struct clk *); +}; + + +struct mpu_rate { + unsigned long rate; + unsigned long xtal; + unsigned long pll_rate; + __u16 ckctl_val; + __u16 dpllctl_val; +}; + + +/* Clock flags */ +#define RATE_CKCTL 1 +#define RATE_FIXED 2 +#define RATE_PROPAGATES 4 +#define VIRTUAL_CLOCK 8 +#define ALWAYS_ENABLED 16 +#define ENABLE_REG_32BIT 32 +#define CLOCK_IN_OMAP16XX 64 +#define CLOCK_IN_OMAP1510 128 +#define CLOCK_IN_OMAP730 256 + +/* ARM_CKCTL bit shifts */ +#define CKCTL_PERDIV_OFFSET 0 +#define CKCTL_LCDDIV_OFFSET 2 +#define CKCTL_ARMDIV_OFFSET 4 +#define CKCTL_DSPDIV_OFFSET 6 +#define CKCTL_TCDIV_OFFSET 8 +#define CKCTL_DSPMMUDIV_OFFSET 10 +/*#define ARM_TIMXO 12*/ +#define EN_DSPCK 13 +/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */ + +/* ARM_IDLECT1 bit shifts */ +/*#define IDLWDT_ARM 0*/ +/*#define IDLXORP_ARM 1*/ +/*#define IDLPER_ARM 2*/ +/*#define IDLLCD_ARM 3*/ +/*#define IDLLB_ARM 4*/ +/*#define IDLHSAB_ARM 5*/ +/*#define IDLIF_ARM 6*/ +/*#define IDLDPLL_ARM 7*/ +/*#define IDLAPI_ARM 8*/ +/*#define IDLTIM_ARM 9*/ +/*#define SETARM_IDLE 11*/ + +/* ARM_IDLECT2 bit shifts */ +#define EN_WDTCK 0 +#define EN_XORPCK 1 +#define EN_PERCK 2 +#define EN_LCDCK 3 +#define EN_LBCK 4 /* Not on 1610/1710 */ +/*#define EN_HSABCK 5*/ +#define EN_APICK 6 +#define EN_TIMCK 7 +#define DMACK_REQ 8 +#define EN_GPIOCK 9 /* Not on 1610/1710 */ +/*#define EN_LBFREECK 10*/ +#define EN_CKOUT_ARM 11 + +/* ARM_IDLECT3 bit shifts */ +#define EN_OCPI_CK 0 +#define EN_TC1_CK 2 +#define EN_TC2_CK 4 + +/* Various register defines for clock controls scattered around OMAP chip */ +#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ +#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ +#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ +#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */ +#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874 +#define COM_CLK_DIV_CTRL_SEL 0xfffe0878 + + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); +int clk_init(void); + +#endif diff --git a/arch/arm/mach-omap/common.c b/arch/arm/mach-omap/common.c new file mode 100644 index 0000000..265cde4 --- /dev/null +++ b/arch/arm/mach-omap/common.c @@ -0,0 +1,549 @@ +/* + * linux/arch/arm/mach-omap/common.c + * + * Code common to all OMAP machines. + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/console.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> +#include <linux/serial_reg.h> + +#include <asm/hardware.h> +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/mach/map.h> +#include <asm/hardware/clock.h> +#include <asm/io.h> +#include <asm/mach-types.h> + +#include <asm/arch/board.h> +#include <asm/arch/mux.h> +#include <asm/arch/fpga.h> + +#include "clock.h" + +#define DEBUG 1 + +struct omap_id { + u16 jtag_id; /* Used to determine OMAP type */ + u8 die_rev; /* Processor revision */ + u32 omap_id; /* OMAP revision */ + u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */ +}; + +/* Register values to detect the OMAP version */ +static struct omap_id omap_ids[] __initdata = { + { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, + { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, + { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, + { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000}, + { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000}, + { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00}, + { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00}, + { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, + { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, + { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000}, + { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00}, + { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00}, + { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300}, + { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300}, + { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300}, + { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000}, + { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000}, + { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000}, +}; + +/* + * Get OMAP type from PROD_ID. + * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM. + * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense. + * Undocumented register in TEST BLOCK is used as fallback; This seems to + * work on 1510, 1610 & 1710. The official way hopefully will work in future + * processors. + */ +static u16 __init omap_get_jtag_id(void) +{ + u32 prod_id, omap_id; + + prod_id = omap_readl(OMAP_PRODUCTION_ID_1); + omap_id = omap_readl(OMAP32_ID_1); + + /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */ + if (((prod_id >> 20) == 0) || (prod_id == omap_id)) + prod_id = 0; + else + prod_id &= 0xffff; + + if (prod_id) + return prod_id; + + /* Use OMAP32_ID_1 as fallback */ + prod_id = ((omap_id >> 12) & 0xffff); + + return prod_id; +} + +/* + * Get OMAP revision from DIE_REV. + * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID. + * Undocumented register in the TEST BLOCK is used as fallback. + * REVISIT: This does not seem to work on 1510 + */ +static u8 __init omap_get_die_rev(void) +{ + u32 die_rev; + + die_rev = omap_readl(OMAP_DIE_ID_1); + + /* Check for broken OMAP_DIE_ID on early 1710 */ + if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id()) + die_rev = 0; + + die_rev = (die_rev >> 17) & 0xf; + if (die_rev) + return die_rev; + + die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf; + + return die_rev; +} + +static void __init omap_check_revision(void) +{ + int i; + u16 jtag_id; + u8 die_rev; + u32 omap_id; + u8 cpu_type; + + jtag_id = omap_get_jtag_id(); + die_rev = omap_get_die_rev(); + omap_id = omap_readl(OMAP32_ID_0); + +#ifdef DEBUG + printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0)); + printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n", + omap_readl(OMAP_DIE_ID_1), + (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf); + printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0)); + printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n", + omap_readl(OMAP_PRODUCTION_ID_1), + omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff); + printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0)); + printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1)); + printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev); +#endif + + system_serial_high = omap_readl(OMAP_DIE_ID_0); + system_serial_low = omap_readl(OMAP_DIE_ID_1); + + /* First check only the major version in a safe way */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == (omap_ids[i].jtag_id)) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Check if we can find the die revision */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Finally check also the omap_id */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == omap_ids[i].jtag_id + && die_rev == omap_ids[i].die_rev + && omap_id == omap_ids[i].omap_id) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */ + cpu_type = system_rev >> 24; + + switch (cpu_type) { + case 0x07: + system_rev |= 0x07; + break; + case 0x15: + system_rev |= 0x15; + break; + case 0x16: + case 0x17: + system_rev |= 0x16; + break; + case 0x24: + system_rev |= 0x24; + break; + default: + printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type); + } + + printk("OMAP%04x", system_rev >> 16); + if ((system_rev >> 8) & 0xff) + printk("%x", (system_rev >> 8) & 0xff); + printk(" revision %i handled as %02xxx id: %08x%08x\n", + die_rev, system_rev & 0xff, system_serial_low, + system_serial_high); +} + +/* + * ---------------------------------------------------------------------------- + * OMAP I/O mapping + * + * The machine specific code may provide the extra mapping besides the + * default mapping provided here. + * ---------------------------------------------------------------------------- + */ + +static struct map_desc omap_io_desc[] __initdata = { + { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, +}; + +#ifdef CONFIG_ARCH_OMAP730 +static struct map_desc omap730_io_desc[] __initdata = { + { OMAP730_DSP_BASE, OMAP730_DSP_START, OMAP730_DSP_SIZE, MT_DEVICE }, + { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE }, + { OMAP730_SRAM_BASE, OMAP730_SRAM_START, OMAP730_SRAM_SIZE, MT_DEVICE } +}; +#endif + +#ifdef CONFIG_ARCH_OMAP1510 +static struct map_desc omap1510_io_desc[] __initdata = { + { OMAP1510_DSP_BASE, OMAP1510_DSP_START, OMAP1510_DSP_SIZE, MT_DEVICE }, + { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE }, + { OMAP1510_SRAM_BASE, OMAP1510_SRAM_START, OMAP1510_SRAM_SIZE, MT_DEVICE } +}; +#endif + +#if defined(CONFIG_ARCH_OMAP16XX) +static struct map_desc omap1610_io_desc[] __initdata = { + { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE }, + { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE }, + { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP1610_SRAM_SIZE, MT_DEVICE } +}; + +static struct map_desc omap5912_io_desc[] __initdata = { + { OMAP16XX_DSP_BASE, OMAP16XX_DSP_START, OMAP16XX_DSP_SIZE, MT_DEVICE }, + { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE }, +/* + * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page + * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped. + * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte + * can be used. + */ + { OMAP16XX_SRAM_BASE, OMAP16XX_SRAM_START, OMAP5912_SRAM_SIZE + 0x800, MT_DEVICE } +}; +#endif + +static int initialized = 0; + +static void __init _omap_map_io(void) +{ + initialized = 1; + + /* We have to initialize the IO space mapping before we can run + * cpu_is_omapxxx() macros. */ + iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); + omap_check_revision(); + +#ifdef CONFIG_ARCH_OMAP730 + if (cpu_is_omap730()) { + iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc)); + } +#endif +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (cpu_is_omap1610() || cpu_is_omap1710()) { + iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc)); + } + if (cpu_is_omap5912()) { + iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc)); + } +#endif + + /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort + * on a Posted Write in the TIPB Bridge". + */ + omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL); + omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL); + + /* Must init clocks early to assure that timer interrupt works + */ + clk_init(); +} + +/* + * This should only get called from board specific init + */ +void omap_map_io(void) +{ + if (!initialized) + _omap_map_io(); +} + +static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, + int offset) +{ + offset <<= up->regshift; + return (unsigned int)__raw_readb(up->membase + offset); +} + +static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset, + int value) +{ + offset <<= p->regshift; + __raw_writeb(value, p->membase + offset); +} + +/* + * Internal UARTs need to be initialized for the 8250 autoconfig to work + * properly. Note that the TX watermark initialization may not be needed + * once the 8250.c watermark handling code is merged. + */ +static void __init omap_serial_reset(struct plat_serial8250_port *p) +{ + omap_serial_outp(p, UART_OMAP_MDR1, 0x07); /* disable UART */ + omap_serial_outp(p, UART_OMAP_SCR, 0x08); /* TX watermark */ + omap_serial_outp(p, UART_OMAP_MDR1, 0x00); /* enable UART */ + + if (!cpu_is_omap1510()) { + omap_serial_outp(p, UART_OMAP_SYSC, 0x01); + while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01)); + } +} + +static struct plat_serial8250_port serial_platform_data[] = { + { + .membase = (char*)IO_ADDRESS(OMAP_UART1_BASE), + .mapbase = (unsigned long)OMAP_UART1_BASE, + .irq = INT_UART1, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { + .membase = (char*)IO_ADDRESS(OMAP_UART2_BASE), + .mapbase = (unsigned long)OMAP_UART2_BASE, + .irq = INT_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { + .membase = (char*)IO_ADDRESS(OMAP_UART3_BASE), + .mapbase = (unsigned long)OMAP_UART3_BASE, + .irq = INT_UART3, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP16XX_BASE_BAUD * 16, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +/* + * Note that on Innovator-1510 UART2 pins conflict with USB2. + * By default UART2 does not work on Innovator-1510 if you have + * USB OHCI enabled. To use UART2, you must disable USB2 first. + */ +void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) +{ + int i; + + if (cpu_is_omap730()) { + serial_platform_data[0].regshift = 0; + serial_platform_data[1].regshift = 0; + serial_platform_data[0].irq = INT_730_UART_MODEM_1; + serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2; + } + + if (cpu_is_omap1510()) { + serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; + } + + for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { + unsigned char reg; + + if (ports[i] == 0) { + serial_platform_data[i].membase = 0; + serial_platform_data[i].mapbase = 0; + continue; + } + + switch (i) { + case 0: + if (cpu_is_omap1510()) { + omap_cfg_reg(UART1_TX); + omap_cfg_reg(UART1_RTS); + if (machine_is_omap_innovator()) { + reg = fpga_read(OMAP1510_FPGA_POWER); + reg |= OMAP1510_FPGA_PCR_COM1_EN; + fpga_write(reg, OMAP1510_FPGA_POWER); + udelay(10); + } + } + break; + case 1: + if (cpu_is_omap1510()) { + omap_cfg_reg(UART2_TX); + omap_cfg_reg(UART2_RTS); + if (machine_is_omap_innovator()) { + reg = fpga_read(OMAP1510_FPGA_POWER); + reg |= OMAP1510_FPGA_PCR_COM2_EN; + fpga_write(reg, OMAP1510_FPGA_POWER); + udelay(10); + } + } + break; + case 2: + if (cpu_is_omap1510()) { + omap_cfg_reg(UART3_TX); + omap_cfg_reg(UART3_RX); + } + if (cpu_is_omap1710()) { + clk_enable(clk_get(0, "uart3_ck")); + } + break; + } + omap_serial_reset(&serial_platform_data[i]); + } +} + +static int __init omap_init(void) +{ + return platform_device_register(&serial_device); +} +arch_initcall(omap_init); + +#define NO_LENGTH_CHECK 0xffffffff + +extern int omap_bootloader_tag_len; +extern u8 omap_bootloader_tag[]; + +struct omap_board_config_kernel *omap_board_config; +int omap_board_config_size = 0; + +static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out) +{ + struct omap_board_config_kernel *kinfo = NULL; + int i; + +#ifdef CONFIG_OMAP_BOOT_TAG + struct omap_board_config_entry *info = NULL; + + if (omap_bootloader_tag_len > 4) + info = (struct omap_board_config_entry *) omap_bootloader_tag; + while (info != NULL) { + u8 *next; + + if (info->tag == tag) { + if (skip == 0) + break; + skip--; + } + + if ((info->len & 0x03) != 0) { + /* We bail out to avoid an alignment fault */ + printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n", + info->len, info->tag); + return NULL; + } + next = (u8 *) info + sizeof(*info) + info->len; + if (next >= omap_bootloader_tag + omap_bootloader_tag_len) + info = NULL; + else + info = (struct omap_board_config_entry *) next; + } + if (info != NULL) { + /* Check the length as a lame attempt to check for + * binary inconsistancy. */ + if (len != NO_LENGTH_CHECK) { + /* Word-align len */ + if (len & 0x03) + len = (len + 3) & ~0x03; + if (info->len != len) { + printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n", + tag, len, info->len); + return NULL; + } + } + if (len_out != NULL) + *len_out = info->len; + return info->data; + } +#endif + /* Try to find the config from the board-specific structures + * in the kernel. */ + for (i = 0; i < omap_board_config_size; i++) { + if (omap_board_config[i].tag == tag) { + kinfo = &omap_board_config[i]; + break; + } + } + if (kinfo == NULL) + return NULL; + return kinfo->data; +} + +const void *__omap_get_config(u16 tag, size_t len, int nr) +{ + return get_config(tag, len, nr, NULL); +} +EXPORT_SYMBOL(__omap_get_config); + +const void *omap_get_var_config(u16 tag, size_t *len) +{ + return get_config(tag, NO_LENGTH_CHECK, 0, len); +} +EXPORT_SYMBOL(omap_get_var_config); + +static int __init omap_add_serial_console(void) +{ + const struct omap_uart_config *info; + + info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); + if (info != NULL && info->console_uart) { + static char speed[11], *opt = NULL; + + if (info->console_speed) { + snprintf(speed, sizeof(speed), "%u", info->console_speed); + opt = speed; + } + return add_preferred_console("ttyS", info->console_uart - 1, opt); + } + return 0; +} +console_initcall(omap_add_serial_console); diff --git a/arch/arm/mach-omap/common.h b/arch/arm/mach-omap/common.h new file mode 100644 index 0000000..9f62858 --- /dev/null +++ b/arch/arm/mach-omap/common.h @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/mach-omap/common.h + * + * Header for code common to all OMAP machines. + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H +#define __ARCH_ARM_MACH_OMAP_COMMON_H + +struct sys_timer; + +extern void omap_map_io(void); +extern struct sys_timer omap_timer; +extern void omap_serial_init(int ports[]); + +#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff --git a/arch/arm/mach-omap/dma.c b/arch/arm/mach-omap/dma.c new file mode 100644 index 0000000..7a9ebe8 --- /dev/null +++ b/arch/arm/mach-omap/dma.c @@ -0,0 +1,1086 @@ +/* + * linux/arch/arm/omap/dma.c + * + * Copyright (C) 2003 Nokia Corporation + * Author: Juha Yrjölä <juha.yrjola@nokia.com> + * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> + * Graphics DMA and LCD DMA graphics tranformations + * by Imre Deak <imre.deak@nokia.com> + * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. + * + * Support functions for the OMAP internal DMA channels. + * + * 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/module.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <linux/errno.h> +#include <linux/interrupt.h> + +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/dma.h> +#include <asm/io.h> + +#include <asm/arch/tc.h> + +#define OMAP_DMA_ACTIVE 0x01 + +#define OMAP_DMA_CCR_EN (1 << 7) + +#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) + +static int enable_1510_mode = 0; + +struct omap_dma_lch { + int next_lch; + int dev_id; + u16 saved_csr; + u16 enabled_irqs; + const char *dev_name; + void (* callback)(int lch, u16 ch_status, void *data); + void *data; + long flags; +}; + +static int dma_chan_count; + +static spinlock_t dma_chan_lock; +static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT]; + +const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { + INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, + INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, + INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, + INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13, + INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD +}; + +static inline int get_gdma_dev(int req) +{ + u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4; + int shift = ((req - 1) % 5) * 6; + + return ((omap_readl(reg) >> shift) & 0x3f) + 1; +} + +static inline void set_gdma_dev(int req, int dev) +{ + u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4; + int shift = ((req - 1) % 5) * 6; + u32 l; + + l = omap_readl(reg); + l &= ~(0x3f << shift); + l |= (dev - 1) << shift; + omap_writel(l, reg); +} + +static void clear_lch_regs(int lch) +{ + int i; + u32 lch_base = OMAP_DMA_BASE + lch * 0x40; + + for (i = 0; i < 0x2c; i += 2) + omap_writew(0, lch_base + i); +} + +void omap_set_dma_priority(int dst_port, int priority) +{ + unsigned long reg; + u32 l; + + switch (dst_port) { + case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ + reg = OMAP_TC_OCPT1_PRIOR; + break; + case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ + reg = OMAP_TC_OCPT2_PRIOR; + break; + case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ + reg = OMAP_TC_EMIFF_PRIOR; + break; + case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ + reg = OMAP_TC_EMIFS_PRIOR; + break; + default: + BUG(); + return; + } + l = omap_readl(reg); + l &= ~(0xf << 8); + l |= (priority & 0xf) << 8; + omap_writel(l, reg); +} + +void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, + int frame_count, int sync_mode) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)); + w &= ~0x03; + w |= data_type; + omap_writew(w, OMAP_DMA_CSDP(lch)); + + w = omap_readw(OMAP_DMA_CCR(lch)); + w &= ~(1 << 5); + if (sync_mode == OMAP_DMA_SYNC_FRAME) + w |= 1 << 5; + omap_writew(w, OMAP_DMA_CCR(lch)); + + w = omap_readw(OMAP_DMA_CCR2(lch)); + w &= ~(1 << 2); + if (sync_mode == OMAP_DMA_SYNC_BLOCK) + w |= 1 << 2; + omap_writew(w, OMAP_DMA_CCR2(lch)); + + omap_writew(elem_count, OMAP_DMA_CEN(lch)); + omap_writew(frame_count, OMAP_DMA_CFN(lch)); + +} +void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) +{ + u16 w; + + BUG_ON(omap_dma_in_1510_mode()); + + w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03; + switch (mode) { + case OMAP_DMA_CONSTANT_FILL: + w |= 0x01; + break; + case OMAP_DMA_TRANSPARENT_COPY: + w |= 0x02; + break; + case OMAP_DMA_COLOR_DIS: + break; + default: + BUG(); + } + omap_writew(w, OMAP_DMA_CCR2(lch)); + + w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f; + /* Default is channel type 2D */ + if (mode) { + omap_writew((u16)color, OMAP_DMA_COLOR_L(lch)); + omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch)); + w |= 1; /* Channel type G */ + } + omap_writew(w, OMAP_DMA_LCH_CTRL(lch)); +} + + +void omap_set_dma_src_params(int lch, int src_port, int src_amode, + unsigned long src_start) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)); + w &= ~(0x1f << 2); + w |= src_port << 2; + omap_writew(w, OMAP_DMA_CSDP(lch)); + + w = omap_readw(OMAP_DMA_CCR(lch)); + w &= ~(0x03 << 12); + w |= src_amode << 12; + omap_writew(w, OMAP_DMA_CCR(lch)); + + omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch)); + omap_writew(src_start, OMAP_DMA_CSSA_L(lch)); +} + +void omap_set_dma_src_index(int lch, int eidx, int fidx) +{ + omap_writew(eidx, OMAP_DMA_CSEI(lch)); + omap_writew(fidx, OMAP_DMA_CSFI(lch)); +} + +void omap_set_dma_src_data_pack(int lch, int enable) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6); + w |= enable ? (1 << 6) : 0; + omap_writew(w, OMAP_DMA_CSDP(lch)); +} + +void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7); + switch (burst_mode) { + case OMAP_DMA_DATA_BURST_DIS: + break; + case OMAP_DMA_DATA_BURST_4: + w |= (0x01 << 7); + break; + case OMAP_DMA_DATA_BURST_8: + /* not supported by current hardware + * w |= (0x03 << 7); + * fall through + */ + default: + BUG(); + } + omap_writew(w, OMAP_DMA_CSDP(lch)); +} + +void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, + unsigned long dest_start) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)); + w &= ~(0x1f << 9); + w |= dest_port << 9; + omap_writew(w, OMAP_DMA_CSDP(lch)); + + w = omap_readw(OMAP_DMA_CCR(lch)); + w &= ~(0x03 << 14); + w |= dest_amode << 14; + omap_writew(w, OMAP_DMA_CCR(lch)); + + omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch)); + omap_writew(dest_start, OMAP_DMA_CDSA_L(lch)); +} + +void omap_set_dma_dest_index(int lch, int eidx, int fidx) +{ + omap_writew(eidx, OMAP_DMA_CDEI(lch)); + omap_writew(fidx, OMAP_DMA_CDFI(lch)); +} + +void omap_set_dma_dest_data_pack(int lch, int enable) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13); + w |= enable ? (1 << 13) : 0; + omap_writew(w, OMAP_DMA_CSDP(lch)); +} + +void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14); + switch (burst_mode) { + case OMAP_DMA_DATA_BURST_DIS: + break; + case OMAP_DMA_DATA_BURST_4: + w |= (0x01 << 14); + break; + case OMAP_DMA_DATA_BURST_8: + w |= (0x03 << 14); + break; + default: + printk(KERN_ERR "Invalid DMA burst mode\n"); + BUG(); + return; + } + omap_writew(w, OMAP_DMA_CSDP(lch)); +} + +static inline void init_intr(int lch) +{ + u16 w; + + /* Read CSR to make sure it's cleared. */ + w = omap_readw(OMAP_DMA_CSR(lch)); + /* Enable some nice interrupts. */ + omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch)); + dma_chan[lch].flags |= OMAP_DMA_ACTIVE; +} + +static inline void enable_lnk(int lch) +{ + u16 w; + + /* Clear the STOP_LNK bits */ + w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); + w &= ~(1 << 14); + omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); + + /* And set the ENABLE_LNK bits */ + if (dma_chan[lch].next_lch != -1) + omap_writew(dma_chan[lch].next_lch | (1 << 15), + OMAP_DMA_CLNK_CTRL(lch)); +} + +static inline void disable_lnk(int lch) +{ + u16 w; + + /* Disable interrupts */ + omap_writew(0, OMAP_DMA_CICR(lch)); + + /* Set the STOP_LNK bit */ + w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); + w |= (1 << 14); + w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); + + dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; +} + +void omap_start_dma(int lch) +{ + u16 w; + + if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { + int next_lch, cur_lch; + char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; + + dma_chan_link_map[lch] = 1; + /* Set the link register of the first channel */ + enable_lnk(lch); + + memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); + cur_lch = dma_chan[lch].next_lch; + do { + next_lch = dma_chan[cur_lch].next_lch; + + /* The loop case: we've been here already */ + if (dma_chan_link_map[cur_lch]) + break; + /* Mark the current channel */ + dma_chan_link_map[cur_lch] = 1; + + enable_lnk(cur_lch); + init_intr(cur_lch); + + cur_lch = next_lch; + } while (next_lch != -1); + } + + init_intr(lch); + + w = omap_readw(OMAP_DMA_CCR(lch)); + w |= OMAP_DMA_CCR_EN; + omap_writew(w, OMAP_DMA_CCR(lch)); + dma_chan[lch].flags |= OMAP_DMA_ACTIVE; +} + +void omap_stop_dma(int lch) +{ + u16 w; + + if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { + int next_lch, cur_lch = lch; + char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; + + memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); + do { + /* The loop case: we've been here already */ + if (dma_chan_link_map[cur_lch]) + break; + /* Mark the current channel */ + dma_chan_link_map[cur_lch] = 1; + + disable_lnk(cur_lch); + + next_lch = dma_chan[cur_lch].next_lch; + cur_lch = next_lch; + } while (next_lch != -1); + + return; + } + /* Disable all interrupts on the channel */ + omap_writew(0, OMAP_DMA_CICR(lch)); + + w = omap_readw(OMAP_DMA_CCR(lch)); + w &= ~OMAP_DMA_CCR_EN; + omap_writew(w, OMAP_DMA_CCR(lch)); + dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; +} + +void omap_enable_dma_irq(int lch, u16 bits) +{ + dma_chan[lch].enabled_irqs |= bits; +} + +void omap_disable_dma_irq(int lch, u16 bits) +{ + dma_chan[lch].enabled_irqs &= ~bits; +} + +static int dma_handle_ch(int ch) +{ + u16 csr; + + if (enable_1510_mode && ch >= 6) { + csr = dma_chan[ch].saved_csr; + dma_chan[ch].saved_csr = 0; + } else + csr = omap_readw(OMAP_DMA_CSR(ch)); + if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) { + dma_chan[ch + 6].saved_csr = csr >> 7; + csr &= 0x7f; + } + if (!csr) + return 0; + if (unlikely(dma_chan[ch].dev_id == -1)) { + printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n", + ch, csr); + return 0; + } + if (unlikely(csr & OMAP_DMA_TOUT_IRQ)) + printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id); + if (unlikely(csr & OMAP_DMA_DROP_IRQ)) + printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n", + dma_chan[ch].dev_id); + if (likely(csr & OMAP_DMA_BLOCK_IRQ)) + dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE; + if (likely(dma_chan[ch].callback != NULL)) + dma_chan[ch].callback(ch, csr, dma_chan[ch].data); + return 1; +} + +static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + int ch = ((int) dev_id) - 1; + int handled = 0; + + for (;;) { + int handled_now = 0; + + handled_now += dma_handle_ch(ch); + if (enable_1510_mode && dma_chan[ch + 6].saved_csr) + handled_now += dma_handle_ch(ch + 6); + if (!handled_now) + break; + handled += handled_now; + } + + return handled ? IRQ_HANDLED : IRQ_NONE; +} + +int omap_request_dma(int dev_id, const char *dev_name, + void (* callback)(int lch, u16 ch_status, void *data), + void *data, int *dma_ch_out) +{ + int ch, free_ch = -1; + unsigned long flags; + struct omap_dma_lch *chan; + + spin_lock_irqsave(&dma_chan_lock, flags); + for (ch = 0; ch < dma_chan_count; ch++) { + if (free_ch == -1 && dma_chan[ch].dev_id == -1) { + free_ch = ch; + if (dev_id == 0) + break; + } + } + if (free_ch == -1) { + spin_unlock_irqrestore(&dma_chan_lock, flags); + return -EBUSY; + } + chan = dma_chan + free_ch; + chan->dev_id = dev_id; + clear_lch_regs(free_ch); + spin_unlock_irqrestore(&dma_chan_lock, flags); + + chan->dev_id = dev_id; + chan->dev_name = dev_name; + chan->callback = callback; + chan->data = data; + chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ; + + if (cpu_is_omap16xx()) { + /* If the sync device is set, configure it dynamically. */ + if (dev_id != 0) { + set_gdma_dev(free_ch + 1, dev_id); + dev_id = free_ch + 1; + } + /* Disable the 1510 compatibility mode and set the sync device + * id. */ + omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch)); + } else { + omap_writew(dev_id, OMAP_DMA_CCR(free_ch)); + } + *dma_ch_out = free_ch; + + return 0; +} + +void omap_free_dma(int ch) +{ + unsigned long flags; + + spin_lock_irqsave(&dma_chan_lock, flags); + if (dma_chan[ch].dev_id == -1) { + printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch); + spin_unlock_irqrestore(&dma_chan_lock, flags); + return; + } + dma_chan[ch].dev_id = -1; + spin_unlock_irqrestore(&dma_chan_lock, flags); + + /* Disable all DMA interrupts for the channel. */ + omap_writew(0, OMAP_DMA_CICR(ch)); + /* Make sure the DMA transfer is stopped. */ + omap_writew(0, OMAP_DMA_CCR(ch)); +} + +int omap_dma_in_1510_mode(void) +{ + return enable_1510_mode; +} + +/* + * lch_queue DMA will start right after lch_head one is finished. + * For this DMA link to start, you still need to start (see omap_start_dma) + * the first one. That will fire up the entire queue. + */ +void omap_dma_link_lch (int lch_head, int lch_queue) +{ + if (omap_dma_in_1510_mode()) { + printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); + BUG(); + return; + } + + if ((dma_chan[lch_head].dev_id == -1) || + (dma_chan[lch_queue].dev_id == -1)) { + printk(KERN_ERR "omap_dma: trying to link non requested channels\n"); + dump_stack(); + } + + dma_chan[lch_head].next_lch = lch_queue; +} + +/* + * Once the DMA queue is stopped, we can destroy it. + */ +void omap_dma_unlink_lch (int lch_head, int lch_queue) +{ + if (omap_dma_in_1510_mode()) { + printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); + BUG(); + return; + } + + if (dma_chan[lch_head].next_lch != lch_queue || + dma_chan[lch_head].next_lch == -1) { + printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n"); + dump_stack(); + } + + + if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) || + (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) { + printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n"); + dump_stack(); + } + + dma_chan[lch_head].next_lch = -1; +} + + +static struct lcd_dma_info { + spinlock_t lock; + int reserved; + void (* callback)(u16 status, void *data); + void *cb_data; + + int active; + unsigned long addr, size; + int rotate, data_type, xres, yres; + int vxres; + int mirror; + int xscale, yscale; + int ext_ctrl; + int src_port; + int single_transfer; +} lcd_dma; + +void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres, + int data_type) +{ + lcd_dma.addr = addr; + lcd_dma.data_type = data_type; + lcd_dma.xres = fb_xres; + lcd_dma.yres = fb_yres; +} + +void omap_set_lcd_dma_src_port(int port) +{ + lcd_dma.src_port = port; +} + +void omap_set_lcd_dma_ext_controller(int external) +{ + lcd_dma.ext_ctrl = external; +} + +void omap_set_lcd_dma_single_transfer(int single) +{ + lcd_dma.single_transfer = single; +} + + +void omap_set_lcd_dma_b1_rotation(int rotate) +{ + if (omap_dma_in_1510_mode()) { + printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n"); + BUG(); + return; + } + lcd_dma.rotate = rotate; +} + +void omap_set_lcd_dma_b1_mirror(int mirror) +{ + if (omap_dma_in_1510_mode()) { + printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n"); + BUG(); + } + lcd_dma.mirror = mirror; +} + +void omap_set_lcd_dma_b1_vxres(unsigned long vxres) +{ + if (omap_dma_in_1510_mode()) { + printk(KERN_ERR "DMA virtual resulotion is not supported " + "in 1510 mode\n"); + BUG(); + } + lcd_dma.vxres = vxres; +} + +void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale) +{ + if (omap_dma_in_1510_mode()) { + printk(KERN_ERR "DMA scale is not supported in 1510 mode\n"); + BUG(); + } + lcd_dma.xscale = xscale; + lcd_dma.yscale = yscale; +} + +static void set_b1_regs(void) +{ + unsigned long top, bottom; + int es; + u16 w; + unsigned long en, fn; + long ei, fi; + unsigned long vxres; + unsigned int xscale, yscale; + + switch (lcd_dma.data_type) { + case OMAP_DMA_DATA_TYPE_S8: + es = 1; + break; + case OMAP_DMA_DATA_TYPE_S16: + es = 2; + break; + case OMAP_DMA_DATA_TYPE_S32: + es = 4; + break; + default: + BUG(); + return; + } + + vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres; + xscale = lcd_dma.xscale ? lcd_dma.xscale : 1; + yscale = lcd_dma.yscale ? lcd_dma.yscale : 1; + BUG_ON(vxres < lcd_dma.xres); +#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es) +#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1) + switch (lcd_dma.rotate) { + case 0: + if (!lcd_dma.mirror) { + top = PIXADDR(0, 0); + bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); + /* 1510 DMA requires the bottom address to be 2 more + * than the actual last memory access location. */ + if (omap_dma_in_1510_mode() && + lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32) + bottom += 2; + ei = PIXSTEP(0, 0, 1, 0); + fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1); + } else { + top = PIXADDR(lcd_dma.xres - 1, 0); + bottom = PIXADDR(0, lcd_dma.yres - 1); + ei = PIXSTEP(1, 0, 0, 0); + fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1); + } + en = lcd_dma.xres; + fn = lcd_dma.yres; + break; + case 90: + if (!lcd_dma.mirror) { + top = PIXADDR(0, lcd_dma.yres - 1); + bottom = PIXADDR(lcd_dma.xres - 1, 0); + ei = PIXSTEP(0, 1, 0, 0); + fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1); + } else { + top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); + bottom = PIXADDR(0, 0); + ei = PIXSTEP(0, 1, 0, 0); + fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1); + } + en = lcd_dma.yres; + fn = lcd_dma.xres; + break; + case 180: + if (!lcd_dma.mirror) { + top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); + bottom = PIXADDR(0, 0); + ei = PIXSTEP(1, 0, 0, 0); + fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0); + } else { + top = PIXADDR(0, lcd_dma.yres - 1); + bottom = PIXADDR(lcd_dma.xres - 1, 0); + ei = PIXSTEP(0, 0, 1, 0); + fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0); + } + en = lcd_dma.xres; + fn = lcd_dma.yres; + break; + case 270: + if (!lcd_dma.mirror) { + top = PIXADDR(lcd_dma.xres - 1, 0); + bottom = PIXADDR(0, lcd_dma.yres - 1); + ei = PIXSTEP(0, 0, 0, 1); + fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0); + } else { + top = PIXADDR(0, 0); + bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1); + ei = PIXSTEP(0, 0, 0, 1); + fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0); + } + en = lcd_dma.yres; + fn = lcd_dma.xres; + break; + default: + BUG(); + return; /* Supress warning about uninitialized vars */ + } + + if (omap_dma_in_1510_mode()) { + omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U); + omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L); + omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U); + omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L); + + return; + } + + /* 1610 regs */ + omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U); + omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L); + omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U); + omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L); + + omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1); + omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1); + + w = omap_readw(OMAP1610_DMA_LCD_CSDP); + w &= ~0x03; + w |= lcd_dma.data_type; + omap_writew(w, OMAP1610_DMA_LCD_CSDP); + + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + /* Always set the source port as SDRAM for now*/ + w &= ~(0x03 << 6); + if (lcd_dma.ext_ctrl) + w |= 1 << 8; + else + w &= ~(1 << 8); + if (lcd_dma.callback != NULL) + w |= 1 << 1; /* Block interrupt enable */ + else + w &= ~(1 << 1); + omap_writew(w, OMAP1610_DMA_LCD_CTRL); + + if (!(lcd_dma.rotate || lcd_dma.mirror || + lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale)) + return; + + w = omap_readw(OMAP1610_DMA_LCD_CCR); + /* Set the double-indexed addressing mode */ + w |= (0x03 << 12); + omap_writew(w, OMAP1610_DMA_LCD_CCR); + + omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1); + omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U); + omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L); +} + +static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + u16 w; + + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + if (unlikely(!(w & (1 << 3)))) { + printk(KERN_WARNING "Spurious LCD DMA IRQ\n"); + return IRQ_NONE; + } + /* Ack the IRQ */ + w |= (1 << 3); + omap_writew(w, OMAP1610_DMA_LCD_CTRL); + lcd_dma.active = 0; + if (lcd_dma.callback != NULL) + lcd_dma.callback(w, lcd_dma.cb_data); + + return IRQ_HANDLED; +} + +int omap_request_lcd_dma(void (* callback)(u16 status, void *data), + void *data) +{ + spin_lock_irq(&lcd_dma.lock); + if (lcd_dma.reserved) { + spin_unlock_irq(&lcd_dma.lock); + printk(KERN_ERR "LCD DMA channel already reserved\n"); + BUG(); + return -EBUSY; + } + lcd_dma.reserved = 1; + spin_unlock_irq(&lcd_dma.lock); + lcd_dma.callback = callback; + lcd_dma.cb_data = data; + lcd_dma.active = 0; + lcd_dma.single_transfer = 0; + lcd_dma.rotate = 0; + lcd_dma.vxres = 0; + lcd_dma.mirror = 0; + lcd_dma.xscale = 0; + lcd_dma.yscale = 0; + lcd_dma.ext_ctrl = 0; + lcd_dma.src_port = 0; + + return 0; +} + +void omap_free_lcd_dma(void) +{ + spin_lock(&lcd_dma.lock); + if (!lcd_dma.reserved) { + spin_unlock(&lcd_dma.lock); + printk(KERN_ERR "LCD DMA is not reserved\n"); + BUG(); + return; + } + if (!enable_1510_mode) + omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR); + lcd_dma.reserved = 0; + spin_unlock(&lcd_dma.lock); +} + +void omap_enable_lcd_dma(void) +{ + u16 w; + + /* Set the Enable bit only if an external controller is + * connected. Otherwise the OMAP internal controller will + * start the transfer when it gets enabled. + */ + if (enable_1510_mode || !lcd_dma.ext_ctrl) + return; + w = omap_readw(OMAP1610_DMA_LCD_CCR); + w |= 1 << 7; + omap_writew(w, OMAP1610_DMA_LCD_CCR); + lcd_dma.active = 1; +} + +void omap_setup_lcd_dma(void) +{ + BUG_ON(lcd_dma.active); + if (!enable_1510_mode) { + /* Set some reasonable defaults */ + omap_writew(0x5440, OMAP1610_DMA_LCD_CCR); + omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP); + omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL); + } + set_b1_regs(); + if (!enable_1510_mode) { + u16 w; + + w = omap_readw(OMAP1610_DMA_LCD_CCR); + /* If DMA was already active set the end_prog bit to have + * the programmed register set loaded into the active + * register set. + */ + w |= 1 << 11; /* End_prog */ + if (!lcd_dma.single_transfer) + w |= (3 << 8); /* Auto_init, repeat */ + omap_writew(w, OMAP1610_DMA_LCD_CCR); + } +} + +void omap_stop_lcd_dma(void) +{ + lcd_dma.active = 0; + if (!enable_1510_mode && lcd_dma.ext_ctrl) + omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~(1 << 7), + OMAP1610_DMA_LCD_CCR); +} + +/* + * Clears any DMA state so the DMA engine is ready to restart with new buffers + * through omap_start_dma(). Any buffers in flight are discarded. + */ +void omap_clear_dma(int lch) +{ + unsigned long flags; + int status; + + local_irq_save(flags); + omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN, + OMAP_DMA_CCR(lch)); + status = OMAP_DMA_CSR(lch); /* clear pending interrupts */ + local_irq_restore(flags); +} + +/* + * Returns current physical source address for the given DMA channel. + * If the channel is running the caller must disable interrupts prior calling + * this function and process the returned value before re-enabling interrupt to + * prevent races with the interrupt handler. Note that in continuous mode there + * is a chance for CSSA_L register overflow inbetween the two reads resulting + * in incorrect return value. + */ +dma_addr_t omap_get_dma_src_pos(int lch) +{ + return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) | + (OMAP_DMA_CSSA_U(lch) << 16)); +} + +/* + * Returns current physical destination address for the given DMA channel. + * If the channel is running the caller must disable interrupts prior calling + * this function and process the returned value before re-enabling interrupt to + * prevent races with the interrupt handler. Note that in continuous mode there + * is a chance for CDSA_L register overflow inbetween the two reads resulting + * in incorrect return value. + */ +dma_addr_t omap_get_dma_dst_pos(int lch) +{ + return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) | + (OMAP_DMA_CDSA_U(lch) << 16)); +} + +static int __init omap_init_dma(void) +{ + int ch, r; + + if (cpu_is_omap1510()) { + printk(KERN_INFO "DMA support for OMAP1510 initialized\n"); + dma_chan_count = 9; + enable_1510_mode = 1; + } else if (cpu_is_omap16xx() || cpu_is_omap730()) { + printk(KERN_INFO "OMAP DMA hardware version %d\n", + omap_readw(OMAP_DMA_HW_ID)); + printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n", + (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L), + (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L), + omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3), + omap_readw(OMAP_DMA_CAPS_4)); + if (!enable_1510_mode) { + u16 w; + + /* Disable OMAP 3.0/3.1 compatibility mode. */ + w = omap_readw(OMAP_DMA_GSCR); + w |= 1 << 3; + omap_writew(w, OMAP_DMA_GSCR); + dma_chan_count = 16; + } else + dma_chan_count = 9; + } else { + dma_chan_count = 0; + return 0; + } + + memset(&lcd_dma, 0, sizeof(lcd_dma)); + spin_lock_init(&lcd_dma.lock); + spin_lock_init(&dma_chan_lock); + memset(&dma_chan, 0, sizeof(dma_chan)); + + for (ch = 0; ch < dma_chan_count; ch++) { + dma_chan[ch].dev_id = -1; + dma_chan[ch].next_lch = -1; + + if (ch >= 6 && enable_1510_mode) + continue; + + /* request_irq() doesn't like dev_id (ie. ch) being zero, + * so we have to kludge around this. */ + r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA", + (void *) (ch + 1)); + if (r != 0) { + int i; + + printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n", + dma_irq[ch], r); + for (i = 0; i < ch; i++) + free_irq(dma_irq[i], (void *) (i + 1)); + return r; + } + } + r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL); + if (r != 0) { + int i; + + printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r); + for (i = 0; i < dma_chan_count; i++) + free_irq(dma_irq[i], (void *) (i + 1)); + return r; + } + return 0; +} + +arch_initcall(omap_init_dma); + + +EXPORT_SYMBOL(omap_get_dma_src_pos); +EXPORT_SYMBOL(omap_get_dma_dst_pos); +EXPORT_SYMBOL(omap_clear_dma); +EXPORT_SYMBOL(omap_set_dma_priority); +EXPORT_SYMBOL(omap_request_dma); +EXPORT_SYMBOL(omap_free_dma); +EXPORT_SYMBOL(omap_start_dma); +EXPORT_SYMBOL(omap_stop_dma); +EXPORT_SYMBOL(omap_enable_dma_irq); +EXPORT_SYMBOL(omap_disable_dma_irq); + +EXPORT_SYMBOL(omap_set_dma_transfer_params); +EXPORT_SYMBOL(omap_set_dma_color_mode); + +EXPORT_SYMBOL(omap_set_dma_src_params); +EXPORT_SYMBOL(omap_set_dma_src_index); +EXPORT_SYMBOL(omap_set_dma_src_data_pack); +EXPORT_SYMBOL(omap_set_dma_src_burst_mode); + +EXPORT_SYMBOL(omap_set_dma_dest_params); +EXPORT_SYMBOL(omap_set_dma_dest_index); +EXPORT_SYMBOL(omap_set_dma_dest_data_pack); +EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); + +EXPORT_SYMBOL(omap_dma_link_lch); +EXPORT_SYMBOL(omap_dma_unlink_lch); + +EXPORT_SYMBOL(omap_request_lcd_dma); +EXPORT_SYMBOL(omap_free_lcd_dma); +EXPORT_SYMBOL(omap_enable_lcd_dma); +EXPORT_SYMBOL(omap_setup_lcd_dma); +EXPORT_SYMBOL(omap_stop_lcd_dma); +EXPORT_SYMBOL(omap_set_lcd_dma_b1); +EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); +EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); +EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation); +EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres); +EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale); +EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror); + diff --git a/arch/arm/mach-omap/fpga.c b/arch/arm/mach-omap/fpga.c new file mode 100644 index 0000000..7c08f6c --- /dev/null +++ b/arch/arm/mach-omap/fpga.c @@ -0,0 +1,188 @@ +/* + * linux/arch/arm/mach-omap/fpga.c + * + * Interrupt handler for OMAP-1510 Innovator FPGA + * + * Copyright (C) 2001 RidgeRun, Inc. + * Author: Greg Lonnon <glonnon@ridgerun.com> + * + * Copyright (C) 2002 MontaVista Software, Inc. + * + * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6 + * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com> + * + * 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/types.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/errno.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> + +#include <asm/arch/fpga.h> +#include <asm/arch/gpio.h> + +static void fpga_mask_irq(unsigned int irq) +{ + irq -= OMAP1510_IH_FPGA_BASE; + + if (irq < 8) + __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) + & ~(1 << irq)), OMAP1510_FPGA_IMR_LO); + else if (irq < 16) + __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI) + & ~(1 << (irq - 8))), OMAP1510_FPGA_IMR_HI); + else + __raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2) + & ~(1 << (irq - 16))), INNOVATOR_FPGA_IMR2); +} + + +static inline u32 get_fpga_unmasked_irqs(void) +{ + return + ((__raw_readb(OMAP1510_FPGA_ISR_LO) & + __raw_readb(OMAP1510_FPGA_IMR_LO))) | + ((__raw_readb(OMAP1510_FPGA_ISR_HI) & + __raw_readb(OMAP1510_FPGA_IMR_HI)) << 8) | + ((__raw_readb(INNOVATOR_FPGA_ISR2) & + __raw_readb(INNOVATOR_FPGA_IMR2)) << 16); +} + + +static void fpga_ack_irq(unsigned int irq) +{ + /* Don't need to explicitly ACK FPGA interrupts */ +} + +static void fpga_unmask_irq(unsigned int irq) +{ + irq -= OMAP1510_IH_FPGA_BASE; + + if (irq < 8) + __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)), + OMAP1510_FPGA_IMR_LO); + else if (irq < 16) + __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI) + | (1 << (irq - 8))), OMAP1510_FPGA_IMR_HI); + else + __raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2) + | (1 << (irq - 16))), INNOVATOR_FPGA_IMR2); +} + +static void fpga_mask_ack_irq(unsigned int irq) +{ + fpga_mask_irq(irq); + fpga_ack_irq(irq); +} + +void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + struct irqdesc *d; + u32 stat; + int fpga_irq; + + stat = get_fpga_unmasked_irqs(); + + if (!stat) + return; + + for (fpga_irq = OMAP1510_IH_FPGA_BASE; + (fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat; + fpga_irq++, stat >>= 1) { + if (stat & 1) { + d = irq_desc + fpga_irq; + d->handle(fpga_irq, d, regs); + } + } +} + +static struct irqchip omap_fpga_irq_ack = { + .ack = fpga_mask_ack_irq, + .mask = fpga_mask_irq, + .unmask = fpga_unmask_irq, +}; + + +static struct irqchip omap_fpga_irq = { + .ack = fpga_ack_irq, + .mask = fpga_mask_irq, + .unmask = fpga_unmask_irq, +}; + +/* + * All of the FPGA interrupt request inputs except for the touchscreen are + * edge-sensitive; the touchscreen is level-sensitive. The edge-sensitive + * interrupts are acknowledged as a side-effect of reading the interrupt + * status register from the FPGA. The edge-sensitive interrupt inputs + * cause a problem with level interrupt requests, such as Ethernet. The + * problem occurs when a level interrupt request is asserted while its + * interrupt input is masked in the FPGA, which results in a missed + * interrupt. + * + * In an attempt to workaround the problem with missed interrupts, the + * mask_ack routine for all of the FPGA interrupts has been changed from + * fpga_mask_ack_irq() to fpga_ack_irq() so that the specific FPGA interrupt + * being serviced is left unmasked. We can do this because the FPGA cascade + * interrupt is installed with the SA_INTERRUPT flag, which leaves all + * interrupts masked at the CPU while an FPGA interrupt handler executes. + * + * Limited testing indicates that this workaround appears to be effective + * for the smc9194 Ethernet driver used on the Innovator. It should work + * on other FPGA interrupts as well, but any drivers that explicitly mask + * interrupts at the interrupt controller via disable_irq/enable_irq + * could pose a problem. + */ +void omap1510_fpga_init_irq(void) +{ + int i; + + __raw_writeb(0, OMAP1510_FPGA_IMR_LO); + __raw_writeb(0, OMAP1510_FPGA_IMR_HI); + __raw_writeb(0, INNOVATOR_FPGA_IMR2); + + for (i = OMAP1510_IH_FPGA_BASE; i < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS); i++) { + + if (i == OMAP1510_INT_FPGA_TS) { + /* + * The touchscreen interrupt is level-sensitive, so + * we'll use the regular mask_ack routine for it. + */ + set_irq_chip(i, &omap_fpga_irq_ack); + } + else { + /* + * All FPGA interrupts except the touchscreen are + * edge-sensitive, so we won't mask them. + */ + set_irq_chip(i, &omap_fpga_irq); + } + + set_irq_handler(i, do_edge_IRQ); + set_irq_flags(i, IRQF_VALID); + } + + /* + * The FPGA interrupt line is connected to GPIO13. Claim this pin for + * the ARM. + * + * NOTE: For general GPIO/MPUIO access and interrupts, please see + * gpio.[ch] + */ + omap_request_gpio(13); + omap_set_gpio_direction(13, 1); + omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE); + set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux); +} + +EXPORT_SYMBOL(omap1510_fpga_init_irq); diff --git a/arch/arm/mach-omap/gpio.c b/arch/arm/mach-omap/gpio.c new file mode 100644 index 0000000..9045dfd --- /dev/null +++ b/arch/arm/mach-omap/gpio.c @@ -0,0 +1,762 @@ +/* + * linux/arch/arm/mach-omap/gpio.c + * + * Support functions for OMAP GPIO + * + * Copyright (C) 2003 Nokia Corporation + * Written by Juha Yrjölä <juha.yrjola@nokia.com> + * + * 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/init.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/arch/irqs.h> +#include <asm/arch/gpio.h> +#include <asm/mach/irq.h> + +#include <asm/io.h> + +/* + * OMAP1510 GPIO registers + */ +#define OMAP1510_GPIO_BASE 0xfffce000 +#define OMAP1510_GPIO_DATA_INPUT 0x00 +#define OMAP1510_GPIO_DATA_OUTPUT 0x04 +#define OMAP1510_GPIO_DIR_CONTROL 0x08 +#define OMAP1510_GPIO_INT_CONTROL 0x0c +#define OMAP1510_GPIO_INT_MASK 0x10 +#define OMAP1510_GPIO_INT_STATUS 0x14 +#define OMAP1510_GPIO_PIN_CONTROL 0x18 + +#define OMAP1510_IH_GPIO_BASE 64 + +/* + * OMAP1610 specific GPIO registers + */ +#define OMAP1610_GPIO1_BASE 0xfffbe400 +#define OMAP1610_GPIO2_BASE 0xfffbec00 +#define OMAP1610_GPIO3_BASE 0xfffbb400 +#define OMAP1610_GPIO4_BASE 0xfffbbc00 +#define OMAP1610_GPIO_REVISION 0x0000 +#define OMAP1610_GPIO_SYSCONFIG 0x0010 +#define OMAP1610_GPIO_SYSSTATUS 0x0014 +#define OMAP1610_GPIO_IRQSTATUS1 0x0018 +#define OMAP1610_GPIO_IRQENABLE1 0x001c +#define OMAP1610_GPIO_DATAIN 0x002c +#define OMAP1610_GPIO_DATAOUT 0x0030 +#define OMAP1610_GPIO_DIRECTION 0x0034 +#define OMAP1610_GPIO_EDGE_CTRL1 0x0038 +#define OMAP1610_GPIO_EDGE_CTRL2 0x003c +#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c +#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 +#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc +#define OMAP1610_GPIO_SET_DATAOUT 0x00f0 + +/* + * OMAP730 specific GPIO registers + */ +#define OMAP730_GPIO1_BASE 0xfffbc000 +#define OMAP730_GPIO2_BASE 0xfffbc800 +#define OMAP730_GPIO3_BASE 0xfffbd000 +#define OMAP730_GPIO4_BASE 0xfffbd800 +#define OMAP730_GPIO5_BASE 0xfffbe000 +#define OMAP730_GPIO6_BASE 0xfffbe800 +#define OMAP730_GPIO_DATA_INPUT 0x00 +#define OMAP730_GPIO_DATA_OUTPUT 0x04 +#define OMAP730_GPIO_DIR_CONTROL 0x08 +#define OMAP730_GPIO_INT_CONTROL 0x0c +#define OMAP730_GPIO_INT_MASK 0x10 +#define OMAP730_GPIO_INT_STATUS 0x14 + +#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) + +struct gpio_bank { + u32 base; + u16 irq; + u16 virtual_irq_start; + u8 method; + u32 reserved_map; + spinlock_t lock; +}; + +#define METHOD_MPUIO 0 +#define METHOD_GPIO_1510 1 +#define METHOD_GPIO_1610 2 +#define METHOD_GPIO_730 3 + +#if defined(CONFIG_ARCH_OMAP16XX) +static struct gpio_bank gpio_bank_1610[5] = { + { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO}, + { OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 }, + { OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 }, + { OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 }, + { OMAP1610_GPIO4_BASE, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48, METHOD_GPIO_1610 }, +}; +#endif + +#ifdef CONFIG_ARCH_OMAP1510 +static struct gpio_bank gpio_bank_1510[2] = { + { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, + { OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 } +}; +#endif + +#ifdef CONFIG_ARCH_OMAP730 +static struct gpio_bank gpio_bank_730[7] = { + { OMAP_MPUIO_BASE, INT_730_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO }, + { OMAP730_GPIO1_BASE, INT_730_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_730 }, + { OMAP730_GPIO2_BASE, INT_730_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_730 }, + { OMAP730_GPIO3_BASE, INT_730_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_730 }, + { OMAP730_GPIO4_BASE, INT_730_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_730 }, + { OMAP730_GPIO5_BASE, INT_730_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_730 }, + { OMAP730_GPIO6_BASE, INT_730_GPIO_BANK6, IH_GPIO_BASE + 160, METHOD_GPIO_730 }, +}; +#endif + +static struct gpio_bank *gpio_bank; +static int gpio_bank_count; + +static inline struct gpio_bank *get_gpio_bank(int gpio) +{ +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + if (OMAP_GPIO_IS_MPUIO(gpio)) + return &gpio_bank[0]; + return &gpio_bank[1]; + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (cpu_is_omap16xx()) { + if (OMAP_GPIO_IS_MPUIO(gpio)) + return &gpio_bank[0]; + return &gpio_bank[1 + (gpio >> 4)]; + } +#endif +#ifdef CONFIG_ARCH_OMAP730 + if (cpu_is_omap730()) { + if (OMAP_GPIO_IS_MPUIO(gpio)) + return &gpio_bank[0]; + return &gpio_bank[1 + (gpio >> 5)]; + } +#endif +} + +static inline int get_gpio_index(int gpio) +{ + if (cpu_is_omap730()) + return gpio & 0x1f; + else + return gpio & 0x0f; +} + +static inline int gpio_valid(int gpio) +{ + if (gpio < 0) + return -1; + if (OMAP_GPIO_IS_MPUIO(gpio)) { + if ((gpio & OMAP_MPUIO_MASK) > 16) + return -1; + return 0; + } +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510() && gpio < 16) + return 0; +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if ((cpu_is_omap16xx()) && gpio < 64) + return 0; +#endif +#ifdef CONFIG_ARCH_OMAP730 + if (cpu_is_omap730() && gpio < 192) + return 0; +#endif + return -1; +} + +static int check_gpio(int gpio) +{ + if (unlikely(gpio_valid(gpio)) < 0) { + printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio); + dump_stack(); + return -1; + } + return 0; +} + +static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) +{ + u32 reg = bank->base; + u32 l; + + switch (bank->method) { + case METHOD_MPUIO: + reg += OMAP_MPUIO_IO_CNTL; + break; + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_DIR_CONTROL; + break; + case METHOD_GPIO_1610: + reg += OMAP1610_GPIO_DIRECTION; + break; + case METHOD_GPIO_730: + reg += OMAP730_GPIO_DIR_CONTROL; + break; + } + l = __raw_readl(reg); + if (is_input) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + __raw_writel(l, reg); +} + +void omap_set_gpio_direction(int gpio, int is_input) +{ + struct gpio_bank *bank; + + if (check_gpio(gpio) < 0) + return; + bank = get_gpio_bank(gpio); + spin_lock(&bank->lock); + _set_gpio_direction(bank, get_gpio_index(gpio), is_input); + spin_unlock(&bank->lock); +} + +static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) +{ + u32 reg = bank->base; + u32 l = 0; + + switch (bank->method) { + case METHOD_MPUIO: + reg += OMAP_MPUIO_OUTPUT; + l = __raw_readl(reg); + if (enable) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + break; + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_DATA_OUTPUT; + l = __raw_readl(reg); + if (enable) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + break; + case METHOD_GPIO_1610: + if (enable) + reg += OMAP1610_GPIO_SET_DATAOUT; + else + reg += OMAP1610_GPIO_CLEAR_DATAOUT; + l = 1 << gpio; + break; + case METHOD_GPIO_730: + reg += OMAP730_GPIO_DATA_OUTPUT; + l = __raw_readl(reg); + if (enable) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + break; + default: + BUG(); + return; + } + __raw_writel(l, reg); +} + +void omap_set_gpio_dataout(int gpio, int enable) +{ + struct gpio_bank *bank; + + if (check_gpio(gpio) < 0) + return; + bank = get_gpio_bank(gpio); + spin_lock(&bank->lock); + _set_gpio_dataout(bank, get_gpio_index(gpio), enable); + spin_unlock(&bank->lock); +} + +int omap_get_gpio_datain(int gpio) +{ + struct gpio_bank *bank; + u32 reg; + + if (check_gpio(gpio) < 0) + return -1; + bank = get_gpio_bank(gpio); + reg = bank->base; + switch (bank->method) { + case METHOD_MPUIO: + reg += OMAP_MPUIO_INPUT_LATCH; + break; + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_DATA_INPUT; + break; + case METHOD_GPIO_1610: + reg += OMAP1610_GPIO_DATAIN; + break; + case METHOD_GPIO_730: + reg += OMAP730_GPIO_DATA_INPUT; + break; + default: + BUG(); + return -1; + } + return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; +} + +static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge) +{ + u32 reg = bank->base; + u32 l; + + switch (bank->method) { + case METHOD_MPUIO: + reg += OMAP_MPUIO_GPIO_INT_EDGE; + l = __raw_readl(reg); + if (edge == OMAP_GPIO_RISING_EDGE) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + __raw_writel(l, reg); + break; + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_INT_CONTROL; + l = __raw_readl(reg); + if (edge == OMAP_GPIO_RISING_EDGE) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + __raw_writel(l, reg); + break; + case METHOD_GPIO_1610: + edge &= 0x03; + if (gpio & 0x08) + reg += OMAP1610_GPIO_EDGE_CTRL2; + else + reg += OMAP1610_GPIO_EDGE_CTRL1; + gpio &= 0x07; + l = __raw_readl(reg); + l &= ~(3 << (gpio << 1)); + l |= edge << (gpio << 1); + __raw_writel(l, reg); + break; + case METHOD_GPIO_730: + reg += OMAP730_GPIO_INT_CONTROL; + l = __raw_readl(reg); + if (edge == OMAP_GPIO_RISING_EDGE) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + __raw_writel(l, reg); + break; + default: + BUG(); + return; + } +} + +void omap_set_gpio_edge_ctrl(int gpio, int edge) +{ + struct gpio_bank *bank; + + if (check_gpio(gpio) < 0) + return; + bank = get_gpio_bank(gpio); + spin_lock(&bank->lock); + _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), edge); + spin_unlock(&bank->lock); +} + + +static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio) +{ + u32 reg = bank->base, l; + + switch (bank->method) { + case METHOD_MPUIO: + l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE); + return (l & (1 << gpio)) ? + OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; + case METHOD_GPIO_1510: + l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL); + return (l & (1 << gpio)) ? + OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; + case METHOD_GPIO_1610: + if (gpio & 0x08) + reg += OMAP1610_GPIO_EDGE_CTRL2; + else + reg += OMAP1610_GPIO_EDGE_CTRL1; + return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03; + case METHOD_GPIO_730: + l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL); + return (l & (1 << gpio)) ? + OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; + default: + BUG(); + return -1; + } +} + +static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) +{ + u32 reg = bank->base; + + switch (bank->method) { + case METHOD_MPUIO: + /* MPUIO irqstatus is reset by reading the status register, + * so do nothing here */ + return; + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_INT_STATUS; + break; + case METHOD_GPIO_1610: + reg += OMAP1610_GPIO_IRQSTATUS1; + break; + case METHOD_GPIO_730: + reg += OMAP730_GPIO_INT_STATUS; + break; + default: + BUG(); + return; + } + __raw_writel(gpio_mask, reg); +} + +static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) +{ + _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio)); +} + +static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) +{ + u32 reg = bank->base; + u32 l; + + switch (bank->method) { + case METHOD_MPUIO: + reg += OMAP_MPUIO_GPIO_MASKIT; + l = __raw_readl(reg); + if (enable) + l &= ~(gpio_mask); + else + l |= gpio_mask; + break; + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_INT_MASK; + l = __raw_readl(reg); + if (enable) + l &= ~(gpio_mask); + else + l |= gpio_mask; + break; + case METHOD_GPIO_1610: + if (enable) + reg += OMAP1610_GPIO_SET_IRQENABLE1; + else + reg += OMAP1610_GPIO_CLEAR_IRQENABLE1; + l = gpio_mask; + break; + case METHOD_GPIO_730: + reg += OMAP730_GPIO_INT_MASK; + l = __raw_readl(reg); + if (enable) + l &= ~(gpio_mask); + else + l |= gpio_mask; + break; + default: + BUG(); + return; + } + __raw_writel(l, reg); +} + +static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) +{ + _enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable); +} + +int omap_request_gpio(int gpio) +{ + struct gpio_bank *bank; + + if (check_gpio(gpio) < 0) + return -EINVAL; + + bank = get_gpio_bank(gpio); + spin_lock(&bank->lock); + if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) { + printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio); + dump_stack(); + spin_unlock(&bank->lock); + return -1; + } + bank->reserved_map |= (1 << get_gpio_index(gpio)); +#ifdef CONFIG_ARCH_OMAP1510 + if (bank->method == METHOD_GPIO_1510) { + u32 reg; + + /* Claim the pin for the ARM */ + reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; + __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); + } +#endif + spin_unlock(&bank->lock); + + return 0; +} + +void omap_free_gpio(int gpio) +{ + struct gpio_bank *bank; + + if (check_gpio(gpio) < 0) + return; + bank = get_gpio_bank(gpio); + spin_lock(&bank->lock); + if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) { + printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio); + dump_stack(); + spin_unlock(&bank->lock); + return; + } + bank->reserved_map &= ~(1 << get_gpio_index(gpio)); + _set_gpio_direction(bank, get_gpio_index(gpio), 1); + _set_gpio_irqenable(bank, gpio, 0); + _clear_gpio_irqstatus(bank, gpio); + spin_unlock(&bank->lock); +} + +/* + * We need to unmask the GPIO bank interrupt as soon as possible to + * avoid missing GPIO interrupts for other lines in the bank. + * Then we need to mask-read-clear-unmask the triggered GPIO lines + * in the bank to avoid missing nested interrupts for a GPIO line. + * If we wait to unmask individual GPIO lines in the bank after the + * line's interrupt handler has been run, we may miss some nested + * interrupts. + */ +static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + u32 isr_reg = 0; + u32 isr; + unsigned int gpio_irq; + struct gpio_bank *bank; + + desc->chip->ack(irq); + + bank = (struct gpio_bank *) desc->data; + if (bank->method == METHOD_MPUIO) + isr_reg = bank->base + OMAP_MPUIO_GPIO_INT; +#ifdef CONFIG_ARCH_OMAP1510 + if (bank->method == METHOD_GPIO_1510) + isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS; +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (bank->method == METHOD_GPIO_1610) + isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1; +#endif +#ifdef CONFIG_ARCH_OMAP730 + if (bank->method == METHOD_GPIO_730) + isr_reg = bank->base + OMAP730_GPIO_INT_STATUS; +#endif + + isr = __raw_readl(isr_reg); + _enable_gpio_irqbank(bank, isr, 0); + _clear_gpio_irqbank(bank, isr); + _enable_gpio_irqbank(bank, isr, 1); + desc->chip->unmask(irq); + + if (unlikely(!isr)) + return; + + gpio_irq = bank->virtual_irq_start; + for (; isr != 0; isr >>= 1, gpio_irq++) { + struct irqdesc *d; + if (!(isr & 1)) + continue; + d = irq_desc + gpio_irq; + d->handle(gpio_irq, d, regs); + } +} + +static void gpio_ack_irq(unsigned int irq) +{ + unsigned int gpio = irq - IH_GPIO_BASE; + struct gpio_bank *bank = get_gpio_bank(gpio); + + _clear_gpio_irqstatus(bank, gpio); +} + +static void gpio_mask_irq(unsigned int irq) +{ + unsigned int gpio = irq - IH_GPIO_BASE; + struct gpio_bank *bank = get_gpio_bank(gpio); + + _set_gpio_irqenable(bank, gpio, 0); +} + +static void gpio_unmask_irq(unsigned int irq) +{ + unsigned int gpio = irq - IH_GPIO_BASE; + struct gpio_bank *bank = get_gpio_bank(gpio); + + if (_get_gpio_edge_ctrl(bank, get_gpio_index(gpio)) == OMAP_GPIO_NO_EDGE) { + printk(KERN_ERR "OMAP GPIO %d: trying to enable GPIO IRQ while no edge is set\n", + gpio); + _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), OMAP_GPIO_RISING_EDGE); + } + _set_gpio_irqenable(bank, gpio, 1); +} + +static void mpuio_ack_irq(unsigned int irq) +{ + /* The ISR is reset automatically, so do nothing here. */ +} + +static void mpuio_mask_irq(unsigned int irq) +{ + unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); + struct gpio_bank *bank = get_gpio_bank(gpio); + + _set_gpio_irqenable(bank, gpio, 0); +} + +static void mpuio_unmask_irq(unsigned int irq) +{ + unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); + struct gpio_bank *bank = get_gpio_bank(gpio); + + _set_gpio_irqenable(bank, gpio, 1); +} + +static struct irqchip gpio_irq_chip = { + .ack = gpio_ack_irq, + .mask = gpio_mask_irq, + .unmask = gpio_unmask_irq, +}; + +static struct irqchip mpuio_irq_chip = { + .ack = mpuio_ack_irq, + .mask = mpuio_mask_irq, + .unmask = mpuio_unmask_irq +}; + +static int initialized = 0; + +static int __init _omap_gpio_init(void) +{ + int i; + struct gpio_bank *bank; + + initialized = 1; + +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + printk(KERN_INFO "OMAP1510 GPIO hardware\n"); + gpio_bank_count = 2; + gpio_bank = gpio_bank_1510; + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (cpu_is_omap16xx()) { + int rev; + + gpio_bank_count = 5; + gpio_bank = gpio_bank_1610; + rev = omap_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION); + printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n", + (rev >> 4) & 0x0f, rev & 0x0f); + } +#endif +#ifdef CONFIG_ARCH_OMAP730 + if (cpu_is_omap730()) { + printk(KERN_INFO "OMAP730 GPIO hardware\n"); + gpio_bank_count = 7; + gpio_bank = gpio_bank_730; + } +#endif + for (i = 0; i < gpio_bank_count; i++) { + int j, gpio_count = 16; + + bank = &gpio_bank[i]; + bank->reserved_map = 0; + bank->base = IO_ADDRESS(bank->base); + spin_lock_init(&bank->lock); + if (bank->method == METHOD_MPUIO) { + omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT); + } +#ifdef CONFIG_ARCH_OMAP1510 + if (bank->method == METHOD_GPIO_1510) { + __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); + __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS); + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (bank->method == METHOD_GPIO_1610) { + __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1); + __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1); + } +#endif +#ifdef CONFIG_ARCH_OMAP730 + if (bank->method == METHOD_GPIO_730) { + __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK); + __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS); + + gpio_count = 32; /* 730 has 32-bit GPIOs */ + } +#endif + for (j = bank->virtual_irq_start; + j < bank->virtual_irq_start + gpio_count; j++) { + if (bank->method == METHOD_MPUIO) + set_irq_chip(j, &mpuio_irq_chip); + else + set_irq_chip(j, &gpio_irq_chip); + set_irq_handler(j, do_simple_IRQ); + set_irq_flags(j, IRQF_VALID); + } + set_irq_chained_handler(bank->irq, gpio_irq_handler); + set_irq_data(bank->irq, bank); + } + + /* Enable system clock for GPIO module. + * The CAM_CLK_CTRL *is* really the right place. */ + if (cpu_is_omap1610() || cpu_is_omap1710()) + omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL); + + return 0; +} + +/* + * This may get called early from board specific init + */ +int omap_gpio_init(void) +{ + if (!initialized) + return _omap_gpio_init(); + else + return 0; +} + +EXPORT_SYMBOL(omap_request_gpio); +EXPORT_SYMBOL(omap_free_gpio); +EXPORT_SYMBOL(omap_set_gpio_direction); +EXPORT_SYMBOL(omap_set_gpio_dataout); +EXPORT_SYMBOL(omap_get_gpio_datain); +EXPORT_SYMBOL(omap_set_gpio_edge_ctrl); + +arch_initcall(omap_gpio_init); diff --git a/arch/arm/mach-omap/irq.c b/arch/arm/mach-omap/irq.c new file mode 100644 index 0000000..f01c992 --- /dev/null +++ b/arch/arm/mach-omap/irq.c @@ -0,0 +1,219 @@ +/* + * linux/arch/arm/mach-omap/irq.c + * + * Interrupt handler for all OMAP boards + * + * Copyright (C) 2004 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.com> + * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com> + * + * Completely re-written to support various OMAP chips with bank specific + * interrupt handlers. + * + * Some snippets of the code taken from the older OMAP interrupt handler + * Copyright (C) 2001 RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com> + * + * GPIO interrupt handler moved to gpio.c by Juha Yrjola + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/arch/gpio.h> + +#include <asm/io.h> + +#define IRQ_BANK(irq) ((irq) >> 5) +#define IRQ_BIT(irq) ((irq) & 0x1f) + +struct omap_irq_bank { + unsigned long base_reg; + unsigned long trigger_map; +}; + +static unsigned int irq_bank_count = 0; +static struct omap_irq_bank *irq_banks; + +static inline unsigned int irq_bank_readl(int bank, int offset) +{ + return omap_readl(irq_banks[bank].base_reg + offset); +} + +static inline void irq_bank_writel(unsigned long value, int bank, int offset) +{ + omap_writel(value, irq_banks[bank].base_reg + offset); +} + +static void omap_ack_irq(unsigned int irq) +{ + if (irq > 31) + omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET); + + omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET); +} + +static void omap_mask_irq(unsigned int irq) +{ + int bank = IRQ_BANK(irq); + u32 l; + + l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); + l |= 1 << IRQ_BIT(irq); + omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); +} + +static void omap_unmask_irq(unsigned int irq) +{ + int bank = IRQ_BANK(irq); + u32 l; + + l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); + l &= ~(1 << IRQ_BIT(irq)); + omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); +} + +static void omap_mask_ack_irq(unsigned int irq) +{ + omap_mask_irq(irq); + omap_ack_irq(irq); +} + +/* + * Allows tuning the IRQ type and priority + * + * NOTE: There is currently no OMAP fiq handler for Linux. Read the + * mailing list threads on FIQ handlers if you are planning to + * add a FIQ handler for OMAP. + */ +static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger) +{ + signed int bank; + unsigned long val, offset; + + bank = IRQ_BANK(irq); + /* FIQ is only available on bank 0 interrupts */ + fiq = bank ? 0 : (fiq & 0x1); + val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1); + offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4; + irq_bank_writel(val, bank, offset); +} + +#ifdef CONFIG_ARCH_OMAP730 +static struct omap_irq_bank omap730_irq_banks[] = { + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, + { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 }, +}; +#endif + +#ifdef CONFIG_ARCH_OMAP1510 +static struct omap_irq_bank omap1510_irq_banks[] = { + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, +}; +#endif + +#if defined(CONFIG_ARCH_OMAP16XX) + +static struct omap_irq_bank omap1610_irq_banks[] = { + { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, + { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, + { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xfffff7ff }, + { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff }, +}; +#endif + +static struct irqchip omap_irq_chip = { + .ack = omap_mask_ack_irq, + .mask = omap_mask_irq, + .unmask = omap_unmask_irq, +}; + +void __init omap_init_irq(void) +{ + int i, j; + +#ifdef CONFIG_ARCH_OMAP730 + if (cpu_is_omap730()) { + irq_banks = omap730_irq_banks; + irq_bank_count = ARRAY_SIZE(omap730_irq_banks); + } +#endif +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + irq_banks = omap1510_irq_banks; + irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (cpu_is_omap16xx()) { + irq_banks = omap1610_irq_banks; + irq_bank_count = ARRAY_SIZE(omap1610_irq_banks); + } +#endif + printk("Total of %i interrupts in %i interrupt banks\n", + irq_bank_count * 32, irq_bank_count); + + /* Mask and clear all interrupts */ + for (i = 0; i < irq_bank_count; i++) { + irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET); + irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET); + } + + /* Clear any pending interrupts */ + irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET); + irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET); + + /* Enable interrupts in global mask */ + if (cpu_is_omap730()) { + irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET); + } + + /* Install the interrupt handlers for each bank */ + for (i = 0; i < irq_bank_count; i++) { + for (j = i * 32; j < (i + 1) * 32; j++) { + int irq_trigger; + + irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j); + omap_irq_set_cfg(j, 0, 0, irq_trigger); + + set_irq_chip(j, &omap_irq_chip); + set_irq_handler(j, do_level_IRQ); + set_irq_flags(j, IRQF_VALID); + } + } + + /* Unmask level 2 handler */ + if (cpu_is_omap730()) { + omap_unmask_irq(INT_730_IH2_IRQ); + } else { + omap_unmask_irq(INT_IH2_IRQ); + } +} diff --git a/arch/arm/mach-omap/leds-h2p2-debug.c b/arch/arm/mach-omap/leds-h2p2-debug.c new file mode 100644 index 0000000..6e98290 --- /dev/null +++ b/arch/arm/mach-omap/leds-h2p2-debug.c @@ -0,0 +1,144 @@ +/* + * linux/arch/arm/mach-omap/leds-h2p2-debug.c + * + * Copyright 2003 by Texas Instruments Incorporated + * + * There are 16 LEDs on the debug board (all green); four may be used + * for logical 'green', 'amber', 'red', and 'blue' (after "claiming"). + * + * The "surfer" expansion board and H2 sample board also have two-color + * green+red LEDs (in parallel), used here for timer and idle indicators. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/sched.h> +#include <linux/version.h> + +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include <asm/arch/fpga.h> +#include <asm/arch/gpio.h> + +#include "leds.h" + + +#define GPIO_LED_RED 3 +#define GPIO_LED_GREEN OMAP_MPUIO(4) + + +#define LED_STATE_ENABLED 0x01 +#define LED_STATE_CLAIMED 0x02 +#define LED_TIMER_ON 0x04 + +#define GPIO_IDLE GPIO_LED_GREEN +#define GPIO_TIMER GPIO_LED_RED + + +void h2p2_dbg_leds_event(led_event_t evt) +{ + unsigned long flags; + + static struct h2p2_dbg_fpga __iomem *fpga; + static u16 led_state, hw_led_state; + + local_irq_save(flags); + + if (!(led_state & LED_STATE_ENABLED) && evt != led_start) + goto done; + + switch (evt) { + case led_start: + if (!fpga) + fpga = ioremap(H2P2_DBG_FPGA_START, + H2P2_DBG_FPGA_SIZE); + if (fpga) { + led_state |= LED_STATE_ENABLED; + __raw_writew(~0, &fpga->leds); + } + break; + + case led_stop: + case led_halted: + /* all leds off during suspend or shutdown */ + omap_set_gpio_dataout(GPIO_TIMER, 0); + omap_set_gpio_dataout(GPIO_IDLE, 0); + __raw_writew(~0, &fpga->leds); + led_state &= ~LED_STATE_ENABLED; + if (evt == led_halted) { + iounmap(fpga); + fpga = NULL; + } + goto done; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + led_state ^= LED_TIMER_ON; + omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON); + goto done; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + omap_set_gpio_dataout(GPIO_IDLE, 1); + goto done; + + case led_idle_end: + omap_set_gpio_dataout(GPIO_IDLE, 0); + goto done; +#endif + + case led_green_on: + hw_led_state |= H2P2_DBG_FPGA_LED_GREEN; + break; + case led_green_off: + hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN; + break; + + case led_amber_on: + hw_led_state |= H2P2_DBG_FPGA_LED_AMBER; + break; + case led_amber_off: + hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER; + break; + + case led_red_on: + hw_led_state |= H2P2_DBG_FPGA_LED_RED; + break; + case led_red_off: + hw_led_state &= ~H2P2_DBG_FPGA_LED_RED; + break; + + case led_blue_on: + hw_led_state |= H2P2_DBG_FPGA_LED_BLUE; + break; + case led_blue_off: + hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE; + break; + + default: + break; + } + + + /* + * Actually burn the LEDs + */ + if (led_state & LED_STATE_CLAIMED) + __raw_writew(~hw_led_state, &fpga->leds); + +done: + local_irq_restore(flags); +} diff --git a/arch/arm/mach-omap/leds-innovator.c b/arch/arm/mach-omap/leds-innovator.c new file mode 100644 index 0000000..8043b7d --- /dev/null +++ b/arch/arm/mach-omap/leds-innovator.c @@ -0,0 +1,103 @@ +/* + * linux/arch/arm/mach-omap/leds-innovator.c + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +void innovator_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = 0; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= 0; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= 0; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~0; + break; +#endif + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~0; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= 0; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~0; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= 0; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + ; + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-omap/leds-osk.c b/arch/arm/mach-omap/leds-osk.c new file mode 100644 index 0000000..f5177f4 --- /dev/null +++ b/arch/arm/mach-omap/leds-osk.c @@ -0,0 +1,198 @@ +/* + * linux/arch/arm/mach-omap/leds-osk.c + * + * LED driver for OSK, and optionally Mistral QVGA, boards + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/workqueue.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/tps65010.h> + +#include "leds.h" + + +#define LED_STATE_ENABLED (1 << 0) +#define LED_STATE_CLAIMED (1 << 1) +static u8 led_state; + +#define GREEN_LED (1 << 0) /* TPS65010 LED1 */ +#define AMBER_LED (1 << 1) /* TPS65010 LED2 */ +#define RED_LED (1 << 2) /* TPS65010 GPIO2 */ +#define TIMER_LED (1 << 3) /* Mistral board */ +#define IDLE_LED (1 << 4) /* Mistral board */ +static u8 hw_led_state; + + +/* TPS65010 leds are changed using i2c -- from a task context. + * Using one of these for the "idle" LED would be impractical... + */ +#define TPS_LEDS (GREEN_LED | RED_LED | AMBER_LED) + +static u8 tps_leds_change; + +static void tps_work(void *unused) +{ + for (;;) { + u8 leds; + + local_irq_disable(); + leds = tps_leds_change; + tps_leds_change = 0; + local_irq_enable(); + + if (!leds) + break; + + /* careful: the set_led() value is on/off/blink */ + if (leds & GREEN_LED) + tps65010_set_led(LED1, !!(hw_led_state & GREEN_LED)); + if (leds & AMBER_LED) + tps65010_set_led(LED2, !!(hw_led_state & AMBER_LED)); + + /* the gpio led doesn't have that issue */ + if (leds & RED_LED) + tps65010_set_gpio_out_value(GPIO2, + !(hw_led_state & RED_LED)); + } +} + +static DECLARE_WORK(work, tps_work, NULL); + +#ifdef CONFIG_FB_OMAP + +/* For now, all system indicators require the Mistral board, since that + * LED can be manipulated without a task context. This LED is either red, + * or green, but not both; it can't give the full "disco led" effect. + */ + +#define GPIO_LED_RED 3 +#define GPIO_LED_GREEN OMAP_MPUIO(4) + +static void mistral_setled(void) +{ + int red = 0; + int green = 0; + + if (hw_led_state & TIMER_LED) + red = 1; + else if (hw_led_state & IDLE_LED) + green = 1; + // else both sides are disabled + + omap_set_gpio_dataout(GPIO_LED_GREEN, green); + omap_set_gpio_dataout(GPIO_LED_RED, red); +} + +#endif + +void osk_leds_event(led_event_t evt) +{ + unsigned long flags; + u16 leds; + + local_irq_save(flags); + + if (!(led_state & LED_STATE_ENABLED) && evt != led_start) + goto done; + + leds = hw_led_state; + switch (evt) { + case led_start: + led_state |= LED_STATE_ENABLED; + hw_led_state = 0; + leds = ~0; + break; + + case led_halted: + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + // NOTE: work may still be pending!! + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + leds = ~0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_FB_OMAP + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + hw_led_state ^= TIMER_LED; + mistral_setled(); + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + hw_led_state |= IDLE_LED; + mistral_setled(); + break; + + case led_idle_end: + hw_led_state &= ~IDLE_LED; + mistral_setled(); + break; +#endif + +#endif /* CONFIG_FB_OMAP */ + + /* "green" == tps LED1 (leftmost, normally power-good) + * works only with DC adapter, not on battery power! + */ + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GREEN_LED; + break; + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~GREEN_LED; + break; + + /* "amber" == tps LED2 (middle) */ + case led_amber_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= AMBER_LED; + break; + case led_amber_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~AMBER_LED; + break; + + /* "red" == LED on tps gpio3 (rightmost) */ + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= RED_LED; + break; + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~RED_LED; + break; + + default: + break; + } + + leds ^= hw_led_state; + leds &= TPS_LEDS; + if (leds && (led_state & LED_STATE_CLAIMED)) { + tps_leds_change |= leds; + schedule_work(&work); + } + +done: + local_irq_restore(flags); +} diff --git a/arch/arm/mach-omap/leds.c b/arch/arm/mach-omap/leds.c new file mode 100644 index 0000000..8ab21fe --- /dev/null +++ b/arch/arm/mach-omap/leds.c @@ -0,0 +1,61 @@ +/* + * linux/arch/arm/mach-omap/leds.c + * + * OMAP LEDs dispatcher + */ +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/leds.h> +#include <asm/mach-types.h> + +#include <asm/arch/gpio.h> +#include <asm/arch/mux.h> + +#include "leds.h" + +static int __init +omap_leds_init(void) +{ + if (machine_is_omap_innovator()) + leds_event = innovator_leds_event; + + else if (machine_is_omap_h2() || machine_is_omap_perseus2()) + leds_event = h2p2_dbg_leds_event; + + else if (machine_is_omap_osk()) + leds_event = osk_leds_event; + + else + return -1; + + if (machine_is_omap_h2() + || machine_is_omap_perseus2() + || machine_is_omap_osk()) { + + /* LED1/LED2 pins can be used as GPIO (as done here), or by + * the LPG (works even in deep sleep!), to drive a bicolor + * LED on the H2 sample board, and another on the H2/P2 + * "surfer" expansion board. + * + * The same pins drive a LED on the OSK Mistral board, but + * that's a different kind of LED (just one color at a time). + */ + omap_cfg_reg(P18_1610_GPIO3); + if (omap_request_gpio(3) == 0) + omap_set_gpio_direction(3, 0); + else + printk(KERN_WARNING "LED: can't get GPIO3/red?\n"); + + omap_cfg_reg(MPUIO4); + if (omap_request_gpio(OMAP_MPUIO(4)) == 0) + omap_set_gpio_direction(OMAP_MPUIO(4), 0); + else + printk(KERN_WARNING "LED: can't get MPUIO4/green?\n"); + } + + leds_event(led_start); + return 0; +} + +__initcall(omap_leds_init); diff --git a/arch/arm/mach-omap/leds.h b/arch/arm/mach-omap/leds.h new file mode 100644 index 0000000..a1e9fed --- /dev/null +++ b/arch/arm/mach-omap/leds.h @@ -0,0 +1,3 @@ +extern void innovator_leds_event(led_event_t evt); +extern void h2p2_dbg_leds_event(led_event_t evt); +extern void osk_leds_event(led_event_t evt); diff --git a/arch/arm/mach-omap/mcbsp.c b/arch/arm/mach-omap/mcbsp.c new file mode 100644 index 0000000..7c4ad77 --- /dev/null +++ b/arch/arm/mach-omap/mcbsp.c @@ -0,0 +1,685 @@ +/* + * linux/arch/arm/omap/mcbsp.c + * + * Copyright (C) 2004 Nokia Corporation + * Author: Samuel Ortiz <samuel.ortiz@nokia.com> + * + * + * 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. + * + * Multichannel mode not supported. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/wait.h> +#include <linux/completion.h> +#include <linux/interrupt.h> +#include <linux/err.h> + +#include <asm/delay.h> +#include <asm/io.h> +#include <asm/irq.h> + +#include <asm/arch/dma.h> +#include <asm/arch/mux.h> +#include <asm/arch/irqs.h> +#include <asm/arch/mcbsp.h> + +#include <asm/hardware/clock.h> + +#ifdef CONFIG_MCBSP_DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +struct omap_mcbsp { + u32 io_base; + u8 id; + u8 free; + omap_mcbsp_word_length rx_word_length; + omap_mcbsp_word_length tx_word_length; + + /* IRQ based TX/RX */ + int rx_irq; + int tx_irq; + + /* DMA stuff */ + u8 dma_rx_sync; + short dma_rx_lch; + u8 dma_tx_sync; + short dma_tx_lch; + + /* Completion queues */ + struct completion tx_irq_completion; + struct completion rx_irq_completion; + struct completion tx_dma_completion; + struct completion rx_dma_completion; + + spinlock_t lock; +}; + +static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; +static struct clk *mcbsp_dsp_ck = 0; +static struct clk *mcbsp_api_ck = 0; + + +static void omap_mcbsp_dump_reg(u8 id) +{ + DBG("**** MCBSP%d regs ****\n", mcbsp[id].id); + DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); + DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); + DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); + DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); + DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); + DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); + DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); + DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); + DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); + DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); + DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); + DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); + DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); + DBG("***********************\n"); +} + + +static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id); + + DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); + + complete(&mcbsp_tx->tx_irq_completion); + return IRQ_HANDLED; +} + +static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id); + + DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); + + complete(&mcbsp_rx->rx_irq_completion); + return IRQ_HANDLED; +} + + +static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) +{ + struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data); + + DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); + + /* We can free the channels */ + omap_free_dma(mcbsp_dma_tx->dma_tx_lch); + mcbsp_dma_tx->dma_tx_lch = -1; + + complete(&mcbsp_dma_tx->tx_dma_completion); +} + +static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) +{ + struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data); + + DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); + + /* We can free the channels */ + omap_free_dma(mcbsp_dma_rx->dma_rx_lch); + mcbsp_dma_rx->dma_rx_lch = -1; + + complete(&mcbsp_dma_rx->rx_dma_completion); +} + + +/* + * omap_mcbsp_config simply write a config to the + * appropriate McBSP. + * You either call this function or set the McBSP registers + * by yourself before calling omap_mcbsp_start(). + */ + +void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config) +{ + u32 io_base = mcbsp[id].io_base; + + DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base); + + /* We write the given config */ + OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); + OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1); + OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2); + OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1); + OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2); + OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1); + OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2); + OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1); + OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2); + OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); + OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); +} + + + +static int omap_mcbsp_check(unsigned int id) +{ + if (cpu_is_omap730()) { + if (id > OMAP_MAX_MCBSP_COUNT - 1) { + printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); + return -1; + } + return 0; + } + + if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) { + if (id > OMAP_MAX_MCBSP_COUNT) { + printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); + return -1; + } + return 0; + } + + return -1; +} + +#define EN_XORPCK 1 +#define DSP_RSTCT2 0xe1008014 + +static void omap_mcbsp_dsp_request(void) +{ + if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) { + omap_writew((omap_readw(ARM_RSTCT1) | (1 << 1) | (1 << 2)), + ARM_RSTCT1); + clk_enable(mcbsp_dsp_ck); + clk_enable(mcbsp_api_ck); + + /* enable 12MHz clock to mcbsp 1 & 3 */ + __raw_writew(__raw_readw(DSP_IDLECT2) | (1 << EN_XORPCK), + DSP_IDLECT2); + __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1, + DSP_RSTCT2); + } +} + +static void omap_mcbsp_dsp_free(void) +{ + /* Useless for now */ +} + + +int omap_mcbsp_request(unsigned int id) +{ + int err; + + if (omap_mcbsp_check(id) < 0) + return -EINVAL; + + /* + * On 1510, 1610 and 1710, McBSP1 and McBSP3 + * are DSP public peripherals. + */ + if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) + omap_mcbsp_dsp_request(); + + spin_lock(&mcbsp[id].lock); + if (!mcbsp[id].free) { + printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); + spin_unlock(&mcbsp[id].lock); + return -1; + } + + mcbsp[id].free = 0; + spin_unlock(&mcbsp[id].lock); + + /* We need to get IRQs here */ + err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, + "McBSP", + (void *) (&mcbsp[id])); + if (err != 0) { + printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", + mcbsp[id].tx_irq, mcbsp[id].id); + return err; + } + + init_completion(&(mcbsp[id].tx_irq_completion)); + + + err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, + "McBSP", + (void *) (&mcbsp[id])); + if (err != 0) { + printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", + mcbsp[id].rx_irq, mcbsp[id].id); + free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); + return err; + } + + init_completion(&(mcbsp[id].rx_irq_completion)); + return 0; + +} + +void omap_mcbsp_free(unsigned int id) +{ + if (omap_mcbsp_check(id) < 0) + return; + + if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) + omap_mcbsp_dsp_free(); + + spin_lock(&mcbsp[id].lock); + if (mcbsp[id].free) { + printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1); + spin_unlock(&mcbsp[id].lock); + return; + } + + mcbsp[id].free = 1; + spin_unlock(&mcbsp[id].lock); + + /* Free IRQs */ + free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); + free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); +} + +/* + * Here we start the McBSP, by enabling the sample + * generator, both transmitter and receivers, + * and the frame sync. + */ +void omap_mcbsp_start(unsigned int id) +{ + u32 io_base; + u16 w; + + if (omap_mcbsp_check(id) < 0) + return; + + io_base = mcbsp[id].io_base; + + mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7); + mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7); + + /* Start the sample generator */ + w = OMAP_MCBSP_READ(io_base, SPCR2); + OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6)); + + /* Enable transmitter and receiver */ + w = OMAP_MCBSP_READ(io_base, SPCR2); + OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1); + + w = OMAP_MCBSP_READ(io_base, SPCR1); + OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1); + + udelay(100); + + /* Start frame sync */ + w = OMAP_MCBSP_READ(io_base, SPCR2); + OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7)); + + /* Dump McBSP Regs */ + omap_mcbsp_dump_reg(id); + +} + +void omap_mcbsp_stop(unsigned int id) +{ + u32 io_base; + u16 w; + + if (omap_mcbsp_check(id) < 0) + return; + + io_base = mcbsp[id].io_base; + + /* Reset transmitter */ + w = OMAP_MCBSP_READ(io_base, SPCR2); + OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1)); + + /* Reset receiver */ + w = OMAP_MCBSP_READ(io_base, SPCR1); + OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1)); + + /* Reset the sample rate generator */ + w = OMAP_MCBSP_READ(io_base, SPCR2); + OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); +} + + +/* + * IRQ based word transmission. + */ +void omap_mcbsp_xmit_word(unsigned int id, u32 word) +{ + u32 io_base; + omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length; + + if (omap_mcbsp_check(id) < 0) + return; + + io_base = mcbsp[id].io_base; + + wait_for_completion(&(mcbsp[id].tx_irq_completion)); + + if (word_length > OMAP_MCBSP_WORD_16) + OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); + OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); +} + +u32 omap_mcbsp_recv_word(unsigned int id) +{ + u32 io_base; + u16 word_lsb, word_msb = 0; + omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length; + + if (omap_mcbsp_check(id) < 0) + return -EINVAL; + + io_base = mcbsp[id].io_base; + + wait_for_completion(&(mcbsp[id].rx_irq_completion)); + + if (word_length > OMAP_MCBSP_WORD_16) + word_msb = OMAP_MCBSP_READ(io_base, DRR2); + word_lsb = OMAP_MCBSP_READ(io_base, DRR1); + + return (word_lsb | (word_msb << 16)); +} + + +/* + * Simple DMA based buffer rx/tx routines. + * Nothing fancy, just a single buffer tx/rx through DMA. + * The DMA resources are released once the transfer is done. + * For anything fancier, you should use your own customized DMA + * routines and callbacks. + */ +int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) +{ + int dma_tx_ch; + + if (omap_mcbsp_check(id) < 0) + return -EINVAL; + + if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback, + &mcbsp[id], + &dma_tx_ch)) { + printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1); + return -EAGAIN; + } + mcbsp[id].dma_tx_lch = dma_tx_ch; + + DBG("TX DMA on channel %d\n", dma_tx_ch); + + init_completion(&(mcbsp[id].tx_dma_completion)); + + omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, + OMAP_DMA_DATA_TYPE_S16, + length >> 1, 1, + OMAP_DMA_SYNC_ELEMENT); + + omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, + OMAP_DMA_PORT_TIPB, + OMAP_DMA_AMODE_CONSTANT, + mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1); + + omap_set_dma_src_params(mcbsp[id].dma_tx_lch, + OMAP_DMA_PORT_EMIFF, + OMAP_DMA_AMODE_POST_INC, + buffer); + + omap_start_dma(mcbsp[id].dma_tx_lch); + wait_for_completion(&(mcbsp[id].tx_dma_completion)); + return 0; +} + + +int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) +{ + int dma_rx_ch; + + if (omap_mcbsp_check(id) < 0) + return -EINVAL; + + if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback, + &mcbsp[id], + &dma_rx_ch)) { + printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1); + return -EAGAIN; + } + mcbsp[id].dma_rx_lch = dma_rx_ch; + + DBG("RX DMA on channel %d\n", dma_rx_ch); + + init_completion(&(mcbsp[id].rx_dma_completion)); + + omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, + OMAP_DMA_DATA_TYPE_S16, + length >> 1, 1, + OMAP_DMA_SYNC_ELEMENT); + + omap_set_dma_src_params(mcbsp[id].dma_rx_lch, + OMAP_DMA_PORT_TIPB, + OMAP_DMA_AMODE_CONSTANT, + mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1); + + omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, + OMAP_DMA_PORT_EMIFF, + OMAP_DMA_AMODE_POST_INC, + buffer); + + omap_start_dma(mcbsp[id].dma_rx_lch); + wait_for_completion(&(mcbsp[id].rx_dma_completion)); + return 0; +} + + +/* + * SPI wrapper. + * Since SPI setup is much simpler than the generic McBSP one, + * this wrapper just need an omap_mcbsp_spi_cfg structure as an input. + * Once this is done, you can call omap_mcbsp_start(). + */ +void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg) +{ + struct omap_mcbsp_reg_cfg mcbsp_cfg; + + if (omap_mcbsp_check(id) < 0) + return; + + memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); + + /* SPI has only one frame */ + mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0)); + mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0)); + + /* Clock stop mode */ + if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY) + mcbsp_cfg.spcr1 |= (1 << 12); + else + mcbsp_cfg.spcr1 |= (3 << 11); + + /* Set clock parities */ + if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING) + mcbsp_cfg.pcr0 |= CLKRP; + else + mcbsp_cfg.pcr0 &= ~CLKRP; + + if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING) + mcbsp_cfg.pcr0 &= ~CLKXP; + else + mcbsp_cfg.pcr0 |= CLKXP; + + /* Set SCLKME to 0 and CLKSM to 1 */ + mcbsp_cfg.pcr0 &= ~SCLKME; + mcbsp_cfg.srgr2 |= CLKSM; + + /* Set FSXP */ + if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH) + mcbsp_cfg.pcr0 &= ~FSXP; + else + mcbsp_cfg.pcr0 |= FSXP; + + if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) { + mcbsp_cfg.pcr0 |= CLKXM; + mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1); + mcbsp_cfg.pcr0 |= FSXM; + mcbsp_cfg.srgr2 &= ~FSGM; + mcbsp_cfg.xcr2 |= XDATDLY(1); + mcbsp_cfg.rcr2 |= RDATDLY(1); + } + else { + mcbsp_cfg.pcr0 &= ~CLKXM; + mcbsp_cfg.srgr1 |= CLKGDV(1); + mcbsp_cfg.pcr0 &= ~FSXM; + mcbsp_cfg.xcr2 &= ~XDATDLY(3); + mcbsp_cfg.rcr2 &= ~RDATDLY(3); + } + + mcbsp_cfg.xcr2 &= ~XPHASE; + mcbsp_cfg.rcr2 &= ~RPHASE; + + omap_mcbsp_config(id, &mcbsp_cfg); +} + + +/* + * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. + * 730 has only 2 McBSP, and both of them are MPU peripherals. + */ +struct omap_mcbsp_info { + u32 virt_base; + u8 dma_rx_sync, dma_tx_sync; + u16 rx_irq, tx_irq; +}; + +#ifdef CONFIG_ARCH_OMAP730 +static const struct omap_mcbsp_info mcbsp_730[] = { + [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE), + .dma_rx_sync = OMAP_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP_DMA_MCBSP1_TX, + .rx_irq = INT_730_McBSP1RX, + .tx_irq = INT_730_McBSP1TX }, + [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE), + .dma_rx_sync = OMAP_DMA_MCBSP3_RX, + .dma_tx_sync = OMAP_DMA_MCBSP3_TX, + .rx_irq = INT_730_McBSP2RX, + .tx_irq = INT_730_McBSP2TX }, +}; +#endif + +#ifdef CONFIG_ARCH_OMAP1510 +static const struct omap_mcbsp_info mcbsp_1510[] = { + [0] = { .virt_base = OMAP1510_MCBSP1_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP_DMA_MCBSP1_TX, + .rx_irq = INT_McBSP1RX, + .tx_irq = INT_McBSP1TX }, + [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE), + .dma_rx_sync = OMAP_DMA_MCBSP2_RX, + .dma_tx_sync = OMAP_DMA_MCBSP2_TX, + .rx_irq = INT_1510_SPI_RX, + .tx_irq = INT_1510_SPI_TX }, + [2] = { .virt_base = OMAP1510_MCBSP3_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP3_RX, + .dma_tx_sync = OMAP_DMA_MCBSP3_TX, + .rx_irq = INT_McBSP3RX, + .tx_irq = INT_McBSP3TX }, +}; +#endif + +#if defined(CONFIG_ARCH_OMAP16XX) +static const struct omap_mcbsp_info mcbsp_1610[] = { + [0] = { .virt_base = OMAP1610_MCBSP1_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP_DMA_MCBSP1_TX, + .rx_irq = INT_McBSP1RX, + .tx_irq = INT_McBSP1TX }, + [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE), + .dma_rx_sync = OMAP_DMA_MCBSP2_RX, + .dma_tx_sync = OMAP_DMA_MCBSP2_TX, + .rx_irq = INT_1610_McBSP2_RX, + .tx_irq = INT_1610_McBSP2_TX }, + [2] = { .virt_base = OMAP1610_MCBSP3_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP3_RX, + .dma_tx_sync = OMAP_DMA_MCBSP3_TX, + .rx_irq = INT_McBSP3RX, + .tx_irq = INT_McBSP3TX }, +}; +#endif + +static int __init omap_mcbsp_init(void) +{ + int mcbsp_count = 0, i; + static const struct omap_mcbsp_info *mcbsp_info; + + printk("Initializing OMAP McBSP system\n"); + + mcbsp_dsp_ck = clk_get(0, "dsp_ck"); + if (IS_ERR(mcbsp_dsp_ck)) { + printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); + return PTR_ERR(mcbsp_dsp_ck); + } + mcbsp_api_ck = clk_get(0, "api_ck"); + if (IS_ERR(mcbsp_dsp_ck)) { + printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n"); + return PTR_ERR(mcbsp_api_ck); + } + +#ifdef CONFIG_ARCH_OMAP730 + if (cpu_is_omap730()) { + mcbsp_info = mcbsp_730; + mcbsp_count = ARRAY_SIZE(mcbsp_730); + } +#endif +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + mcbsp_info = mcbsp_1510; + mcbsp_count = ARRAY_SIZE(mcbsp_1510); + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (cpu_is_omap1610() || cpu_is_omap1710()) { + mcbsp_info = mcbsp_1610; + mcbsp_count = ARRAY_SIZE(mcbsp_1610); + } +#endif + for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { + if (i >= mcbsp_count) { + mcbsp[i].io_base = 0; + mcbsp[i].free = 0; + continue; + } + mcbsp[i].id = i + 1; + mcbsp[i].free = 1; + mcbsp[i].dma_tx_lch = -1; + mcbsp[i].dma_rx_lch = -1; + + mcbsp[i].io_base = mcbsp_info[i].virt_base; + mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; + mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; + mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; + mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync; + spin_lock_init(&mcbsp[i].lock); + } + + return 0; +} + + +arch_initcall(omap_mcbsp_init); + +EXPORT_SYMBOL(omap_mcbsp_config); +EXPORT_SYMBOL(omap_mcbsp_request); +EXPORT_SYMBOL(omap_mcbsp_free); +EXPORT_SYMBOL(omap_mcbsp_start); +EXPORT_SYMBOL(omap_mcbsp_stop); +EXPORT_SYMBOL(omap_mcbsp_xmit_word); +EXPORT_SYMBOL(omap_mcbsp_recv_word); +EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); +EXPORT_SYMBOL(omap_mcbsp_recv_buffer); +EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); diff --git a/arch/arm/mach-omap/mux.c b/arch/arm/mach-omap/mux.c new file mode 100644 index 0000000..bcf3c6e --- /dev/null +++ b/arch/arm/mach-omap/mux.c @@ -0,0 +1,163 @@ +/* + * linux/arch/arm/mach-omap/mux.c + * + * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h + * + * Copyright (C) 2003 Nokia Corporation + * + * Written by Tony Lindgren <tony.lindgren@nokia.com> + * + * 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/module.h> +#include <linux/init.h> +#include <asm/system.h> +#include <asm/io.h> +#include <linux/spinlock.h> + +#define __MUX_C__ +#include <asm/arch/mux.h> + +#ifdef CONFIG_OMAP_MUX + +/* + * Sets the Omap MUX and PULL_DWN registers based on the table + */ +int __init_or_module +omap_cfg_reg(const reg_cfg_t reg_cfg) +{ + static DEFINE_SPINLOCK(mux_spin_lock); + + unsigned long flags; + reg_cfg_set *cfg; + unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, + pull_orig = 0, pull = 0; + unsigned int mask, warn = 0; + + if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) { + printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg); + return -EINVAL; + } + + cfg = ®_cfg_table[reg_cfg]; + + /* + * We do a pretty long section here with lock on, but pin muxing + * should only happen on driver init for each driver, so it's not time + * critical. + */ + spin_lock_irqsave(&mux_spin_lock, flags); + + /* Check the mux register in question */ + if (cfg->mux_reg) { + unsigned tmp1, tmp2; + + reg_orig = omap_readl(cfg->mux_reg); + + /* The mux registers always seem to be 3 bits long */ + mask = (0x7 << cfg->mask_offset); + tmp1 = reg_orig & mask; + reg = reg_orig & ~mask; + + tmp2 = (cfg->mask << cfg->mask_offset); + reg |= tmp2; + + if (tmp1 != tmp2) + warn = 1; + + omap_writel(reg, cfg->mux_reg); + } + + /* Check for pull up or pull down selection on 1610 */ + if (!cpu_is_omap1510()) { + if (cfg->pu_pd_reg && cfg->pull_val) { + pu_pd_orig = omap_readl(cfg->pu_pd_reg); + mask = 1 << cfg->pull_bit; + + if (cfg->pu_pd_val) { + if (!(pu_pd_orig & mask)) + warn = 1; + /* Use pull up */ + pu_pd = pu_pd_orig | mask; + } else { + if (pu_pd_orig & mask) + warn = 1; + /* Use pull down */ + pu_pd = pu_pd_orig & ~mask; + } + omap_writel(pu_pd, cfg->pu_pd_reg); + } + } + + /* Check for an associated pull down register */ + if (cfg->pull_reg) { + pull_orig = omap_readl(cfg->pull_reg); + mask = 1 << cfg->pull_bit; + + if (cfg->pull_val) { + if (pull_orig & mask) + warn = 1; + /* Low bit = pull enabled */ + pull = pull_orig & ~mask; + } else { + if (!(pull_orig & mask)) + warn = 1; + /* High bit = pull disabled */ + pull = pull_orig | mask; + } + + omap_writel(pull, cfg->pull_reg); + } + + if (warn) { +#ifdef CONFIG_OMAP_MUX_WARNINGS + printk(KERN_WARNING "MUX: initialized %s\n", cfg->name); +#endif + } + +#ifdef CONFIG_OMAP_MUX_DEBUG + if (cfg->debug || warn) { + printk("MUX: Setting register %s\n", cfg->name); + printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", + cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg); + + if (!cpu_is_omap1510()) { + if (cfg->pu_pd_reg && cfg->pull_val) { + printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", + cfg->pu_pd_name, cfg->pu_pd_reg, + pu_pd_orig, pu_pd); + } + } + + if (cfg->pull_reg) + printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", + cfg->pull_name, cfg->pull_reg, pull_orig, pull); + } +#endif + + spin_unlock_irqrestore(&mux_spin_lock, flags); + +#ifdef CONFIG_OMAP_MUX_ERRORS + return warn ? -ETXTBSY : 0; +#else + return 0; +#endif +} + +EXPORT_SYMBOL(omap_cfg_reg); + +#endif /* CONFIG_OMAP_MUX */ diff --git a/arch/arm/mach-omap/ocpi.c b/arch/arm/mach-omap/ocpi.c new file mode 100644 index 0000000..c9ced13 --- /dev/null +++ b/arch/arm/mach-omap/ocpi.c @@ -0,0 +1,114 @@ +/* + * linux/arch/arm/mach-omap/ocpi.c + * + * Minimal OCP bus support for omap16xx + * + * Copyright (C) 2003 - 2005 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.com> + * + * Modified for clock framework by Paul Mundt <paul.mundt@nokia.com>. + * + * 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/module.h> +#include <linux/version.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/err.h> + +#include <asm/io.h> +#include <asm/hardware/clock.h> +#include <asm/arch/hardware.h> + +#define OCPI_BASE 0xfffec320 +#define OCPI_FAULT (OCPI_BASE + 0x00) +#define OCPI_CMD_FAULT (OCPI_BASE + 0x04) +#define OCPI_SINT0 (OCPI_BASE + 0x08) +#define OCPI_TABORT (OCPI_BASE + 0x0c) +#define OCPI_SINT1 (OCPI_BASE + 0x10) +#define OCPI_PROT (OCPI_BASE + 0x14) +#define OCPI_SEC (OCPI_BASE + 0x18) + +/* USB OHCI OCPI access error registers */ +#define HOSTUEADDR 0xfffba0e0 +#define HOSTUESTATUS 0xfffba0e4 + +static struct clk *ocpi_ck; + +/* + * Enables device access to OMAP buses via the OCPI bridge + * FIXME: Add locking + */ +int ocpi_enable(void) +{ + unsigned int val; + + if (!cpu_is_omap16xx()) + return -ENODEV; + + /* Make sure there's clock for OCPI */ + clk_enable(ocpi_ck); + + /* Enable access for OHCI in OCPI */ + val = omap_readl(OCPI_PROT); + val &= ~0xff; + //val &= (1 << 0); /* Allow access only to EMIFS */ + omap_writel(val, OCPI_PROT); + + val = omap_readl(OCPI_SEC); + val &= ~0xff; + omap_writel(val, OCPI_SEC); + + return 0; +} +EXPORT_SYMBOL(ocpi_enable); + +static int __init omap_ocpi_init(void) +{ + if (!cpu_is_omap16xx()) + return -ENODEV; + + ocpi_ck = clk_get(NULL, "l3_ocpi_ck"); + if (IS_ERR(ocpi_ck)) + return PTR_ERR(ocpi_ck); + + clk_use(ocpi_ck); + ocpi_enable(); + printk("OMAP OCPI interconnect driver loaded\n"); + + return 0; +} + +static void __exit omap_ocpi_exit(void) +{ + /* REVISIT: Disable OCPI */ + + if (!cpu_is_omap16xx()) + return; + + clk_unuse(ocpi_ck); + clk_put(ocpi_ck); +} + +MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>"); +MODULE_DESCRIPTION("OMAP OCPI bus controller module"); +MODULE_LICENSE("GPL"); +module_init(omap_ocpi_init); +module_exit(omap_ocpi_exit); diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c new file mode 100644 index 0000000..00fac15 --- /dev/null +++ b/arch/arm/mach-omap/pm.c @@ -0,0 +1,628 @@ +/* + * linux/arch/arm/mach-omap/pm.c + * + * OMAP Power Management Routines + * + * Original code for the SA11x0: + * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> + * + * Modified for the PXA250 by Nicolas Pitre: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Modified for the OMAP1510 by David Singleton: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/pm.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> +#include <linux/pm.h> + +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/arch/omap16xx.h> +#include <asm/arch/pm.h> +#include <asm/arch/mux.h> +#include <asm/arch/tc.h> +#include <asm/arch/tps65010.h> + +#include "clock.h" + +static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; +static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; +static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; +static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; + +/* + * Let's power down on idle, but only if we are really + * idle, because once we start down the path of + * going idle we continue to do idle even if we get + * a clock tick interrupt . . + */ +void omap_pm_idle(void) +{ + int (*func_ptr)(void) = 0; + unsigned int mask32 = 0; + + /* + * If the DSP is being used let's just idle the CPU, the overhead + * to wake up from Big Sleep is big, milliseconds versus micro + * seconds for wait for interrupt. + */ + + local_irq_disable(); + local_fiq_disable(); + if (need_resched()) { + local_fiq_enable(); + local_irq_enable(); + return; + } + mask32 = omap_readl(ARM_SYSST); + local_fiq_enable(); + local_irq_enable(); + +#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ) + /* Override timer to use VST for the next cycle */ + omap_32k_timer_next_vst_interrupt(); +#endif + + if ((mask32 & DSP_IDLE) == 0) { + __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); + } else { + + if (cpu_is_omap1510()) { + func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND); + } else if (cpu_is_omap1610() || cpu_is_omap1710()) { + func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND); + } else if (cpu_is_omap5912()) { + func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND); + } + + func_ptr(); + } +} + +/* + * Configuration of the wakeup event is board specific. For the + * moment we put it into this helper function. Later it may move + * to board specific files. + */ +static void omap_pm_wakeup_setup(void) +{ + /* + * Enable ARM XOR clock and release peripheral from reset by + * writing 1 to PER_EN bit in ARM_RSTCT2, this is required + * for UART configuration to use UART2 to wake up. + */ + + omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2); + omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2); + omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL); + + /* + * Turn off all interrupts except L1-2nd level cascade, + * and the L2 wakeup interrupts: keypad and UART2. + */ + + omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR); + + if (cpu_is_omap1510()) { + omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_MIR); + } + + if (cpu_is_omap16xx()) { + omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR); + + omap_writel(~0x0, OMAP_IH2_1_MIR); + omap_writel(~0x0, OMAP_IH2_2_MIR); + omap_writel(~0x0, OMAP_IH2_3_MIR); + } + + /* New IRQ agreement */ + omap_writel(1, OMAP_IH1_CONTROL); + + /* external PULL to down, bit 22 = 0 */ + omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2); +} + +void omap_pm_suspend(void) +{ + unsigned int mask32 = 0; + unsigned long arg0 = 0, arg1 = 0; + int (*func_ptr)(unsigned short, unsigned short) = 0; + unsigned short save_dsp_idlect2; + + printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev); + + if (machine_is_omap_osk()) { + /* Stop LED1 (D9) blink */ + tps65010_set_led(LED1, OFF); + } + + /* + * Step 1: turn off interrupts + */ + + local_irq_disable(); + local_fiq_disable(); + + /* + * Step 2: save registers + * + * The omap is a strange/beautiful device. The caches, memory + * and register state are preserved across power saves. + * We have to save and restore very little register state to + * idle the omap. + * + * Save interrupt, MPUI, ARM and UPLD control registers. + */ + + if (cpu_is_omap1510()) { + MPUI1510_SAVE(OMAP_IH1_MIR); + MPUI1510_SAVE(OMAP_IH2_MIR); + MPUI1510_SAVE(MPUI_CTRL); + MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI1510_SAVE(MPUI_DSP_API_CONFIG); + MPUI1510_SAVE(EMIFS_CONFIG); + MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); + } else if (cpu_is_omap16xx()) { + MPUI1610_SAVE(OMAP_IH1_MIR); + MPUI1610_SAVE(OMAP_IH2_0_MIR); + MPUI1610_SAVE(OMAP_IH2_1_MIR); + MPUI1610_SAVE(OMAP_IH2_2_MIR); + MPUI1610_SAVE(OMAP_IH2_3_MIR); + MPUI1610_SAVE(MPUI_CTRL); + MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI1610_SAVE(MPUI_DSP_API_CONFIG); + MPUI1610_SAVE(EMIFS_CONFIG); + MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); + } + + ARM_SAVE(ARM_CKCTL); + ARM_SAVE(ARM_IDLECT1); + ARM_SAVE(ARM_IDLECT2); + ARM_SAVE(ARM_EWUPCT); + ARM_SAVE(ARM_RSTCT1); + ARM_SAVE(ARM_RSTCT2); + ARM_SAVE(ARM_SYSST); + ULPD_SAVE(ULPD_CLOCK_CTRL); + ULPD_SAVE(ULPD_STATUS_REQ); + + /* + * Step 3: LOW_PWR signal enabling + * + * Allow the LOW_PWR signal to be visible on MPUIO5 ball. + */ + if (cpu_is_omap1510()) { + /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */ + omap_writew(omap_readw(ULPD_POWER_CTRL) | + OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); + } else if (cpu_is_omap16xx()) { + /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */ + omap_writew(omap_readw(ULPD_POWER_CTRL) | + OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); + } + + /* configure LOW_PWR pin */ + omap_cfg_reg(T20_1610_LOW_PWR); + + /* + * Step 4: OMAP DSP Shutdown + */ + + /* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */ + omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE, + ARM_RSTCT1); + + /* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */ + omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG); + + /* Set EN_DSPCK = 0, stop DSP block clock */ + omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL); + + /* Stop any DSP domain clocks */ + omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2); + save_dsp_idlect2 = __raw_readw(DSP_IDLECT2); + __raw_writew(0, DSP_IDLECT2); + + /* + * Step 5: Wakeup Event Setup + */ + + omap_pm_wakeup_setup(); + + /* + * Step 6a: ARM and Traffic controller shutdown + * + * Step 6 starts here with clock and watchdog disable + */ + + /* stop clocks */ + mask32 = omap_readl(ARM_IDLECT2); + mask32 &= ~(1<<EN_WDTCK); /* bit 0 -> 0 (WDT clock) */ + mask32 |= (1<<EN_XORPCK); /* bit 1 -> 1 (XORPCK clock) */ + mask32 &= ~(1<<EN_PERCK); /* bit 2 -> 0 (MPUPER_CK clock) */ + mask32 &= ~(1<<EN_LCDCK); /* bit 3 -> 0 (LCDC clock) */ + mask32 &= ~(1<<EN_LBCK); /* bit 4 -> 0 (local bus clock) */ + mask32 |= (1<<EN_APICK); /* bit 6 -> 1 (MPUI clock) */ + mask32 &= ~(1<<EN_TIMCK); /* bit 7 -> 0 (MPU timer clock) */ + mask32 &= ~(1<<DMACK_REQ); /* bit 8 -> 0 (DMAC clock) */ + mask32 &= ~(1<<EN_GPIOCK); /* bit 9 -> 0 (GPIO clock) */ + omap_writel(mask32, ARM_IDLECT2); + + /* disable ARM watchdog */ + omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); + omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); + + /* + * Step 6b: ARM and Traffic controller shutdown + * + * Step 6 continues here. Prepare jump to power management + * assembly code in internal SRAM. + * + * Since the omap_cpu_suspend routine has been copied to + * SRAM, we'll do an indirect procedure call to it and pass the + * contents of arm_idlect1 and arm_idlect2 so it can restore + * them when it wakes up and it will return. + */ + + arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; + arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; + + if (cpu_is_omap1510()) { + func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND); + } else if (cpu_is_omap1610() || cpu_is_omap1710()) { + func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND); + } else if (cpu_is_omap5912()) { + func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND); + } + + /* + * Step 6c: ARM and Traffic controller shutdown + * + * Jump to assembly code. The processor will stay there + * until wake up. + */ + + func_ptr(arg0, arg1); + + /* + * If we are here, processor is woken up! + */ + + if (cpu_is_omap1510()) { + /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */ + omap_writew(omap_readw(ULPD_POWER_CTRL) & + ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); + } else if (cpu_is_omap16xx()) { + /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */ + omap_writew(omap_readw(ULPD_POWER_CTRL) & + ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); + } + + + /* Restore DSP clocks */ + omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2); + __raw_writew(save_dsp_idlect2, DSP_IDLECT2); + ARM_RESTORE(ARM_IDLECT2); + + /* + * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did + */ + + ARM_RESTORE(ARM_CKCTL); + ARM_RESTORE(ARM_EWUPCT); + ARM_RESTORE(ARM_RSTCT1); + ARM_RESTORE(ARM_RSTCT2); + ARM_RESTORE(ARM_SYSST); + ULPD_RESTORE(ULPD_CLOCK_CTRL); + ULPD_RESTORE(ULPD_STATUS_REQ); + + if (cpu_is_omap1510()) { + MPUI1510_RESTORE(MPUI_CTRL); + MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); + MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); + MPUI1510_RESTORE(EMIFS_CONFIG); + MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG); + MPUI1510_RESTORE(OMAP_IH1_MIR); + MPUI1510_RESTORE(OMAP_IH2_MIR); + } else if (cpu_is_omap16xx()) { + MPUI1610_RESTORE(MPUI_CTRL); + MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG); + MPUI1610_RESTORE(MPUI_DSP_API_CONFIG); + MPUI1610_RESTORE(EMIFS_CONFIG); + MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG); + + MPUI1610_RESTORE(OMAP_IH1_MIR); + MPUI1610_RESTORE(OMAP_IH2_0_MIR); + MPUI1610_RESTORE(OMAP_IH2_1_MIR); + MPUI1610_RESTORE(OMAP_IH2_2_MIR); + MPUI1610_RESTORE(OMAP_IH2_3_MIR); + } + + /* + * Reenable interrupts + */ + + local_irq_enable(); + local_fiq_enable(); + + printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); + + if (machine_is_omap_osk()) { + /* Let LED1 (D9) blink again */ + tps65010_set_led(LED1, BLINK); + } +} + +#if defined(DEBUG) && defined(CONFIG_PROC_FS) +static int g_read_completed; + +/* + * Read system PM registers for debugging + */ +static int omap_pm_read_proc( + char *page_buffer, + char **my_first_byte, + off_t virtual_start, + int length, + int *eof, + void *data) +{ + int my_buffer_offset = 0; + char * const my_base = page_buffer; + + ARM_SAVE(ARM_CKCTL); + ARM_SAVE(ARM_IDLECT1); + ARM_SAVE(ARM_IDLECT2); + ARM_SAVE(ARM_EWUPCT); + ARM_SAVE(ARM_RSTCT1); + ARM_SAVE(ARM_RSTCT2); + ARM_SAVE(ARM_SYSST); + + ULPD_SAVE(ULPD_IT_STATUS); + ULPD_SAVE(ULPD_CLOCK_CTRL); + ULPD_SAVE(ULPD_SOFT_REQ); + ULPD_SAVE(ULPD_STATUS_REQ); + ULPD_SAVE(ULPD_DPLL_CTRL); + ULPD_SAVE(ULPD_POWER_CTRL); + + if (cpu_is_omap1510()) { + MPUI1510_SAVE(MPUI_CTRL); + MPUI1510_SAVE(MPUI_DSP_STATUS); + MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI1510_SAVE(MPUI_DSP_API_CONFIG); + MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); + MPUI1510_SAVE(EMIFS_CONFIG); + } else if (cpu_is_omap16xx()) { + MPUI1610_SAVE(MPUI_CTRL); + MPUI1610_SAVE(MPUI_DSP_STATUS); + MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI1610_SAVE(MPUI_DSP_API_CONFIG); + MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); + MPUI1610_SAVE(EMIFS_CONFIG); + } + + if (virtual_start == 0) { + g_read_completed = 0; + + my_buffer_offset += sprintf(my_base + my_buffer_offset, + "ARM_CKCTL_REG: 0x%-8x \n" + "ARM_IDLECT1_REG: 0x%-8x \n" + "ARM_IDLECT2_REG: 0x%-8x \n" + "ARM_EWUPCT_REG: 0x%-8x \n" + "ARM_RSTCT1_REG: 0x%-8x \n" + "ARM_RSTCT2_REG: 0x%-8x \n" + "ARM_SYSST_REG: 0x%-8x \n" + "ULPD_IT_STATUS_REG: 0x%-4x \n" + "ULPD_CLOCK_CTRL_REG: 0x%-4x \n" + "ULPD_SOFT_REQ_REG: 0x%-4x \n" + "ULPD_DPLL_CTRL_REG: 0x%-4x \n" + "ULPD_STATUS_REQ_REG: 0x%-4x \n" + "ULPD_POWER_CTRL_REG: 0x%-4x \n", + ARM_SHOW(ARM_CKCTL), + ARM_SHOW(ARM_IDLECT1), + ARM_SHOW(ARM_IDLECT2), + ARM_SHOW(ARM_EWUPCT), + ARM_SHOW(ARM_RSTCT1), + ARM_SHOW(ARM_RSTCT2), + ARM_SHOW(ARM_SYSST), + ULPD_SHOW(ULPD_IT_STATUS), + ULPD_SHOW(ULPD_CLOCK_CTRL), + ULPD_SHOW(ULPD_SOFT_REQ), + ULPD_SHOW(ULPD_DPLL_CTRL), + ULPD_SHOW(ULPD_STATUS_REQ), + ULPD_SHOW(ULPD_POWER_CTRL)); + + if (cpu_is_omap1510()) { + my_buffer_offset += sprintf(my_base + my_buffer_offset, + "MPUI1510_CTRL_REG 0x%-8x \n" + "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" + "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n" + "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n" + "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n" + "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n", + MPUI1510_SHOW(MPUI_CTRL), + MPUI1510_SHOW(MPUI_DSP_STATUS), + MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG), + MPUI1510_SHOW(MPUI_DSP_API_CONFIG), + MPUI1510_SHOW(EMIFF_SDRAM_CONFIG), + MPUI1510_SHOW(EMIFS_CONFIG)); + } else if (cpu_is_omap16xx()) { + my_buffer_offset += sprintf(my_base + my_buffer_offset, + "MPUI1610_CTRL_REG 0x%-8x \n" + "MPUI1610_DSP_STATUS_REG: 0x%-8x \n" + "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n" + "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n" + "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n" + "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n", + MPUI1610_SHOW(MPUI_CTRL), + MPUI1610_SHOW(MPUI_DSP_STATUS), + MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG), + MPUI1610_SHOW(MPUI_DSP_API_CONFIG), + MPUI1610_SHOW(EMIFF_SDRAM_CONFIG), + MPUI1610_SHOW(EMIFS_CONFIG)); + } + + g_read_completed++; + } else if (g_read_completed >= 1) { + *eof = 1; + return 0; + } + g_read_completed++; + + *my_first_byte = page_buffer; + return my_buffer_offset; +} + +static void omap_pm_init_proc(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_read_entry("driver/omap_pm", + S_IWUSR | S_IRUGO, NULL, + omap_pm_read_proc, 0); +} + +#endif /* DEBUG && CONFIG_PROC_FS */ + +/* + * omap_pm_prepare - Do preliminary suspend work. + * @state: suspend state we're entering. + * + */ +//#include <asm/arch/hardware.h> + +static int omap_pm_prepare(suspend_state_t state) +{ + int error = 0; + + switch (state) + { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + break; + + case PM_SUSPEND_DISK: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return error; +} + + +/* + * omap_pm_enter - Actually enter a sleep state. + * @state: State we're entering. + * + */ + +static int omap_pm_enter(suspend_state_t state) +{ + switch (state) + { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + omap_pm_suspend(); + break; + + case PM_SUSPEND_DISK: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return 0; +} + + +/** + * omap_pm_finish - Finish up suspend sequence. + * @state: State we're coming out of. + * + * This is called after we wake back up (or if entering the sleep state + * failed). + */ + +static int omap_pm_finish(suspend_state_t state) +{ + return 0; +} + + +struct pm_ops omap_pm_ops ={ + .pm_disk_mode = 0, + .prepare = omap_pm_prepare, + .enter = omap_pm_enter, + .finish = omap_pm_finish, +}; + +static int __init omap_pm_init(void) +{ + printk("Power Management for TI OMAP.\n"); + pm_idle = omap_pm_idle; + /* + * We copy the assembler sleep/wakeup routines to SRAM. + * These routines need to be in SRAM as that's the only + * memory the MPU can see when it wakes up. + */ + +#ifdef CONFIG_ARCH_OMAP1510 + if (cpu_is_omap1510()) { + memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND, + omap1510_idle_loop_suspend, + omap1510_idle_loop_suspend_sz); + memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend, + omap1510_cpu_suspend_sz); + } else +#endif + if (cpu_is_omap1610() || cpu_is_omap1710()) { + memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND, + omap1610_idle_loop_suspend, + omap1610_idle_loop_suspend_sz); + memcpy((void *)OMAP1610_SRAM_API_SUSPEND, omap1610_cpu_suspend, + omap1610_cpu_suspend_sz); + } else if (cpu_is_omap5912()) { + memcpy((void *)OMAP5912_SRAM_IDLE_SUSPEND, + omap1610_idle_loop_suspend, + omap1610_idle_loop_suspend_sz); + memcpy((void *)OMAP5912_SRAM_API_SUSPEND, omap1610_cpu_suspend, + omap1610_cpu_suspend_sz); + } + + pm_set_ops(&omap_pm_ops); + +#if defined(DEBUG) && defined(CONFIG_PROC_FS) + omap_pm_init_proc(); +#endif + + return 0; +} +__initcall(omap_pm_init); + diff --git a/arch/arm/mach-omap/sleep.S b/arch/arm/mach-omap/sleep.S new file mode 100644 index 0000000..4d426d1 --- /dev/null +++ b/arch/arm/mach-omap/sleep.S @@ -0,0 +1,314 @@ +/* + * linux/arch/arm/mach-omap/sleep.S + * + * Low-level OMAP1510/1610 sleep/wakeUp support + * + * Initial SA1110 code: + * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> + * + * Adapted for PXA by Nicolas Pitre: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/arch/io.h> +#include <asm/arch/pm.h> + + .text + +/* + * Forces OMAP into idle state + * + * omapXXXX_idle_loop_suspend() + * + * Note: This code get's copied to internal SRAM at boot. When the OMAP + * wakes up it continues execution at the point it went to sleep. + * + * Note: Because of slightly different configuration values we have + * processor specific functions here. + */ + +#ifdef CONFIG_ARCH_OMAP1510 +ENTRY(omap1510_idle_loop_suspend) + + stmfd sp!, {r0 - r12, lr} @ save registers on stack + + @ load base address of ARM_IDLECT1 and ARM_IDLECT2 + mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 + orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 + orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 + + @ turn off clock domains + @ get ARM_IDLECT2 into r2 + ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff + orr r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 + strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + + @ request ARM idle + @ get ARM_IDLECT1 into r1 + ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + orr r3, r1, #OMAP1510_IDLE_LOOP_REQUEST & 0xffff + strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + + mov r5, #IDLE_WAIT_CYCLES & 0xff + orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 +l_1510: subs r5, r5, #1 + bne l_1510 +/* + * Let's wait for the next clock tick to wake us up. + */ + mov r0, #0 + mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt +/* + * omap1510_idle_loop_suspend()'s resume point. + * + * It will just start executing here, so we'll restore stuff from the + * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. + */ + + @ restore ARM_IDLECT1 and ARM_IDLECT2 and return + @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2 + strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + + ldmfd sp!, {r0 - r12, pc} @ restore regs and return + +ENTRY(omap1510_idle_loop_suspend_sz) + .word . - omap1510_idle_loop_suspend +#endif /* CONFIG_ARCH_OMAP1510 */ + +#if defined(CONFIG_ARCH_OMAP16XX) +ENTRY(omap1610_idle_loop_suspend) + + stmfd sp!, {r0 - r12, lr} @ save registers on stack + + @ load base address of ARM_IDLECT1 and ARM_IDLECT2 + mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 + orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 + orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 + + @ turn off clock domains + @ get ARM_IDLECT2 into r2 + ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff + orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00 + strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + + @ request ARM idle + @ get ARM_IDLECT1 into r1 + ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + orr r3, r1, #OMAP1610_IDLE_LOOP_REQUEST & 0xffff + strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + + mov r5, #IDLE_WAIT_CYCLES & 0xff + orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 +l_1610: subs r5, r5, #1 + bne l_1610 +/* + * Let's wait for the next clock tick to wake us up. + */ + mov r0, #0 + mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt +/* + * omap1610_idle_loop_suspend()'s resume point. + * + * It will just start executing here, so we'll restore stuff from the + * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. + */ + + @ restore ARM_IDLECT1 and ARM_IDLECT2 and return + @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2 + strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + + ldmfd sp!, {r0 - r12, pc} @ restore regs and return + +ENTRY(omap1610_idle_loop_suspend_sz) + .word . - omap1610_idle_loop_suspend +#endif /* CONFIG_ARCH_OMAP16XX */ + +/* + * Forces OMAP into deep sleep state + * + * omapXXXX_cpu_suspend() + * + * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed + * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1 + * in register r1. + * + * Note: This code get's copied to internal SRAM at boot. When the OMAP + * wakes up it continues execution at the point it went to sleep. + * + * Note: Because of errata work arounds we have processor specific functions + * here. They are mostly the same, but slightly different. + * + */ + +#ifdef CONFIG_ARCH_OMAP1510 +ENTRY(omap1510_cpu_suspend) + + @ save registers on stack + stmfd sp!, {r0 - r12, lr} + + @ load base address of Traffic Controller + mov r4, #TCMIF_ASM_BASE & 0xff000000 + orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000 + orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00 + + @ work around errata of OMAP1510 PDE bit for TC shut down + @ clear PDE bit + ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] + bic r5, r5, #PDE_BIT & 0xff + str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] + + @ set PWD_EN bit + and r5, r5, #PWD_EN_BIT & 0xff + str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] + + @ prepare to put SDRAM into self-refresh manually + ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] + orr r5, r5, #SELF_REFRESH_MODE & 0xff000000 + orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff + str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] + + @ prepare to put EMIFS to Sleep + ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] + orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff + str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] + + @ load base address of ARM_IDLECT1 and ARM_IDLECT2 + mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 + orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 + orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 + + @ turn off clock domains + mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff + orr r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 + strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + + @ request ARM idle + mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff + orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00 + strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + + mov r5, #IDLE_WAIT_CYCLES & 0xff + orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 +l_1510_2: + subs r5, r5, #1 + bne l_1510_2 +/* + * Let's wait for the next wake up event to wake us up. r0 can't be + * used here because r0 holds ARM_IDLECT1 + */ + mov r2, #0 + mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt +/* + * omap1510_cpu_suspend()'s resume point. + * + * It will just start executing here, so we'll restore stuff from the + * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. + */ + strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + + @ restore regs and return + ldmfd sp!, {r0 - r12, pc} + +ENTRY(omap1510_cpu_suspend_sz) + .word . - omap1510_cpu_suspend +#endif /* CONFIG_ARCH_OMAP1510 */ + +#if defined(CONFIG_ARCH_OMAP16XX) +ENTRY(omap1610_cpu_suspend) + + @ save registers on stack + stmfd sp!, {r0 - r12, lr} + + @ load base address of Traffic Controller + mov r4, #TCMIF_ASM_BASE & 0xff000000 + orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000 + orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00 + + @ prepare to put SDRAM into self-refresh manually + ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] + orr r5, r5, #SELF_REFRESH_MODE & 0xff000000 + orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff + str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] + + @ prepare to put EMIFS to Sleep + ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] + orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff + str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] + + @ load base address of ARM_IDLECT1 and ARM_IDLECT2 + mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 + orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 + orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 + + @ turn off clock domains + mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff + orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00 + strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + + @ work around errata of OMAP1610/5912. Enable (!) peripheral + @ clock to let the chip go into deep sleep + ldrh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + orr r5,r5, #EN_PERCK_BIT & 0xff + strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + + @ request ARM idle + mov r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff + orr r3, r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff00 + strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + + mov r5, #IDLE_WAIT_CYCLES & 0xff + orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 +l_1610_2: + subs r5, r5, #1 + bne l_1610_2 +/* + * Let's wait for the next wake up event to wake us up. r0 can't be + * used here because r0 holds ARM_IDLECT1 + */ + mov r2, #0 + mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt +/* + * omap1610_cpu_suspend()'s resume point. + * + * It will just start executing here, so we'll restore stuff from the + * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. + */ + strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] + strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] + + @ restore regs and return + ldmfd sp!, {r0 - r12, pc} + +ENTRY(omap1610_cpu_suspend_sz) + .word . - omap1610_cpu_suspend +#endif /* CONFIG_ARCH_OMAP16XX */ diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c new file mode 100644 index 0000000..4205fdc --- /dev/null +++ b/arch/arm/mach-omap/time.c @@ -0,0 +1,384 @@ +/* + * linux/arch/arm/mach-omap/time.c + * + * OMAP Timers + * + * Copyright (C) 2004 Nokia Corporation + * Partial timer rewrite and additional VST timer support by + * Tony Lindgen <tony@atomide.com> and + * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> + * + * MPU timer code based on the older MPU timer code for OMAP + * Copyright (C) 2000 RidgeRun, Inc. + * Author: Greg Lonnon <glonnon@ridgerun.com> + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/sched.h> +#include <linux/spinlock.h> + +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> + +struct sys_timer omap_timer; + +#ifdef CONFIG_OMAP_MPU_TIMER + +/* + * --------------------------------------------------------------------------- + * MPU timer + * --------------------------------------------------------------------------- + */ +#define OMAP_MPU_TIMER1_BASE (0xfffec500) +#define OMAP_MPU_TIMER2_BASE (0xfffec600) +#define OMAP_MPU_TIMER3_BASE (0xfffec700) +#define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE +#define OMAP_MPU_TIMER_OFFSET 0x100 + +#define MPU_TIMER_FREE (1 << 6) +#define MPU_TIMER_CLOCK_ENABLE (1 << 5) +#define MPU_TIMER_AR (1 << 1) +#define MPU_TIMER_ST (1 << 0) + +/* cycles to nsec conversions taken from arch/i386/kernel/timers/timer_tsc.c, + * converted to use kHz by Kevin Hilman */ +/* convert from cycles(64bits) => nanoseconds (64bits) + * basic equation: + * ns = cycles / (freq / ns_per_sec) + * ns = cycles * (ns_per_sec / freq) + * ns = cycles * (10^9 / (cpu_khz * 10^3)) + * ns = cycles * (10^6 / cpu_khz) + * + * Then we use scaling math (suggested by george at mvista.com) to get: + * ns = cycles * (10^6 * SC / cpu_khz / SC + * ns = cycles * cyc2ns_scale / SC + * + * And since SC is a constant power of two, we can convert the div + * into a shift. + * -johnstul at us.ibm.com "math is hard, lets go shopping!" + */ +static unsigned long cyc2ns_scale; +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ + +static inline void set_cyc2ns_scale(unsigned long cpu_khz) +{ + cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; +} + +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} + +/* + * MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs + * will break. On P2, the timer count rate is 6.5 MHz after programming PTV + * with 0. This divides the 13MHz input by 2, and is undocumented. + */ +#ifdef CONFIG_MACH_OMAP_PERSEUS2 +/* REVISIT: This ifdef construct should be replaced by a query to clock + * framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz. + */ +#define MPU_TICKS_PER_SEC (13000000 / 2) +#else +#define MPU_TICKS_PER_SEC (12000000 / 2) +#endif + +#define MPU_TIMER_TICK_PERIOD ((MPU_TICKS_PER_SEC / HZ) - 1) + +typedef struct { + u32 cntl; /* CNTL_TIMER, R/W */ + u32 load_tim; /* LOAD_TIM, W */ + u32 read_tim; /* READ_TIM, R */ +} omap_mpu_timer_regs_t; + +#define omap_mpu_timer_base(n) \ +((volatile omap_mpu_timer_regs_t*)IO_ADDRESS(OMAP_MPU_TIMER_BASE + \ + (n)*OMAP_MPU_TIMER_OFFSET)) + +static inline unsigned long omap_mpu_timer_read(int nr) +{ + volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr); + return timer->read_tim; +} + +static inline void omap_mpu_timer_start(int nr, unsigned long load_val) +{ + volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr); + + timer->cntl = MPU_TIMER_CLOCK_ENABLE; + udelay(1); + timer->load_tim = load_val; + udelay(1); + timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST); +} + +unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks) +{ + unsigned long long nsec; + + nsec = cycles_2_ns((unsigned long long)nr_ticks); + return (unsigned long)nsec / 1000; +} + +/* + * Last processed system timer interrupt + */ +static unsigned long omap_mpu_timer_last = 0; + +/* + * Returns elapsed usecs since last system timer interrupt + */ +static unsigned long omap_mpu_timer_gettimeoffset(void) +{ + unsigned long now = 0 - omap_mpu_timer_read(0); + unsigned long elapsed = now - omap_mpu_timer_last; + + return omap_mpu_timer_ticks_to_usecs(elapsed); +} + +/* + * Elapsed time between interrupts is calculated using timer0. + * Latency during the interrupt is calculated using timer1. + * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz). + */ +static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long now, latency; + + write_seqlock(&xtime_lock); + now = 0 - omap_mpu_timer_read(0); + latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1); + omap_mpu_timer_last = now - latency; + timer_tick(regs); + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction omap_mpu_timer_irq = { + .name = "mpu timer", + .flags = SA_INTERRUPT, + .handler = omap_mpu_timer_interrupt +}; + +static unsigned long omap_mpu_timer1_overflows; +static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + omap_mpu_timer1_overflows++; + return IRQ_HANDLED; +} + +static struct irqaction omap_mpu_timer1_irq = { + .name = "mpu timer1 overflow", + .flags = SA_INTERRUPT, + .handler = omap_mpu_timer1_interrupt +}; + +static __init void omap_init_mpu_timer(void) +{ + set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000); + omap_timer.offset = omap_mpu_timer_gettimeoffset; + setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); + setup_irq(INT_TIMER2, &omap_mpu_timer_irq); + omap_mpu_timer_start(0, 0xffffffff); + omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD); +} + +/* + * Scheduler clock - returns current time in nanosec units. + */ +unsigned long long sched_clock(void) +{ + unsigned long ticks = 0 - omap_mpu_timer_read(0); + unsigned long long ticks64; + + ticks64 = omap_mpu_timer1_overflows; + ticks64 <<= 32; + ticks64 |= ticks; + + return cycles_2_ns(ticks64); +} +#endif /* CONFIG_OMAP_MPU_TIMER */ + +#ifdef CONFIG_OMAP_32K_TIMER + +#ifdef CONFIG_ARCH_OMAP1510 +#error OMAP 32KHz timer does not currently work on 1510! +#endif + +/* + * --------------------------------------------------------------------------- + * 32KHz OS timer + * + * This currently works only on 16xx, as 1510 does not have the continuous + * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track + * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer + * on 1510 would be possible, but the timer would not be as accurate as + * with the 32KHz synchronized timer. + * --------------------------------------------------------------------------- + */ +#define OMAP_32K_TIMER_BASE 0xfffb9000 +#define OMAP_32K_TIMER_CR 0x08 +#define OMAP_32K_TIMER_TVR 0x00 +#define OMAP_32K_TIMER_TCR 0x04 + +#define OMAP_32K_TICKS_PER_HZ (32768 / HZ) + +/* + * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 + * so with HZ = 100, TVR = 327.68. + */ +#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) +#define MAX_SKIP_JIFFIES 25 +#define TIMER_32K_SYNCHRONIZED 0xfffbc410 + +#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ + (((nr_jiffies) * (clock_rate)) / HZ) + +static inline void omap_32k_timer_write(int val, int reg) +{ + omap_writew(val, reg + OMAP_32K_TIMER_BASE); +} + +static inline unsigned long omap_32k_timer_read(int reg) +{ + return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff; +} + +/* + * The 32KHz synchronized timer is an additional timer on 16xx. + * It is always running. + */ +static inline unsigned long omap_32k_sync_timer_read(void) +{ + return omap_readl(TIMER_32K_SYNCHRONIZED); +} + +static inline void omap_32k_timer_start(unsigned long load_val) +{ + omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR); + omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR); +} + +static inline void omap_32k_timer_stop(void) +{ + omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR); +} + +/* + * Rounds down to nearest usec + */ +static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) +{ + return (ticks_32k * 5*5*5*5*5*5) >> 9; +} + +static unsigned long omap_32k_last_tick = 0; + +/* + * Returns elapsed usecs since last 32k timer interrupt + */ +static unsigned long omap_32k_timer_gettimeoffset(void) +{ + unsigned long now = omap_32k_sync_timer_read(); + return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); +} + +/* + * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this + * function is also called from other interrupts to remove latency + * issues with dynamic tick. In the dynamic tick case, we need to lock + * with irqsave. + */ +static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long flags; + unsigned long now; + + write_seqlock_irqsave(&xtime_lock, flags); + now = omap_32k_sync_timer_read(); + + while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { + omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; + timer_tick(regs); + } + + /* Restart timer so we don't drift off due to modulo or dynamic tick. + * By default we program the next timer to be continuous to avoid + * latencies during high system load. During dynamic tick operation the + * continuous timer can be overridden from pm_idle to be longer. + */ + omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); + write_sequnlock_irqrestore(&xtime_lock, flags); + + return IRQ_HANDLED; +} + +static struct irqaction omap_32k_timer_irq = { + .name = "32KHz timer", + .flags = SA_INTERRUPT, + .handler = omap_32k_timer_interrupt +}; + +static __init void omap_init_32k_timer(void) +{ + setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); + omap_timer.offset = omap_32k_timer_gettimeoffset; + omap_32k_last_tick = omap_32k_sync_timer_read(); + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); +} +#endif /* CONFIG_OMAP_32K_TIMER */ + +/* + * --------------------------------------------------------------------------- + * Timer initialization + * --------------------------------------------------------------------------- + */ +void __init omap_timer_init(void) +{ +#if defined(CONFIG_OMAP_MPU_TIMER) + omap_init_mpu_timer(); +#elif defined(CONFIG_OMAP_32K_TIMER) + omap_init_32k_timer(); +#else +#error No system timer selected in Kconfig! +#endif +} + +struct sys_timer omap_timer = { + .init = omap_timer_init, + .offset = NULL, /* Initialized later */ +}; diff --git a/arch/arm/mach-omap/usb.c b/arch/arm/mach-omap/usb.c new file mode 100644 index 0000000..6e805d4 --- /dev/null +++ b/arch/arm/mach-omap/usb.c @@ -0,0 +1,594 @@ +/* + * arch/arm/mach-omap/usb.c -- platform level USB initialization + * + * Copyright (C) 2004 Texas Instruments, Inc. + * + * 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 + */ + +#undef DEBUG + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/usb_otg.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +#include <asm/arch/mux.h> +#include <asm/arch/usb.h> +#include <asm/arch/board.h> + +/* These routines should handle the standard chip-specific modes + * for usb0/1/2 ports, covering basic mux and transceiver setup. + * Call omap_usb_init() once, from INIT_MACHINE(). + * + * Some board-*.c files will need to set up additional mux options, + * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. + */ + +/* TESTED ON: + * - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables + * - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables + * - 5912 OSK UDC, with *nonstandard* A-to-A cable + * - 1510 Innovator UDC with bundled usb0 cable + * - 1510 Innovator OHCI with bundled usb1/usb2 cable + * - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS + * - 1710 custom development board using alternate pin group + * - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables + */ + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_ARCH_OMAP_OTG + +static struct otg_transceiver *xceiv; + +/** + * otg_get_transceiver - find the (single) OTG transceiver driver + * + * Returns the transceiver driver, after getting a refcount to it; or + * null if there is no such transceiver. The caller is responsible for + * releasing that count. + */ +struct otg_transceiver *otg_get_transceiver(void) +{ + if (xceiv) + get_device(xceiv->dev); + return xceiv; +} +EXPORT_SYMBOL(otg_get_transceiver); + +int otg_set_transceiver(struct otg_transceiver *x) +{ + if (xceiv && x) + return -EBUSY; + xceiv = x; + return 0; +} +EXPORT_SYMBOL(otg_set_transceiver); + +#endif + +/*-------------------------------------------------------------------------*/ + +static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) +{ + u32 syscon1 = 0; + + if (nwires == 0) { + if (!cpu_is_omap15xx()) { + /* pulldown D+/D- */ + USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1); + } + return 0; + } + + if (is_device) + omap_cfg_reg(W4_USB_PUEN); + + /* internal transceiver */ + if (nwires == 2) { + // omap_cfg_reg(P9_USB_DP); + // omap_cfg_reg(R8_USB_DM); + + if (cpu_is_omap15xx()) { + /* This works on 1510-Innovator */ + return 0; + } + + /* NOTES: + * - peripheral should configure VBUS detection! + * - only peripherals may use the internal D+/D- pulldowns + * - OTG support on this port not yet written + */ + + USB_TRANSCEIVER_CTRL_REG &= ~(7 << 4); + if (!is_device) + USB_TRANSCEIVER_CTRL_REG |= (3 << 1); + + return 3 << 16; + } + + /* alternate pin config, external transceiver */ + if (cpu_is_omap15xx()) { + printk(KERN_ERR "no usb0 alt pin config on 15xx\n"); + return 0; + } + + omap_cfg_reg(V6_USB0_TXD); + omap_cfg_reg(W9_USB0_TXEN); + omap_cfg_reg(W5_USB0_SE0); + + /* NOTE: SPEED and SUSP aren't configured here */ + + if (nwires != 3) + omap_cfg_reg(Y5_USB0_RCV); + if (nwires != 6) + USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; + + switch (nwires) { + case 3: + syscon1 = 2; + break; + case 4: + syscon1 = 1; + break; + case 6: + syscon1 = 3; + omap_cfg_reg(AA9_USB0_VP); + omap_cfg_reg(R9_USB0_VM); + USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R; + break; + default: + printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", + 0, nwires); + } + return syscon1 << 16; +} + +static u32 __init omap_usb1_init(unsigned nwires) +{ + u32 syscon1 = 0; + + if (nwires != 6 && !cpu_is_omap15xx()) + USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R; + if (nwires == 0) + return 0; + + /* external transceiver */ + omap_cfg_reg(USB1_TXD); + omap_cfg_reg(USB1_TXEN); + if (cpu_is_omap15xx()) { + omap_cfg_reg(USB1_SEO); + omap_cfg_reg(USB1_SPEED); + // SUSP + } else if (cpu_is_omap1610() || cpu_is_omap5912()) { + omap_cfg_reg(W13_1610_USB1_SE0); + omap_cfg_reg(R13_1610_USB1_SPEED); + // SUSP + } else if (cpu_is_omap1710()) { + omap_cfg_reg(R13_1710_USB1_SE0); + // SUSP + } else { + pr_debug("usb unrecognized\n"); + } + if (nwires != 3) + omap_cfg_reg(USB1_RCV); + + switch (nwires) { + case 3: + syscon1 = 2; + break; + case 4: + syscon1 = 1; + break; + case 6: + syscon1 = 3; + omap_cfg_reg(USB1_VP); + omap_cfg_reg(USB1_VM); + if (!cpu_is_omap15xx()) + USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R; + break; + default: + printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", + 1, nwires); + } + return syscon1 << 20; +} + +static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) +{ + u32 syscon1 = 0; + + /* NOTE erratum: must leave USB2_UNI_R set if usb0 in use */ + if (alt_pingroup || nwires == 0) + return 0; + if (nwires != 6 && !cpu_is_omap15xx()) + USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; + + /* external transceiver */ + if (cpu_is_omap15xx()) { + omap_cfg_reg(USB2_TXD); + omap_cfg_reg(USB2_TXEN); + omap_cfg_reg(USB2_SEO); + if (nwires != 3) + omap_cfg_reg(USB2_RCV); + /* there is no USB2_SPEED */ + } else if (cpu_is_omap16xx()) { + omap_cfg_reg(V6_USB2_TXD); + omap_cfg_reg(W9_USB2_TXEN); + omap_cfg_reg(W5_USB2_SE0); + if (nwires != 3) + omap_cfg_reg(Y5_USB2_RCV); + // FIXME omap_cfg_reg(USB2_SPEED); + } else { + pr_debug("usb unrecognized\n"); + } + // omap_cfg_reg(USB2_SUSP); + + switch (nwires) { + case 3: + syscon1 = 2; + break; + case 4: + syscon1 = 1; + break; + case 6: + syscon1 = 3; + if (cpu_is_omap15xx()) { + omap_cfg_reg(USB2_VP); + omap_cfg_reg(USB2_VM); + } else { + omap_cfg_reg(AA9_USB2_VP); + omap_cfg_reg(R9_USB2_VM); + USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R; + } + break; + default: + printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", + 2, nwires); + } + return syscon1 << 24; +} + +/*-------------------------------------------------------------------------*/ + +#if defined(CONFIG_USB_GADGET_OMAP) || \ + defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) || \ + (defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)) +static void usb_release(struct device *dev) +{ + /* normally not freed */ +} +#endif + +#ifdef CONFIG_USB_GADGET_OMAP + +static struct resource udc_resources[] = { + /* order is significant! */ + { /* registers */ + .start = IO_ADDRESS(UDC_BASE), + .end = IO_ADDRESS(UDC_BASE + 0xff), + .flags = IORESOURCE_MEM, + }, { /* general IRQ */ + .start = IH2_BASE + 20, + .flags = IORESOURCE_IRQ, + }, { /* PIO IRQ */ + .start = IH2_BASE + 30, + .flags = IORESOURCE_IRQ, + }, { /* SOF IRQ */ + .start = IH2_BASE + 29, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dmamask = ~(u32)0; + +static struct platform_device udc_device = { + .name = "omap_udc", + .id = -1, + .dev = { + .release = usb_release, + .dma_mask = &udc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(udc_resources), + .resource = udc_resources, +}; + +#endif + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32)0; + +static struct resource ohci_resources[] = { + { + .start = OMAP_OHCI_BASE, + .end = OMAP_OHCI_BASE + 4096, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_USB_HHC_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ohci_device = { + .name = "ohci", + .id = -1, + .dev = { + .release = usb_release, + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(ohci_resources), + .resource = ohci_resources, +}; + +#endif + +#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) + +static struct resource otg_resources[] = { + /* order is significant! */ + { + .start = IO_ADDRESS(OTG_BASE), + .end = IO_ADDRESS(OTG_BASE + 0xff), + .flags = IORESOURCE_MEM, + }, { + .start = IH2_BASE + 8, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device otg_device = { + .name = "omap_otg", + .id = -1, + .dev = { + .release = usb_release, + }, + .num_resources = ARRAY_SIZE(otg_resources), + .resource = otg_resources, +}; + +#endif + +/*-------------------------------------------------------------------------*/ + +#define ULPD_CLOCK_CTRL_REG __REG16(ULPD_CLOCK_CTRL) +#define ULPD_SOFT_REQ_REG __REG16(ULPD_SOFT_REQ) + + +// FIXME correct answer depends on hmc_mode, +// as does any nonzero value for config->otg port number +#ifdef CONFIG_USB_GADGET_OMAP +#define is_usb0_device(config) 1 +#else +#define is_usb0_device(config) 0 +#endif + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_ARCH_OMAP_OTG + +void __init +omap_otg_init(struct omap_usb_config *config) +{ + u32 syscon = OTG_SYSCON_1_REG & 0xffff; + int status; + int alt_pingroup = 0; + + /* NOTE: no bus or clock setup (yet?) */ + + syscon = OTG_SYSCON_1_REG & 0xffff; + if (!(syscon & OTG_RESET_DONE)) + pr_debug("USB resets not complete?\n"); + + // OTG_IRQ_EN_REG = 0; + + /* pin muxing and transceiver pinouts */ + if (config->pins[0] > 2) /* alt pingroup 2 */ + alt_pingroup = 1; + syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config)); + syscon |= omap_usb1_init(config->pins[1]); + syscon |= omap_usb2_init(config->pins[2], alt_pingroup); + pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon); + OTG_SYSCON_1_REG = syscon; + + syscon = config->hmc_mode; + syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; +#ifdef CONFIG_USB_OTG + if (config->otg) + syscon |= OTG_EN; +#endif + pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG); + pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon); + OTG_SYSCON_2_REG = syscon; + + printk("USB: hmc %d", config->hmc_mode); + if (alt_pingroup) + printk(", usb2 alt %d wires", config->pins[2]); + else if (config->pins[0]) + printk(", usb0 %d wires%s", config->pins[0], + is_usb0_device(config) ? " (dev)" : ""); + if (config->pins[1]) + printk(", usb1 %d wires", config->pins[1]); + if (!alt_pingroup && config->pins[2]) + printk(", usb2 %d wires", config->pins[2]); + if (config->otg) + printk(", Mini-AB on usb%d", config->otg - 1); + printk("\n"); + + /* leave USB clocks/controllers off until needed */ + ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ; + ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN; + ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK; + syscon = OTG_SYSCON_1_REG; + syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; + +#ifdef CONFIG_USB_GADGET_OMAP + if (config->otg || config->register_dev) { + syscon &= ~DEV_IDLE_EN; + udc_device.dev.platform_data = config; + /* FIXME patch IRQ numbers for omap730 */ + status = platform_device_register(&udc_device); + if (status) + pr_debug("can't register UDC device, %d\n", status); + } +#endif + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + if (config->otg || config->register_host) { + syscon &= ~HST_IDLE_EN; + ohci_device.dev.platform_data = config; + if (cpu_is_omap730()) + ohci_resources[1].start = INT_730_USB_HHC_1; + status = platform_device_register(&ohci_device); + if (status) + pr_debug("can't register OHCI device, %d\n", status); + } +#endif + +#ifdef CONFIG_USB_OTG + if (config->otg) { + syscon &= ~OTG_IDLE_EN; + otg_device.dev.platform_data = config; + if (cpu_is_omap730()) + otg_resources[1].start = INT_730_USB_OTG; + status = platform_device_register(&otg_device); + if (status) + pr_debug("can't register OTG device, %d\n", status); + } +#endif + pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon); + OTG_SYSCON_1_REG = syscon; + + status = 0; +} + +#else +static inline void omap_otg_init(struct omap_usb_config *config) {} +#endif + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_ARCH_OMAP1510 + +#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL) +#define DPLL_IOB (1 << 13) +#define DPLL_PLL_ENABLE (1 << 4) +#define DPLL_LOCK (1 << 0) + +#define ULPD_APLL_CTRL_REG __REG16(ULPD_APLL_CTRL) +#define APLL_NDPLL_SWITCH (1 << 0) + + +static void __init omap_1510_usb_init(struct omap_usb_config *config) +{ + int status; + unsigned int val; + + omap_usb0_init(config->pins[0], is_usb0_device(config)); + omap_usb1_init(config->pins[1]); + omap_usb2_init(config->pins[2], 0); + + val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1); + val |= (config->hmc_mode << 1); + omap_writel(val, MOD_CONF_CTRL_0); + + printk("USB: hmc %d", config->hmc_mode); + if (config->pins[0]) + printk(", usb0 %d wires%s", config->pins[0], + is_usb0_device(config) ? " (dev)" : ""); + if (config->pins[1]) + printk(", usb1 %d wires", config->pins[1]); + if (config->pins[2]) + printk(", usb2 %d wires", config->pins[2]); + printk("\n"); + + /* use DPLL for 48 MHz function clock */ + pr_debug("APLL %04x DPLL %04x REQ %04x\n", ULPD_APLL_CTRL_REG, + ULPD_DPLL_CTRL_REG, ULPD_SOFT_REQ_REG); + ULPD_APLL_CTRL_REG &= ~APLL_NDPLL_SWITCH; + ULPD_DPLL_CTRL_REG |= DPLL_IOB | DPLL_PLL_ENABLE; + ULPD_SOFT_REQ_REG |= SOFT_UDC_REQ | SOFT_DPLL_REQ; + while (!(ULPD_DPLL_CTRL_REG & DPLL_LOCK)) + cpu_relax(); + +#ifdef CONFIG_USB_GADGET_OMAP + if (config->register_dev) { + udc_device.dev.platform_data = config; + status = platform_device_register(&udc_device); + if (status) + pr_debug("can't register UDC device, %d\n", status); + /* udc driver gates 48MHz by D+ pullup */ + } +#endif + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) + if (config->register_host) { + ohci_device.dev.platform_data = config; + status = platform_device_register(&ohci_device); + if (status) + pr_debug("can't register OHCI device, %d\n", status); + /* hcd explicitly gates 48MHz */ + } +#endif +} + +#else +static inline void omap_1510_usb_init(struct omap_usb_config *config) {} +#endif + +/*-------------------------------------------------------------------------*/ + +static struct omap_usb_config platform_data; + +static int __init +omap_usb_init(void) +{ + const struct omap_usb_config *config; + + config = omap_get_config(OMAP_TAG_USB, struct omap_usb_config); + if (config == NULL) { + printk(KERN_ERR "USB: No board-specific " + "platform config found\n"); + return -ENODEV; + } + platform_data = *config; + + if (cpu_is_omap730() || cpu_is_omap16xx()) + omap_otg_init(&platform_data); + else if (cpu_is_omap15xx()) + omap_1510_usb_init(&platform_data); + else { + printk(KERN_ERR "USB: No init for your chip yet\n"); + return -ENODEV; + } + return 0; +} + +subsys_initcall(omap_usb_init); diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig new file mode 100644 index 0000000..405a55f --- /dev/null +++ b/arch/arm/mach-pxa/Kconfig @@ -0,0 +1,77 @@ +if ARCH_PXA + +menu "Intel PXA2xx Implementations" + +choice + prompt "Select target board" + +config ARCH_LUBBOCK + bool "Intel DBPXA250 Development Platform" + select PXA25x + select SA1111 + +config MACH_MAINSTONE + bool "Intel HCDDBBVA0 Development Platform" + select PXA27x + select IWMMXT + +config ARCH_PXA_IDP + bool "Accelent Xscale IDP" + select PXA25x + +config PXA_SHARPSL + bool "SHARP SL-5600 and SL-C7xx Models" + select PXA25x + select SHARP_SCOOP + select SHARP_PARAM + help + Say Y here if you intend to run this kernel on a + Sharp SL-5600 (Poodle), Sharp SL-C700 (Corgi), + SL-C750 (Shepherd) or a Sharp SL-C760 (Husky) + handheld computer. + +endchoice + +endmenu + +config MACH_POODLE + bool "Enable Sharp SL-5600 (Poodle) Support" + depends PXA_SHARPSL + select SHARP_LOCOMO + +config MACH_CORGI + bool "Enable Sharp SL-C700 (Corgi) Support" + depends PXA_SHARPSL + select PXA_SHARP_C7xx + +config MACH_SHEPHERD + bool "Enable Sharp SL-C750 (Shepherd) Support" + depends PXA_SHARPSL + select PXA_SHARP_C7xx + +config MACH_HUSKY + bool "Enable Sharp SL-C760 (Husky) Support" + depends PXA_SHARPSL + select PXA_SHARP_C7xx + +config PXA25x + bool + help + Select code specific to PXA21x/25x/26x variants + +config PXA27x + bool + help + Select code specific to PXA27x variants + +config IWMMXT + bool + help + Enable support for iWMMXt + +config PXA_SHARP_C7xx + bool + help + Enable support for all Sharp C7xx models + +endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile new file mode 100644 index 0000000..c4e6d25 --- /dev/null +++ b/arch/arm/mach-pxa/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for the linux kernel. +# + +# Common support (must be linked before board specific support) +obj-y += generic.o irq.o dma.o time.o +obj-$(CONFIG_PXA25x) += pxa25x.o +obj-$(CONFIG_PXA27x) += pxa27x.o + +# Specific board support +obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o +obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o +obj-$(CONFIG_ARCH_PXA_IDP) += idp.o +obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o ssp.o +obj-$(CONFIG_MACH_POODLE) += poodle.o + +# Support for blinky lights +led-y := leds.o +led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o +led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o +led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o + +obj-$(CONFIG_LEDS) += $(led-y) + +# Misc features +obj-$(CONFIG_PM) += pm.o sleep.o diff --git a/arch/arm/mach-pxa/Makefile.boot b/arch/arm/mach-pxa/Makefile.boot new file mode 100644 index 0000000..1ead671 --- /dev/null +++ b/arch/arm/mach-pxa/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y := 0xa0008000 + diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c new file mode 100644 index 0000000..f691cf7 --- /dev/null +++ b/arch/arm/mach-pxa/corgi.c @@ -0,0 +1,320 @@ +/* + * Support for Sharp SL-C7xx PDAs + * Models: SL-C700 (Corgi), SL-C750 (Shepherd), SL-C760 (Husky) + * + * Copyright (c) 2004-2005 Richard Purdie + * + * Based on Sharp's 2.4 kernel patches/lubbock.c + * + * 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/init.h> +#include <linux/device.h> +#include <linux/major.h> +#include <linux/fs.h> +#include <linux/interrupt.h> +#include <linux/mmc/host.h> + +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/irq.h> +#include <asm/arch/mmc.h> +#include <asm/arch/udc.h> +#include <asm/arch/corgi.h> + +#include <asm/mach/sharpsl_param.h> +#include <asm/hardware/scoop.h> +#include <video/w100fb.h> + +#include "generic.h" + + +/* + * Corgi SCOOP Device + */ +static struct resource corgi_scoop_resources[] = { + [0] = { + .start = 0x10800000, + .end = 0x10800fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct scoop_config corgi_scoop_setup = { + .io_dir = CORGI_SCOOP_IO_DIR, + .io_out = CORGI_SCOOP_IO_OUT, +}; + +struct platform_device corgiscoop_device = { + .name = "sharp-scoop", + .id = -1, + .dev = { + .platform_data = &corgi_scoop_setup, + }, + .num_resources = ARRAY_SIZE(corgi_scoop_resources), + .resource = corgi_scoop_resources, +}; + + +/* + * Corgi SSP Device + * + * Set the parent as the scoop device because a lot of SSP devices + * also use scoop functions and this makes the power up/down order + * work correctly. + */ +static struct platform_device corgissp_device = { + .name = "corgi-ssp", + .dev = { + .parent = &corgiscoop_device.dev, + }, + .id = -1, +}; + + +/* + * Corgi w100 Frame Buffer Device + */ +static struct w100fb_mach_info corgi_fb_info = { + .w100fb_ssp_send = corgi_ssp_lcdtg_send, + .comadj = -1, + .phadadj = -1, +}; + +static struct resource corgi_fb_resources[] = { + [0] = { + .start = 0x08000000, + .end = 0x08ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device corgifb_device = { + .name = "w100fb", + .id = -1, + .dev = { + .platform_data = &corgi_fb_info, + .parent = &corgissp_device.dev, + }, + .num_resources = ARRAY_SIZE(corgi_fb_resources), + .resource = corgi_fb_resources, +}; + + +/* + * Corgi Backlight Device + */ +static struct platform_device corgibl_device = { + .name = "corgi-bl", + .dev = { + .parent = &corgifb_device.dev, + }, + .id = -1, +}; + + +/* + * MMC/SD Device + * + * The card detect interrupt isn't debounced so we delay it by HZ/4 + * to give the card a chance to fully insert/eject. + */ +static struct mmc_detect { + struct timer_list detect_timer; + void *devid; +} mmc_detect; + +static void mmc_detect_callback(unsigned long data) +{ + mmc_detect_change(mmc_detect.devid); +} + +static irqreturn_t corgi_mmc_detect_int(int irq, void *devid, struct pt_regs *regs) +{ + mmc_detect.devid=devid; + mod_timer(&mmc_detect.detect_timer, jiffies + HZ/4); + return IRQ_HANDLED; +} + +static int corgi_mci_init(struct device *dev, irqreturn_t (*unused_detect_int)(int, void *, struct pt_regs *), void *data) +{ + int err; + + /* setup GPIO for PXA25x MMC controller */ + pxa_gpio_mode(GPIO6_MMCCLK_MD); + pxa_gpio_mode(GPIO8_MMCCS0_MD); + pxa_gpio_mode(CORGI_GPIO_nSD_DETECT | GPIO_IN); + pxa_gpio_mode(CORGI_GPIO_SD_PWR | GPIO_OUT); + + init_timer(&mmc_detect.detect_timer); + mmc_detect.detect_timer.function = mmc_detect_callback; + mmc_detect.detect_timer.data = (unsigned long) &mmc_detect; + + err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_mmc_detect_int, SA_INTERRUPT, + "MMC card detect", data); + if (err) { + printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); + return -1; + } + + set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); + + return 0; +} + +static void corgi_mci_setpower(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data* p_d = dev->platform_data; + + if (( 1 << vdd) & p_d->ocr_mask) { + printk(KERN_DEBUG "%s: on\n", __FUNCTION__); + GPSR1 = GPIO_bit(CORGI_GPIO_SD_PWR); + } else { + printk(KERN_DEBUG "%s: off\n", __FUNCTION__); + GPCR1 = GPIO_bit(CORGI_GPIO_SD_PWR); + } +} + +static void corgi_mci_exit(struct device *dev, void *data) +{ + free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data); + del_timer(&mmc_detect.detect_timer); +} + +static struct pxamci_platform_data corgi_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = corgi_mci_init, + .setpower = corgi_mci_setpower, + .exit = corgi_mci_exit, +}; + + +/* + * USB Device Controller + */ +static void corgi_udc_command(int cmd) +{ + switch(cmd) { + case PXA2XX_UDC_CMD_CONNECT: + GPSR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP); + break; + case PXA2XX_UDC_CMD_DISCONNECT: + GPCR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP); + break; + } +} + +static struct pxa2xx_udc_mach_info udc_info __initdata = { + /* no connect GPIO; corgi can't tell connection status */ + .udc_command = corgi_udc_command, +}; + + +static struct platform_device *devices[] __initdata = { + &corgiscoop_device, + &corgissp_device, + &corgifb_device, + &corgibl_device, +}; + +static void __init corgi_init(void) +{ + corgi_fb_info.comadj=sharpsl_param.comadj; + corgi_fb_info.phadadj=sharpsl_param.phadadj; + + pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT); + pxa_set_udc_info(&udc_info); + pxa_set_mci_info(&corgi_mci_platform_data); + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static void __init fixup_corgi(struct machine_desc *desc, + struct tag *tags, char **cmdline, struct meminfo *mi) +{ + sharpsl_save_param(); + mi->nr_banks=1; + mi->bank[0].start = 0xa0000000; + mi->bank[0].node = 0; + if (machine_is_corgi()) + mi->bank[0].size = (32*1024*1024); + else + mi->bank[0].size = (64*1024*1024); +} + +static void __init corgi_init_irq(void) +{ + pxa_init_irq(); +} + +static struct map_desc corgi_io_desc[] __initdata = { +/* virtual physical length */ +/* { 0xf1000000, 0x08000000, 0x01000000, MT_DEVICE },*/ /* LCDC (readable for Qt driver) */ +/* { 0xef700000, 0x10800000, 0x00001000, MT_DEVICE },*/ /* SCOOP */ + { 0xef800000, 0x00000000, 0x00800000, MT_DEVICE }, /* Boot Flash */ +}; + +static void __init corgi_map_io(void) +{ + pxa_map_io(); + iotable_init(corgi_io_desc,ARRAY_SIZE(corgi_io_desc)); + + /* setup sleep mode values */ + PWER = 0x00000002; + PFER = 0x00000000; + PRER = 0x00000002; + PGSR0 = 0x0158C000; + PGSR1 = 0x00FF0080; + PGSR2 = 0x0001C004; + /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ + PCFR |= PCFR_OPDE; +} + +#ifdef CONFIG_MACH_CORGI +MACHINE_START(CORGI, "SHARP Corgi") + BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) + FIXUP(fixup_corgi) + MAPIO(corgi_map_io) + INITIRQ(corgi_init_irq) + .init_machine = corgi_init, + .timer = &pxa_timer, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_SHEPHERD +MACHINE_START(SHEPHERD, "SHARP Shepherd") + BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) + FIXUP(fixup_corgi) + MAPIO(corgi_map_io) + INITIRQ(corgi_init_irq) + .init_machine = corgi_init, + .timer = &pxa_timer, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_HUSKY +MACHINE_START(HUSKY, "SHARP Husky") + BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) + FIXUP(fixup_corgi) + MAPIO(corgi_map_io) + INITIRQ(corgi_init_irq) + .init_machine = corgi_init, + .timer = &pxa_timer, +MACHINE_END +#endif + diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c new file mode 100644 index 0000000..8ccffba --- /dev/null +++ b/arch/arm/mach-pxa/corgi_ssp.c @@ -0,0 +1,248 @@ +/* + * SSP control code for Sharp Corgi devices + * + * Copyright (c) 2004 Richard Purdie + * + * 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/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <asm/hardware.h> + +#include <asm/arch/ssp.h> +#include <asm/arch/corgi.h> +#include <asm/arch/pxa-regs.h> + +static spinlock_t corgi_ssp_lock = SPIN_LOCK_UNLOCKED; +static struct ssp_dev corgi_ssp_dev; +static struct ssp_state corgi_ssp_state; + +/* + * There are three devices connected to the SSP interface: + * 1. A touchscreen controller (TI ADS7846 compatible) + * 2. An LCD contoller (with some Backlight functionality) + * 3. A battery moinitoring IC (Maxim MAX1111) + * + * Each device uses a different speed/mode of communication. + * + * The touchscreen is very sensitive and the most frequently used + * so the port is left configured for this. + * + * Devices are selected using Chip Selects on GPIOs. + */ + +/* + * ADS7846 Routines + */ +unsigned long corgi_ssp_ads7846_putget(ulong data) +{ + unsigned long ret,flag; + + spin_lock_irqsave(&corgi_ssp_lock, flag); + GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + + ssp_write_word(&corgi_ssp_dev,data); + ret = ssp_read_word(&corgi_ssp_dev); + + GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + spin_unlock_irqrestore(&corgi_ssp_lock, flag); + + return ret; +} + +/* + * NOTE: These functions should always be called in interrupt context + * and use the _lock and _unlock functions. They are very time sensitive. + */ +void corgi_ssp_ads7846_lock(void) +{ + spin_lock(&corgi_ssp_lock); + GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); +} + +void corgi_ssp_ads7846_unlock(void) +{ + GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); + spin_unlock(&corgi_ssp_lock); +} + +void corgi_ssp_ads7846_put(ulong data) +{ + ssp_write_word(&corgi_ssp_dev,data); +} + +unsigned long corgi_ssp_ads7846_get(void) +{ + return ssp_read_word(&corgi_ssp_dev); +} + +EXPORT_SYMBOL(corgi_ssp_ads7846_putget); +EXPORT_SYMBOL(corgi_ssp_ads7846_lock); +EXPORT_SYMBOL(corgi_ssp_ads7846_unlock); +EXPORT_SYMBOL(corgi_ssp_ads7846_put); +EXPORT_SYMBOL(corgi_ssp_ads7846_get); + + +/* + * LCD/Backlight Routines + */ +unsigned long corgi_ssp_dac_put(ulong data) +{ + unsigned long flag; + + spin_lock_irqsave(&corgi_ssp_lock, flag); + GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); + + ssp_disable(&corgi_ssp_dev); + ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76)); + ssp_enable(&corgi_ssp_dev); + + ssp_write_word(&corgi_ssp_dev,data); + /* Read null data back from device to prevent SSP overflow */ + ssp_read_word(&corgi_ssp_dev); + + ssp_disable(&corgi_ssp_dev); + ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); + ssp_enable(&corgi_ssp_dev); + GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); + spin_unlock_irqrestore(&corgi_ssp_lock, flag); + + return 0; +} + +void corgi_ssp_lcdtg_send(u8 adrs, u8 data) +{ + corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f)); +} + +void corgi_ssp_blduty_set(int duty) +{ + corgi_ssp_lcdtg_send(0x02,duty); +} + +EXPORT_SYMBOL(corgi_ssp_lcdtg_send); +EXPORT_SYMBOL(corgi_ssp_blduty_set); + +/* + * Max1111 Routines + */ +int corgi_ssp_max1111_get(ulong data) +{ + unsigned long flag; + int voltage,voltage1,voltage2; + + spin_lock_irqsave(&corgi_ssp_lock, flag); + GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); + ssp_disable(&corgi_ssp_dev); + ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(8)); + ssp_enable(&corgi_ssp_dev); + + udelay(1); + + /* TB1/RB1 */ + ssp_write_word(&corgi_ssp_dev,data); + ssp_read_word(&corgi_ssp_dev); /* null read */ + + /* TB12/RB2 */ + ssp_write_word(&corgi_ssp_dev,0); + voltage1=ssp_read_word(&corgi_ssp_dev); + + /* TB13/RB3*/ + ssp_write_word(&corgi_ssp_dev,0); + voltage2=ssp_read_word(&corgi_ssp_dev); + + ssp_disable(&corgi_ssp_dev); + ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); + ssp_enable(&corgi_ssp_dev); + GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); + spin_unlock_irqrestore(&corgi_ssp_lock, flag); + + if (voltage1 & 0xc0 || voltage2 & 0x3f) + voltage = -1; + else + voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03); + + return voltage; +} + +EXPORT_SYMBOL(corgi_ssp_max1111_get); + +/* + * Support Routines + */ +int __init corgi_ssp_probe(struct device *dev) +{ + int ret; + + /* Chip Select - Disable All */ + GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */ + GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */ + GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */ + GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/ + GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS); /* output */ + GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/ + + ret=ssp_init(&corgi_ssp_dev,1); + + if (ret) + printk(KERN_ERR "Unable to register SSP handler!\n"); + else { + ssp_disable(&corgi_ssp_dev); + ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2)); + ssp_enable(&corgi_ssp_dev); + } + + return ret; +} + +static int corgi_ssp_remove(struct device *dev) +{ + ssp_exit(&corgi_ssp_dev); + return 0; +} + +static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level) +{ + if (level == SUSPEND_POWER_DOWN) { + ssp_flush(&corgi_ssp_dev); + ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state); + } + return 0; +} + +static int corgi_ssp_resume(struct device *dev, u32 level) +{ + if (level == RESUME_POWER_ON) { + GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS); /* High - Disable LCD Control/Timing Gen */ + GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/ + GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/ + ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state); + ssp_enable(&corgi_ssp_dev); + } + return 0; +} + +static struct device_driver corgissp_driver = { + .name = "corgi-ssp", + .bus = &platform_bus_type, + .probe = corgi_ssp_probe, + .remove = corgi_ssp_remove, + .suspend = corgi_ssp_suspend, + .resume = corgi_ssp_resume, +}; + +int __init corgi_ssp_init(void) +{ + return driver_register(&corgissp_driver); +} + +arch_initcall(corgi_ssp_init); diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c new file mode 100644 index 0000000..458112b --- /dev/null +++ b/arch/arm/mach-pxa/dma.c @@ -0,0 +1,133 @@ +/* + * linux/arch/arm/mach-pxa/dma.c + * + * PXA DMA registration and IRQ dispatching + * + * Author: Nicolas Pitre + * Created: Nov 15, 2001 + * Copyright: MontaVista Software Inc. + * + * 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/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/errno.h> + +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/dma.h> + +#include <asm/arch/pxa-regs.h> + +static struct dma_channel { + char *name; + void (*irq_handler)(int, void *, struct pt_regs *); + void *data; +} dma_channels[PXA_DMA_CHANNELS]; + + +int pxa_request_dma (char *name, pxa_dma_prio prio, + void (*irq_handler)(int, void *, struct pt_regs *), + void *data) +{ + unsigned long flags; + int i, found = 0; + + /* basic sanity checks */ + if (!name || !irq_handler) + return -EINVAL; + + local_irq_save(flags); + + /* try grabbing a DMA channel with the requested priority */ + for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) { + if (!dma_channels[i].name) { + found = 1; + break; + } + } + + if (!found) { + /* requested prio group is full, try hier priorities */ + for (i = prio-1; i >= 0; i--) { + if (!dma_channels[i].name) { + found = 1; + break; + } + } + } + + if (found) { + DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; + dma_channels[i].name = name; + dma_channels[i].irq_handler = irq_handler; + dma_channels[i].data = data; + } else { + printk (KERN_WARNING "No more available DMA channels for %s\n", name); + i = -ENODEV; + } + + local_irq_restore(flags); + return i; +} + +void pxa_free_dma (int dma_ch) +{ + unsigned long flags; + + if (!dma_channels[dma_ch].name) { + printk (KERN_CRIT + "%s: trying to free channel %d which is already freed\n", + __FUNCTION__, dma_ch); + return; + } + + local_irq_save(flags); + DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; + dma_channels[dma_ch].name = NULL; + local_irq_restore(flags); +} + +static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + int i, dint = DINT; + + for (i = 0; i < PXA_DMA_CHANNELS; i++) { + if (dint & (1 << i)) { + struct dma_channel *channel = &dma_channels[i]; + if (channel->name && channel->irq_handler) { + channel->irq_handler(i, channel->data, regs); + } else { + /* + * IRQ for an unregistered DMA channel: + * let's clear the interrupts and disable it. + */ + printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i); + DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; + } + } + } + return IRQ_HANDLED; +} + +static int __init pxa_dma_init (void) +{ + int ret; + + ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL); + if (ret) + printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); + return ret; +} + +arch_initcall(pxa_dma_init); + +EXPORT_SYMBOL(pxa_request_dma); +EXPORT_SYMBOL(pxa_free_dma); + diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c new file mode 100644 index 0000000..b1575b8 --- /dev/null +++ b/arch/arm/mach-pxa/generic.c @@ -0,0 +1,237 @@ +/* + * linux/arch/arm/mach-pxa/generic.c + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * Code common to all PXA machines. + * + * 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. + * + * Since this file should be linked before any other machine specific file, + * the __initcall() here will be executed first. This serves as default + * initialization stuff for PXA machines which can be overridden later if + * need be. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/ioport.h> +#include <linux/pm.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/mach/map.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/udc.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/mmc.h> + +#include "generic.h" + +/* + * Handy function to set GPIO alternate functions + */ + +void pxa_gpio_mode(int gpio_mode) +{ + unsigned long flags; + int gpio = gpio_mode & GPIO_MD_MASK_NR; + int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; + int gafr; + + local_irq_save(flags); + if (gpio_mode & GPIO_DFLT_LOW) + GPCR(gpio) = GPIO_bit(gpio); + else if (gpio_mode & GPIO_DFLT_HIGH) + GPSR(gpio) = GPIO_bit(gpio); + if (gpio_mode & GPIO_MD_MASK_DIR) + GPDR(gpio) |= GPIO_bit(gpio); + else + GPDR(gpio) &= ~GPIO_bit(gpio); + gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); + GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); + local_irq_restore(flags); +} + +EXPORT_SYMBOL(pxa_gpio_mode); + +/* + * Routine to safely enable or disable a clock in the CKEN + */ +void pxa_set_cken(int clock, int enable) +{ + unsigned long flags; + local_irq_save(flags); + + if (enable) + CKEN |= clock; + else + CKEN &= ~clock; + + local_irq_restore(flags); +} + +EXPORT_SYMBOL(pxa_set_cken); + +/* + * Intel PXA2xx internal register mapping. + * + * Note 1: not all PXA2xx variants implement all those addresses. + * + * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table + * and cache flush area. + */ +static struct map_desc standard_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */ + { 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */ + { 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */ + { 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */ + { 0xfa000000, 0x50000000, 0x00100000, MT_DEVICE }, /* Camera */ + { 0xfe000000, 0x58000000, 0x00100000, MT_DEVICE }, /* IMem ctl */ + { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE } /* UNCACHED_PHYS_0 */ +}; + +void __init pxa_map_io(void) +{ + iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); + get_clk_frequency_khz(1); +} + + +static struct resource pxamci_resources[] = { + [0] = { + .start = 0x41100000, + .end = 0x41100fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MMC, + .end = IRQ_MMC, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxamci_dmamask = 0xffffffffUL; + +static struct platform_device pxamci_device = { + .name = "pxa2xx-mci", + .id = -1, + .dev = { + .dma_mask = &pxamci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxamci_resources), + .resource = pxamci_resources, +}; + +void __init pxa_set_mci_info(struct pxamci_platform_data *info) +{ + pxamci_device.dev.platform_data = info; +} + + +static struct pxa2xx_udc_mach_info pxa_udc_info; + +void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) +{ + memcpy(&pxa_udc_info, info, sizeof *info); +} + +static struct resource pxa2xx_udc_resources[] = { + [0] = { + .start = 0x40600000, + .end = 0x4060ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USB, + .end = IRQ_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 udc_dma_mask = ~(u32)0; + +static struct platform_device udc_device = { + .name = "pxa2xx-udc", + .id = -1, + .resource = pxa2xx_udc_resources, + .num_resources = ARRAY_SIZE(pxa2xx_udc_resources), + .dev = { + .platform_data = &pxa_udc_info, + .dma_mask = &udc_dma_mask, + } +}; + +static struct pxafb_mach_info pxa_fb_info; + +void __init set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info) +{ + memcpy(&pxa_fb_info,hard_pxa_fb_info,sizeof(struct pxafb_mach_info)); +} + +static struct resource pxafb_resources[] = { + [0] = { + .start = 0x44000000, + .end = 0x4400ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 fb_dma_mask = ~(u64)0; + +static struct platform_device pxafb_device = { + .name = "pxa2xx-fb", + .id = -1, + .dev = { + .platform_data = &pxa_fb_info, + .dma_mask = &fb_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxafb_resources), + .resource = pxafb_resources, +}; + +static struct platform_device ffuart_device = { + .name = "pxa2xx-uart", + .id = 0, +}; +static struct platform_device btuart_device = { + .name = "pxa2xx-uart", + .id = 1, +}; +static struct platform_device stuart_device = { + .name = "pxa2xx-uart", + .id = 2, +}; + +static struct platform_device *devices[] __initdata = { + &pxamci_device, + &udc_device, + &pxafb_device, + &ffuart_device, + &btuart_device, + &stuart_device, +}; + +static int __init pxa_init(void) +{ + return platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +subsys_initcall(pxa_init); diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h new file mode 100644 index 0000000..e54a8dd --- /dev/null +++ b/arch/arm/mach-pxa/generic.h @@ -0,0 +1,24 @@ +/* + * linux/arch/arm/mach-pxa/generic.h + * + * Author: Nicolas Pitre + * Copyright: MontaVista Software Inc. + * + * 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. + */ + +struct sys_timer; + +extern struct sys_timer pxa_timer; +extern void __init pxa_map_io(void); +extern void __init pxa_init_irq(void); + +extern unsigned int get_clk_frequency_khz(int info); + +#define SET_BANK(__nr,__start,__size) \ + mi->bank[__nr].start = (__start), \ + mi->bank[__nr].size = (__size), \ + mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) + diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c new file mode 100644 index 0000000..c5a66bf --- /dev/null +++ b/arch/arm/mach-pxa/idp.c @@ -0,0 +1,190 @@ +/* + * linux/arch/arm/mach-pxa/idp.c + * + * 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. + * + * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc. + * + * 2001-09-13: Cliff Brake <cbrake@accelent.com> + * Initial code + * + * 2005-02-15: Cliff Brake <cliff.brake@gmail.com> + * <http://www.vibren.com> <http://bec-systems.com> + * Updated for 2.6 kernel + * + */ + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/device.h> +#include <linux/fb.h> + +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/idp.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/bitfield.h> +#include <asm/arch/mmc.h> + +#include "generic.h" + +/* TODO: + * - add pxa2xx_audio_ops_t device structure + * - Ethernet interrupt + */ + +static struct resource smc91x_resources[] = { + [0] = { + .start = (IDP_ETH_PHYS + 0x300), + .end = (IDP_ETH_PHYS + 0xfffff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO(4), + .end = IRQ_GPIO(4), + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static void idp_backlight_power(int on) +{ + if (on) { + IDP_CPLD_LCD |= (1<<1); + } else { + IDP_CPLD_LCD &= ~(1<<1); + } +} + +static void idp_vlcd(int on) +{ + if (on) { + IDP_CPLD_LCD |= (1<<2); + } else { + IDP_CPLD_LCD &= ~(1<<2); + } +} + +static void idp_lcd_power(int on) +{ + if (on) { + IDP_CPLD_LCD |= (1<<0); + } else { + IDP_CPLD_LCD &= ~(1<<0); + } + + /* call idp_vlcd for now as core driver does not support + * both power and vlcd hooks. Note, this is not technically + * the correct sequence, but seems to work. Disclaimer: + * this may eventually damage the display. + */ + + idp_vlcd(on); +} + +static struct pxafb_mach_info sharp_lm8v31 __initdata = { + .pixclock = 270000, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 1, + .left_margin = 3, + .right_margin = 3, + .vsync_len = 1, + .upper_margin = 0, + .lower_margin = 0, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .cmap_greyscale = 0, + .cmap_inverse = 0, + .cmap_static = 0, + .lccr0 = LCCR0_SDS, + .lccr3 = LCCR3_PCP | LCCR3_Acb(255), + .pxafb_backlight_power = &idp_backlight_power, + .pxafb_lcd_power = &idp_lcd_power +}; + +static int idp_mci_init(struct device *dev, irqreturn_t (*idp_detect_int)(int, void *, struct pt_regs *), void *data) +{ + /* setup GPIO for PXA25x MMC controller */ + pxa_gpio_mode(GPIO6_MMCCLK_MD); + pxa_gpio_mode(GPIO8_MMCCS0_MD); + + return 0; +} + +static struct pxamci_platform_data idp_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = idp_mci_init, +}; + +static void __init idp_init(void) +{ + printk("idp_init()\n"); + + platform_device_register(&smc91x_device); + //platform_device_register(&mst_audio_device); + set_pxa_fb_info(&sharp_lm8v31); + pxa_set_mci_info(&idp_mci_platform_data); +} + +static void __init idp_init_irq(void) +{ + + pxa_init_irq(); + + set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE); +} + +static struct map_desc idp_io_desc[] __initdata = { + /* virtual physical length type */ + + { IDP_COREVOLT_VIRT, + IDP_COREVOLT_PHYS, + IDP_COREVOLT_SIZE, + MT_DEVICE }, + { IDP_CPLD_VIRT, + IDP_CPLD_PHYS, + IDP_CPLD_SIZE, + MT_DEVICE } +}; + +static void __init idp_map_io(void) +{ + pxa_map_io(); + iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc)); + + // serial ports 2 & 3 + pxa_gpio_mode(GPIO42_BTRXD_MD); + pxa_gpio_mode(GPIO43_BTTXD_MD); + pxa_gpio_mode(GPIO44_BTCTS_MD); + pxa_gpio_mode(GPIO45_BTRTS_MD); + pxa_gpio_mode(GPIO46_STRXD_MD); + pxa_gpio_mode(GPIO47_STTXD_MD); + +} + + +MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") + MAINTAINER("Vibren Technologies") + BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) + MAPIO(idp_map_io) + INITIRQ(idp_init_irq) + .timer = &pxa_timer, + INIT_MACHINE(idp_init) +MACHINE_END diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c new file mode 100644 index 0000000..f3cac43 --- /dev/null +++ b/arch/arm/mach-pxa/irq.c @@ -0,0 +1,313 @@ +/* + * linux/arch/arm/mach-pxa/irq.c + * + * Generic PXA IRQ handling, GPIO IRQ demultiplexing, etc. + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * 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/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ptrace.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/arch/pxa-regs.h> + +#include "generic.h" + + +/* + * This is for peripheral IRQs internal to the PXA chip. + */ + +static void pxa_mask_low_irq(unsigned int irq) +{ + ICMR &= ~(1 << (irq + PXA_IRQ_SKIP)); +} + +static void pxa_unmask_low_irq(unsigned int irq) +{ + ICMR |= (1 << (irq + PXA_IRQ_SKIP)); +} + +static struct irqchip pxa_internal_chip_low = { + .ack = pxa_mask_low_irq, + .mask = pxa_mask_low_irq, + .unmask = pxa_unmask_low_irq, +}; + +#if PXA_INTERNAL_IRQS > 32 + +/* + * This is for the second set of internal IRQs as found on the PXA27x. + */ + +static void pxa_mask_high_irq(unsigned int irq) +{ + ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP)); +} + +static void pxa_unmask_high_irq(unsigned int irq) +{ + ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP)); +} + +static struct irqchip pxa_internal_chip_high = { + .ack = pxa_mask_high_irq, + .mask = pxa_mask_high_irq, + .unmask = pxa_unmask_high_irq, +}; + +#endif + +/* + * PXA GPIO edge detection for IRQs: + * IRQs are generated on Falling-Edge, Rising-Edge, or both. + * Use this instead of directly setting GRER/GFER. + */ + +static long GPIO_IRQ_rising_edge[4]; +static long GPIO_IRQ_falling_edge[4]; +static long GPIO_IRQ_mask[4]; + +static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) +{ + int gpio, idx; + + gpio = IRQ_TO_GPIO(irq); + idx = gpio >> 5; + + if (type == IRQT_PROBE) { + /* Don't mess with enabled GPIOs using preconfigured edges or + GPIOs set to alternate function during probe */ + if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) & + GPIO_bit(gpio)) + return 0; + if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2))) + return 0; + type = __IRQT_RISEDGE | __IRQT_FALEDGE; + } + + /* printk(KERN_DEBUG "IRQ%d (GPIO%d): ", irq, gpio); */ + + pxa_gpio_mode(gpio | GPIO_IN); + + if (type & __IRQT_RISEDGE) { + /* printk("rising "); */ + __set_bit (gpio, GPIO_IRQ_rising_edge); + } else + __clear_bit (gpio, GPIO_IRQ_rising_edge); + + if (type & __IRQT_FALEDGE) { + /* printk("falling "); */ + __set_bit (gpio, GPIO_IRQ_falling_edge); + } else + __clear_bit (gpio, GPIO_IRQ_falling_edge); + + /* printk("edges\n"); */ + + GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx]; + GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx]; + return 0; +} + +/* + * GPIO IRQs must be acknowledged. This is for GPIO 0 and 1. + */ + +static void pxa_ack_low_gpio(unsigned int irq) +{ + GEDR0 = (1 << (irq - IRQ_GPIO0)); +} + +static struct irqchip pxa_low_gpio_chip = { + .ack = pxa_ack_low_gpio, + .mask = pxa_mask_low_irq, + .unmask = pxa_unmask_low_irq, + .type = pxa_gpio_irq_type, +}; + +/* + * Demux handler for GPIO>=2 edge detect interrupts + */ + +static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask; + int loop; + + do { + loop = 0; + + mask = GEDR0 & ~3; + if (mask) { + GEDR0 = mask; + irq = IRQ_GPIO(2); + desc = irq_desc + irq; + mask >>= 2; + do { + if (mask & 1) + desc->handle(irq, desc, regs); + irq++; + desc++; + mask >>= 1; + } while (mask); + loop = 1; + } + + mask = GEDR1; + if (mask) { + GEDR1 = mask; + irq = IRQ_GPIO(32); + desc = irq_desc + irq; + do { + if (mask & 1) + desc->handle(irq, desc, regs); + irq++; + desc++; + mask >>= 1; + } while (mask); + loop = 1; + } + + mask = GEDR2; + if (mask) { + GEDR2 = mask; + irq = IRQ_GPIO(64); + desc = irq_desc + irq; + do { + if (mask & 1) + desc->handle(irq, desc, regs); + irq++; + desc++; + mask >>= 1; + } while (mask); + loop = 1; + } + +#if PXA_LAST_GPIO >= 96 + mask = GEDR3; + if (mask) { + GEDR3 = mask; + irq = IRQ_GPIO(96); + desc = irq_desc + irq; + do { + if (mask & 1) + desc->handle(irq, desc, regs); + irq++; + desc++; + mask >>= 1; + } while (mask); + loop = 1; + } +#endif + } while (loop); +} + +static void pxa_ack_muxed_gpio(unsigned int irq) +{ + int gpio = irq - IRQ_GPIO(2) + 2; + GEDR(gpio) = GPIO_bit(gpio); +} + +static void pxa_mask_muxed_gpio(unsigned int irq) +{ + int gpio = irq - IRQ_GPIO(2) + 2; + __clear_bit(gpio, GPIO_IRQ_mask); + GRER(gpio) &= ~GPIO_bit(gpio); + GFER(gpio) &= ~GPIO_bit(gpio); +} + +static void pxa_unmask_muxed_gpio(unsigned int irq) +{ + int gpio = irq - IRQ_GPIO(2) + 2; + int idx = gpio >> 5; + __set_bit(gpio, GPIO_IRQ_mask); + GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx]; + GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx]; +} + +static struct irqchip pxa_muxed_gpio_chip = { + .ack = pxa_ack_muxed_gpio, + .mask = pxa_mask_muxed_gpio, + .unmask = pxa_unmask_muxed_gpio, + .type = pxa_gpio_irq_type, +}; + + +void __init pxa_init_irq(void) +{ + int irq; + + /* disable all IRQs */ + ICMR = 0; + + /* all IRQs are IRQ, not FIQ */ + ICLR = 0; + + /* clear all GPIO edge detects */ + GFER0 = 0; + GFER1 = 0; + GFER2 = 0; + GRER0 = 0; + GRER1 = 0; + GRER2 = 0; + GEDR0 = GEDR0; + GEDR1 = GEDR1; + GEDR2 = GEDR2; + +#ifdef CONFIG_PXA27x + /* And similarly for the extra regs on the PXA27x */ + ICMR2 = 0; + ICLR2 = 0; + GFER3 = 0; + GRER3 = 0; + GEDR3 = GEDR3; +#endif + + /* only unmasked interrupts kick us out of idle */ + ICCR = 1; + + /* GPIO 0 and 1 must have their mask bit always set */ + GPIO_IRQ_mask[0] = 3; + + for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) { + set_irq_chip(irq, &pxa_internal_chip_low); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } + +#if PXA_INTERNAL_IRQS > 32 + for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) { + set_irq_chip(irq, &pxa_internal_chip_high); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } +#endif + + for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { + set_irq_chip(irq, &pxa_low_gpio_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) { + set_irq_chip(irq, &pxa_muxed_gpio_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + /* Install handler for GPIO>=2 edge detect interrupts */ + set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low); + set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); +} diff --git a/arch/arm/mach-pxa/leds-idp.c b/arch/arm/mach-pxa/leds-idp.c new file mode 100644 index 0000000..5eba6ea --- /dev/null +++ b/arch/arm/mach-pxa/leds-idp.c @@ -0,0 +1,117 @@ +/* + * linux/arch/arm/mach-pxa/leds-idp.c + * + * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu> + * + * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com> + * + * Original (leds-footbridge.c) by Russell King + * + * Macros for actual LED manipulation should be in machine specific + * files in this 'mach' directory. + */ + + +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/idp.h> + +#include "leds.h" + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +void idp_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = IDP_HB_LED | IDP_BUSY_LED; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = IDP_HB_LED | IDP_BUSY_LED; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = IDP_HB_LED | IDP_BUSY_LED; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= IDP_HB_LED; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~IDP_BUSY_LED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= IDP_BUSY_LED; + break; +#endif + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= IDP_HB_LED; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~IDP_HB_LED; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= IDP_BUSY_LED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~IDP_BUSY_LED; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + IDP_CPLD_LED_CONTROL = ( (IDP_CPLD_LED_CONTROL | IDP_LEDS_MASK) & ~hw_led_state); + else + IDP_CPLD_LED_CONTROL |= IDP_LEDS_MASK; + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-pxa/leds-lubbock.c b/arch/arm/mach-pxa/leds-lubbock.c new file mode 100644 index 0000000..05cf560 --- /dev/null +++ b/arch/arm/mach-pxa/leds-lubbock.c @@ -0,0 +1,126 @@ +/* + * linux/arch/arm/mach-pxa/leds-lubbock.c + * + * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu> + * + * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com> + * + * Original (leds-footbridge.c) by Russell King + * + * Major surgery on April 2004 by Nicolas Pitre for less global + * namespace collision. Mostly adapted the Mainstone version. + */ + +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/lubbock.h> + +#include "leds.h" + +/* + * 8 discrete leds available for general use: + * + * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays + * so be sure to not monkey with them here. + */ + +#define D28 (1 << 0) +#define D27 (1 << 1) +#define D26 (1 << 2) +#define D25 (1 << 3) +#define D24 (1 << 4) +#define D23 (1 << 5) +#define D22 (1 << 6) +#define D21 (1 << 7) + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +void lubbock_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = 0; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + hw_led_state ^= D26; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + hw_led_state &= ~D27; + break; + + case led_idle_end: + hw_led_state |= D27; + break; +#endif + + case led_halted: + break; + + case led_green_on: + hw_led_state |= D21; + break; + + case led_green_off: + hw_led_state &= ~D21; + break; + + case led_amber_on: + hw_led_state |= D22; + break; + + case led_amber_off: + hw_led_state &= ~D22; + break; + + case led_red_on: + hw_led_state |= D23; + break; + + case led_red_off: + hw_led_state &= ~D23; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + LUB_DISC_BLNK_LED = (LUB_DISC_BLNK_LED | 0xff) & ~hw_led_state; + else + LUB_DISC_BLNK_LED |= 0xff; + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-pxa/leds-mainstone.c b/arch/arm/mach-pxa/leds-mainstone.c new file mode 100644 index 0000000..bbd3f87 --- /dev/null +++ b/arch/arm/mach-pxa/leds-mainstone.c @@ -0,0 +1,121 @@ +/* + * linux/arch/arm/mach-pxa/leds-mainstone.c + * + * Author: Nicolas Pitre + * Created: Nov 05, 2002 + * Copyright: MontaVista Software Inc. + * + * 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/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/mainstone.h> + +#include "leds.h" + + +/* 8 discrete leds available for general use: */ +#define D28 (1 << 0) +#define D27 (1 << 1) +#define D26 (1 << 2) +#define D25 (1 << 3) +#define D24 (1 << 4) +#define D23 (1 << 5) +#define D22 (1 << 6) +#define D21 (1 << 7) + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +void mainstone_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = 0; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + hw_led_state ^= D26; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + hw_led_state &= ~D27; + break; + + case led_idle_end: + hw_led_state |= D27; + break; +#endif + + case led_halted: + break; + + case led_green_on: + hw_led_state |= D21;; + break; + + case led_green_off: + hw_led_state &= ~D21; + break; + + case led_amber_on: + hw_led_state |= D22;; + break; + + case led_amber_off: + hw_led_state &= ~D22; + break; + + case led_red_on: + hw_led_state |= D23;; + break; + + case led_red_off: + hw_led_state &= ~D23; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + MST_LEDCTRL = (MST_LEDCTRL | 0xff) & ~hw_led_state; + else + MST_LEDCTRL |= 0xff; + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c new file mode 100644 index 0000000..bbe4d5f --- /dev/null +++ b/arch/arm/mach-pxa/leds.c @@ -0,0 +1,32 @@ +/* + * linux/arch/arm/mach-pxa/leds.c + * + * xscale LEDs dispatcher + * + * Copyright (C) 2001 Nicolas Pitre + * + * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc. + */ +#include <linux/compiler.h> +#include <linux/init.h> + +#include <asm/leds.h> +#include <asm/mach-types.h> + +#include "leds.h" + +static int __init +pxa_leds_init(void) +{ + if (machine_is_lubbock()) + leds_event = lubbock_leds_event; + if (machine_is_mainstone()) + leds_event = mainstone_leds_event; + if (machine_is_pxa_idp()) + leds_event = idp_leds_event; + + leds_event(led_start); + return 0; +} + +core_initcall(pxa_leds_init); diff --git a/arch/arm/mach-pxa/leds.h b/arch/arm/mach-pxa/leds.h new file mode 100644 index 0000000..d98f6e9 --- /dev/null +++ b/arch/arm/mach-pxa/leds.h @@ -0,0 +1,12 @@ +/* + * include/asm-arm/arch-pxa/leds.h + * + * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc. + * + * blinky lights for various PXA-based systems: + * + */ + +extern void idp_leds_event(led_event_t evt); +extern void lubbock_leds_event(led_event_t evt); +extern void mainstone_leds_event(led_event_t evt); diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c new file mode 100644 index 0000000..dd012d6 --- /dev/null +++ b/arch/arm/mach-pxa/lubbock.c @@ -0,0 +1,247 @@ +/* + * linux/arch/arm/mach-pxa/lubbock.c + * + * Support for the Intel DBPXA250 Development Platform. + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/major.h> +#include <linux/fb.h> +#include <linux/interrupt.h> + +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware/sa1111.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/lubbock.h> +#include <asm/arch/udc.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/mmc.h> + +#include "generic.h" + + +#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080) + +void lubbock_set_misc_wr(unsigned int mask, unsigned int set) +{ + unsigned long flags; + + local_irq_save(flags); + LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask); + local_irq_restore(flags); +} +EXPORT_SYMBOL(lubbock_set_misc_wr); + +static unsigned long lubbock_irq_enabled; + +static void lubbock_mask_irq(unsigned int irq) +{ + int lubbock_irq = (irq - LUBBOCK_IRQ(0)); + LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq)); +} + +static void lubbock_unmask_irq(unsigned int irq) +{ + int lubbock_irq = (irq - LUBBOCK_IRQ(0)); + /* the irq can be acknowledged only if deasserted, so it's done here */ + LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq); + LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq)); +} + +static struct irqchip lubbock_irq_chip = { + .ack = lubbock_mask_irq, + .mask = lubbock_mask_irq, + .unmask = lubbock_unmask_irq, +}; + +static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; + do { + GEDR(0) = GPIO_bit(0); /* clear our parent irq */ + if (likely(pending)) { + irq = LUBBOCK_IRQ(0) + __ffs(pending); + desc = irq_desc + irq; + desc->handle(irq, desc, regs); + } + pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; + } while (pending); +} + +static void __init lubbock_init_irq(void) +{ + int irq; + + pxa_init_irq(); + + /* setup extra lubbock irqs */ + for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) { + set_irq_chip(irq, &lubbock_irq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler); + set_irq_type(IRQ_GPIO(0), IRQT_FALLING); +} + +static int lubbock_udc_is_connected(void) +{ + return (LUB_MISC_RD & (1 << 9)) == 0; +} + +static struct pxa2xx_udc_mach_info udc_info __initdata = { + .udc_is_connected = lubbock_udc_is_connected, + // no D+ pullup; lubbock can't connect/disconnect in software +}; + +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x10000000, + .end = 0x10001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = LUBBOCK_SA1111_IRQ, + .end = LUBBOCK_SA1111_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = -1, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = 0x0c000000, + .end = 0x0c0fffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = LUBBOCK_ETH_IRQ, + .end = LUBBOCK_ETH_IRQ, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "smc91x-attrib", + .start = 0x0e000000, + .end = 0x0e0fffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, + &smc91x_device, +}; + +static struct pxafb_mach_info sharp_lm8v31 __initdata = { + .pixclock = 270000, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 1, + .left_margin = 3, + .right_margin = 3, + .vsync_len = 1, + .upper_margin = 0, + .lower_margin = 0, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .cmap_greyscale = 0, + .cmap_inverse = 0, + .cmap_static = 0, + .lccr0 = LCCR0_SDS, + .lccr3 = LCCR3_PCP | LCCR3_Acb(255), +}; + +static int lubbock_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data) +{ + /* setup GPIO for PXA25x MMC controller */ + pxa_gpio_mode(GPIO6_MMCCLK_MD); + pxa_gpio_mode(GPIO8_MMCCS0_MD); + + return 0; +} + +static struct pxamci_platform_data lubbock_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = lubbock_mci_init, +}; + +static void __init lubbock_init(void) +{ + pxa_set_udc_info(&udc_info); + set_pxa_fb_info(&sharp_lm8v31); + pxa_set_mci_info(&lubbock_mci_platform_data); + (void) platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +static struct map_desc lubbock_io_desc[] __initdata = { + { LUBBOCK_FPGA_VIRT, LUBBOCK_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */ +}; + +static void __init lubbock_map_io(void) +{ + pxa_map_io(); + iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc)); + + /* This enables the BTUART */ + pxa_gpio_mode(GPIO42_BTRXD_MD); + pxa_gpio_mode(GPIO43_BTTXD_MD); + pxa_gpio_mode(GPIO44_BTCTS_MD); + pxa_gpio_mode(GPIO45_BTRTS_MD); + + /* This is for the SMC chip select */ + pxa_gpio_mode(GPIO79_nCS_3_MD); + + /* setup sleep mode values */ + PWER = 0x00000002; + PFER = 0x00000000; + PRER = 0x00000002; + PGSR0 = 0x00008000; + PGSR1 = 0x003F0202; + PGSR2 = 0x0001C000; + PCFR |= PCFR_OPDE; +} + +MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") + MAINTAINER("MontaVista Software Inc.") + BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) + MAPIO(lubbock_map_io) + INITIRQ(lubbock_init_irq) + .timer = &pxa_timer, + INIT_MACHINE(lubbock_init) +MACHINE_END diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c new file mode 100644 index 0000000..3f95223 --- /dev/null +++ b/arch/arm/mach-pxa/mainstone.c @@ -0,0 +1,316 @@ +/* + * linux/arch/arm/mach-pxa/mainstone.c + * + * Support for the Intel HCDDBBVA0 Development Platform. + * (go figure how they came up with such name...) + * + * Author: Nicolas Pitre + * Created: Nov 05, 2002 + * Copyright: MontaVista Software Inc. + * + * 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/init.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/sched.h> +#include <linux/bitops.h> +#include <linux/fb.h> + +#include <asm/types.h> +#include <asm/setup.h> +#include <asm/memory.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/mainstone.h> +#include <asm/arch/audio.h> +#include <asm/arch/pxafb.h> +#include <asm/arch/mmc.h> + +#include "generic.h" + + +static unsigned long mainstone_irq_enabled; + +static void mainstone_mask_irq(unsigned int irq) +{ + int mainstone_irq = (irq - MAINSTONE_IRQ(0)); + MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq)); +} + +static void mainstone_unmask_irq(unsigned int irq) +{ + int mainstone_irq = (irq - MAINSTONE_IRQ(0)); + /* the irq can be acknowledged only if deasserted, so it's done here */ + MST_INTSETCLR &= ~(1 << mainstone_irq); + MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq)); +} + +static struct irqchip mainstone_irq_chip = { + .ack = mainstone_mask_irq, + .mask = mainstone_mask_irq, + .unmask = mainstone_unmask_irq, +}; + + +static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled; + do { + GEDR(0) = GPIO_bit(0); /* clear useless edge notification */ + if (likely(pending)) { + irq = MAINSTONE_IRQ(0) + __ffs(pending); + desc = irq_desc + irq; + desc->handle(irq, desc, regs); + } + pending = MST_INTSETCLR & mainstone_irq_enabled; + } while (pending); +} + +static void __init mainstone_init_irq(void) +{ + int irq; + + pxa_init_irq(); + + /* setup extra Mainstone irqs */ + for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { + set_irq_chip(irq, &mainstone_irq_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + set_irq_flags(MAINSTONE_IRQ(8), 0); + set_irq_flags(MAINSTONE_IRQ(12), 0); + + MST_INTMSKENA = 0; + MST_INTSETCLR = 0; + + set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); + set_irq_type(IRQ_GPIO(0), IRQT_FALLING); +} + + +static struct resource smc91x_resources[] = { + [0] = { + .start = (MST_ETH_PHYS + 0x300), + .end = (MST_ETH_PHYS + 0xfffff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MAINSTONE_IRQ(3), + .end = MAINSTONE_IRQ(3), + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv) +{ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF; + return 0; +} + +static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv) +{ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; +} + +static long mst_audio_suspend_mask; + +static void mst_audio_suspend(void *priv) +{ + mst_audio_suspend_mask = MST_MSCWR2; + MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; +} + +static void mst_audio_resume(void *priv) +{ + MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF; +} + +static pxa2xx_audio_ops_t mst_audio_ops = { + .startup = mst_audio_startup, + .shutdown = mst_audio_shutdown, + .suspend = mst_audio_suspend, + .resume = mst_audio_resume, +}; + +static struct platform_device mst_audio_device = { + .name = "pxa2xx-ac97", + .id = -1, + .dev = { .platform_data = &mst_audio_ops }, +}; + +static void mainstone_backlight_power(int on) +{ + if (on) { + pxa_gpio_mode(GPIO16_PWM0_MD); + pxa_set_cken(CKEN0_PWM0, 1); + PWM_CTRL0 = 0; + PWM_PWDUTY0 = 0x3ff; + PWM_PERVAL0 = 0x3ff; + } else { + PWM_CTRL0 = 0; + PWM_PWDUTY0 = 0x0; + PWM_PERVAL0 = 0x3FF; + pxa_set_cken(CKEN0_PWM0, 0); + } +} + +static struct pxafb_mach_info toshiba_ltm04c380k __initdata = { + .pixclock = 50000, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 1, + .left_margin = 0x9f, + .right_margin = 1, + .vsync_len = 44, + .upper_margin = 0, + .lower_margin = 0, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, + .lccr0 = LCCR0_Act, + .lccr3 = LCCR3_PCP, + .pxafb_backlight_power = mainstone_backlight_power, +}; + +static struct pxafb_mach_info toshiba_ltm035a776c __initdata = { + .pixclock = 110000, + .xres = 240, + .yres = 320, + .bpp = 16, + .hsync_len = 4, + .left_margin = 8, + .right_margin = 20, + .vsync_len = 3, + .upper_margin = 1, + .lower_margin = 10, + .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, + .lccr0 = LCCR0_Act, + .lccr3 = LCCR3_PCP, + .pxafb_backlight_power = mainstone_backlight_power, +}; + +static int mainstone_mci_init(struct device *dev, irqreturn_t (*mstone_detect_int)(int, void *, struct pt_regs *), void *data) +{ + int err; + + /* + * setup GPIO for PXA27x MMC controller + */ + pxa_gpio_mode(GPIO32_MMCCLK_MD); + pxa_gpio_mode(GPIO112_MMCCMD_MD); + pxa_gpio_mode(GPIO92_MMCDAT0_MD); + pxa_gpio_mode(GPIO109_MMCDAT1_MD); + pxa_gpio_mode(GPIO110_MMCDAT2_MD); + pxa_gpio_mode(GPIO111_MMCDAT3_MD); + + /* make sure SD/Memory Stick multiplexer's signals + * are routed to MMC controller + */ + MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL; + + err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, SA_INTERRUPT, + "MMC card detect", data); + if (err) { + printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); + return -1; + } + + return 0; +} + +static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data* p_d = dev->platform_data; + + if (( 1 << vdd) & p_d->ocr_mask) { + printk(KERN_DEBUG "%s: on\n", __FUNCTION__); + MST_MSCWR1 |= MST_MSCWR1_MMC_ON; + MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL; + } else { + printk(KERN_DEBUG "%s: off\n", __FUNCTION__); + MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON; + } +} + +static void mainstone_mci_exit(struct device *dev, void *data) +{ + free_irq(MAINSTONE_MMC_IRQ, data); +} + +static struct pxamci_platform_data mainstone_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .init = mainstone_mci_init, + .setpower = mainstone_mci_setpower, + .exit = mainstone_mci_exit, +}; + +static void __init mainstone_init(void) +{ + /* + * On Mainstone, we route AC97_SYSCLK via GPIO45 to + * the audio daughter card + */ + pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); + + platform_device_register(&smc91x_device); + platform_device_register(&mst_audio_device); + + /* reading Mainstone's "Virtual Configuration Register" + might be handy to select LCD type here */ + if (0) + set_pxa_fb_info(&toshiba_ltm04c380k); + else + set_pxa_fb_info(&toshiba_ltm035a776c); + + pxa_set_mci_info(&mainstone_mci_platform_data); +} + + +static struct map_desc mainstone_io_desc[] __initdata = { + { MST_FPGA_VIRT, MST_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */ +}; + +static void __init mainstone_map_io(void) +{ + pxa_map_io(); + iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc)); + + /* initialize sleep mode regs (wake-up sources, etc) */ + PGSR0 = 0x00008800; + PGSR1 = 0x00000002; + PGSR2 = 0x0001FC00; + PGSR3 = 0x00001F81; + PWER = 0xC0000002; + PRER = 0x00000002; + PFER = 0x00000002; +} + +MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") + MAINTAINER("MontaVista Software Inc.") + BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) + MAPIO(mainstone_map_io) + INITIRQ(mainstone_init_irq) + .timer = &pxa_timer, + INIT_MACHINE(mainstone_init) +MACHINE_END diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c new file mode 100644 index 0000000..82a4bf3 --- /dev/null +++ b/arch/arm/mach-pxa/pm.c @@ -0,0 +1,227 @@ +/* + * PXA250/210 Power Management Routines + * + * Original code for the SA11x0: + * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> + * + * Modified for the PXA250 by Nicolas Pitre: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/suspend.h> +#include <linux/errno.h> +#include <linux/time.h> + +#include <asm/hardware.h> +#include <asm/memory.h> +#include <asm/system.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/lubbock.h> +#include <asm/mach/time.h> + + +/* + * Debug macros + */ +#undef DEBUG + +extern void pxa_cpu_suspend(void); +extern void pxa_cpu_resume(void); + +#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x +#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] + +#define RESTORE_GPLEVEL(n) do { \ + GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ + GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ +} while (0) + +/* + * List of global PXA peripheral registers to preserve. + * More ones like CP and general purpose register values are preserved + * with the stack pointer in sleep.S. + */ +enum { SLEEP_SAVE_START = 0, + + SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, + SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, + SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, + SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, + SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, + + SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, + SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, + SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, + SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U, + + SLEEP_SAVE_PSTR, + + SLEEP_SAVE_ICMR, + SLEEP_SAVE_CKEN, + + SLEEP_SAVE_CKSUM, + + SLEEP_SAVE_SIZE +}; + + +static int pxa_pm_enter(suspend_state_t state) +{ + unsigned long sleep_save[SLEEP_SAVE_SIZE]; + unsigned long checksum = 0; + struct timespec delta, rtc; + int i; + + if (state != PM_SUSPEND_MEM) + return -EINVAL; + +#ifdef CONFIG_IWMMXT + /* force any iWMMXt context to ram **/ + iwmmxt_task_disable(NULL); +#endif + + /* preserve current time */ + rtc.tv_sec = RCNR; + rtc.tv_nsec = 0; + save_time_delta(&delta, &rtc); + + SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); + SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); + SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); + SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); + SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); + + SAVE(GAFR0_L); SAVE(GAFR0_U); + SAVE(GAFR1_L); SAVE(GAFR1_U); + SAVE(GAFR2_L); SAVE(GAFR2_U); + +#ifdef CONFIG_PXA27x + SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); + SAVE(GAFR3_L); SAVE(GAFR3_U); +#endif + + SAVE(ICMR); + ICMR = 0; + + SAVE(CKEN); + CKEN = 0; + + SAVE(PSTR); + + /* Note: wake up source are set up in each machine specific files */ + + /* clear GPIO transition detect bits */ + GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; +#ifdef CONFIG_PXA27x + GEDR3 = GEDR3; +#endif + + /* Clear sleep reset status */ + RCSR = RCSR_SMR; + + /* set resume return address */ + PSPR = virt_to_phys(pxa_cpu_resume); + + /* before sleeping, calculate and save a checksum */ + for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) + checksum += sleep_save[i]; + sleep_save[SLEEP_SAVE_CKSUM] = checksum; + + /* *** go zzz *** */ + pxa_cpu_suspend(); + + /* after sleeping, validate the checksum */ + checksum = 0; + for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) + checksum += sleep_save[i]; + + /* if invalid, display message and wait for a hardware reset */ + if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) { +#ifdef CONFIG_ARCH_LUBBOCK + LUB_HEXLED = 0xbadbadc5; +#endif + while (1) + pxa_cpu_suspend(); + } + + /* ensure not to come back here if it wasn't intended */ + PSPR = 0; + + /* restore registers */ + RESTORE(GAFR0_L); RESTORE(GAFR0_U); + RESTORE(GAFR1_L); RESTORE(GAFR1_U); + RESTORE(GAFR2_L); RESTORE(GAFR2_U); + RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); + RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); + RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); + RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); + RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); + +#ifdef CONFIG_PXA27x + RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); + RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); +#endif + + PSSR = PSSR_RDH | PSSR_PH; + + RESTORE(CKEN); + + ICLR = 0; + ICCR = 1; + RESTORE(ICMR); + + RESTORE(PSTR); + + /* restore current time */ + rtc.tv_sec = RCNR; + restore_time_delta(&delta, &rtc); + +#ifdef DEBUG + printk(KERN_DEBUG "*** made it back from resume\n"); +#endif + + return 0; +} + +unsigned long sleep_phys_sp(void *sp) +{ + return virt_to_phys(sp); +} + +/* + * Called after processes are frozen, but before we shut down devices. + */ +static int pxa_pm_prepare(suspend_state_t state) +{ + return 0; +} + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +static int pxa_pm_finish(suspend_state_t state) +{ + return 0; +} + +/* + * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. + */ +static struct pm_ops pxa_pm_ops = { + .pm_disk_mode = PM_DISK_FIRMWARE, + .prepare = pxa_pm_prepare, + .enter = pxa_pm_enter, + .finish = pxa_pm_finish, +}; + +static int __init pxa_pm_init(void) +{ + pm_set_ops(&pxa_pm_ops); + return 0; +} + +late_initcall(pxa_pm_init); diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c new file mode 100644 index 0000000..b6c746e --- /dev/null +++ b/arch/arm/mach-pxa/poodle.c @@ -0,0 +1,189 @@ +/* + * linux/arch/arm/mach-pxa/poodle.c + * + * Support for the SHARP Poodle Board. + * + * Based on: + * linux/arch/arm/mach-pxa/lubbock.c Author: Nicolas Pitre + * + * 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. + * + * Change Log + * 12-Dec-2002 Sharp Corporation for Poodle + * John Lenz <lenz@cs.wisc.edu> updates to 2.6 + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/fb.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/setup.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/arch/pxa-regs.h> +#include <asm/arch/irq.h> +#include <asm/arch/poodle.h> +#include <asm/arch/pxafb.h> + +#include <asm/hardware/scoop.h> +#include <asm/hardware/locomo.h> +#include <asm/mach/sharpsl_param.h> + +#include "generic.h" + +static struct resource poodle_scoop_resources[] = { + [0] = { + .start = 0x10800000, + .end = 0x10800fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct scoop_config poodle_scoop_setup = { + .io_dir = POODLE_SCOOP_IO_DIR, + .io_out = POODLE_SCOOP_IO_OUT, +}; + +struct platform_device poodle_scoop_device = { + .name = "sharp-scoop", + .id = -1, + .dev = { + .platform_data = &poodle_scoop_setup, + }, + .num_resources = ARRAY_SIZE(poodle_scoop_resources), + .resource = poodle_scoop_resources, +}; + + +/* LoCoMo device */ +static struct resource locomo_resources[] = { + [0] = { + .start = 0x10000000, + .end = 0x10001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO(10), + .end = IRQ_GPIO(10), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device locomo_device = { + .name = "locomo", + .id = 0, + .num_resources = ARRAY_SIZE(locomo_resources), + .resource = locomo_resources, +}; + +/* PXAFB device */ +static struct pxafb_mach_info poodle_fb_info __initdata = { + .pixclock = 144700, + + .xres = 320, + .yres = 240, + .bpp = 16, + + .hsync_len = 7, + .left_margin = 11, + .right_margin = 30, + + .vsync_len = 2, + .upper_margin = 2, + .lower_margin = 0, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + + .lccr0 = LCCR0_Act | LCCR0_Sngl | LCCR0_Color, + .lccr3 = 0, + + .pxafb_backlight_power = NULL, + .pxafb_lcd_power = NULL, +}; + +static struct platform_device *devices[] __initdata = { + &locomo_device, + &poodle_scoop_device, +}; + +static void __init poodle_init(void) +{ + int ret = 0; + + /* cpu initialize */ + /* Pgsr Register */ + PGSR0 = 0x0146dd80; + PGSR1 = 0x03bf0890; + PGSR2 = 0x0001c000; + + /* Alternate Register */ + GAFR0_L = 0x01001000; + GAFR0_U = 0x591a8010; + GAFR1_L = 0x900a8451; + GAFR1_U = 0xaaa5aaaa; + GAFR2_L = 0x8aaaaaaa; + GAFR2_U = 0x00000002; + + /* Direction Register */ + GPDR0 = 0xd3f0904c; + GPDR1 = 0xfcffb7d3; + GPDR2 = 0x0001ffff; + + /* Output Register */ + GPCR0 = 0x00000000; + GPCR1 = 0x00000000; + GPCR2 = 0x00000000; + + GPSR0 = 0x00400000; + GPSR1 = 0x00000000; + GPSR2 = 0x00000000; + + set_pxa_fb_info(&poodle_fb_info); + + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + if (ret) { + printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n"); + } +} + +static void __init fixup_poodle(struct machine_desc *desc, + struct tag *tags, char **cmdline, struct meminfo *mi) +{ + sharpsl_save_param(); +} + +static struct map_desc poodle_io_desc[] __initdata = { + /* virtual physical length */ + { 0xef800000, 0x00000000, 0x00800000, MT_DEVICE }, /* Boot Flash */ +}; + +static void __init poodle_map_io(void) +{ + pxa_map_io(); + iotable_init(poodle_io_desc, ARRAY_SIZE(poodle_io_desc)); + + /* setup sleep mode values */ + PWER = 0x00000002; + PFER = 0x00000000; + PRER = 0x00000002; + PGSR0 = 0x00008000; + PGSR1 = 0x003F0202; + PGSR2 = 0x0001C000; + PCFR |= PCFR_OPDE; +} + +MACHINE_START(POODLE, "SHARP Poodle") + BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) + FIXUP(fixup_poodle) + MAPIO(poodle_map_io) + INITIRQ(pxa_init_irq) + .timer = &pxa_timer, + .init_machine = poodle_init, +MACHINE_END diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c new file mode 100644 index 0000000..e887b71 --- /dev/null +++ b/arch/arm/mach-pxa/pxa25x.c @@ -0,0 +1,104 @@ +/* + * linux/arch/arm/mach-pxa/pxa25x.c + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * Code specific to PXA21x/25x/26x variants. + * + * 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. + * + * Since this file should be linked before any other machine specific file, + * the __initcall() here will be executed first. This serves as default + * initialization stuff for PXA machines which can be overridden later if + * need be. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pm.h> + +#include <asm/hardware.h> +#include <asm/arch/pxa-regs.h> + +#include "generic.h" + +/* + * Various clock factors driven by the CCCR register. + */ + +/* Crystal Frequency to Memory Frequency Multiplier (L) */ +static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, }; + +/* Memory Frequency to Run Mode Frequency Multiplier (M) */ +static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 }; + +/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */ +/* Note: we store the value N * 2 here. */ +static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 }; + +/* Crystal clock */ +#define BASE_CLK 3686400 + +/* + * Get the clock frequency as reflected by CCCR and the turbo flag. + * We assume these values have been applied via a fcs. + * If info is not 0 we also display the current settings. + */ +unsigned int get_clk_frequency_khz(int info) +{ + unsigned long cccr, turbo; + unsigned int l, L, m, M, n2, N; + + cccr = CCCR; + asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) ); + + l = L_clk_mult[(cccr >> 0) & 0x1f]; + m = M_clk_mult[(cccr >> 5) & 0x03]; + n2 = N2_clk_mult[(cccr >> 7) & 0x07]; + + L = l * BASE_CLK; + M = m * L; + N = n2 * M / 2; + + if(info) + { + L += 5000; + printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n", + L / 1000000, (L % 1000000) / 10000, l ); + M += 5000; + printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n", + M / 1000000, (M % 1000000) / 10000, m ); + N += 5000; + printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n", + N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5, + (turbo & 1) ? "" : "in" ); + } + + return (turbo & 1) ? (N/1000) : (M/1000); +} + +EXPORT_SYMBOL(get_clk_frequency_khz); + +/* + * Return the current memory clock frequency in units of 10kHz + */ +unsigned int get_memclk_frequency_10khz(void) +{ + return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000; +} + +EXPORT_SYMBOL(get_memclk_frequency_10khz); + +/* + * Return the current LCD clock frequency in units of 10kHz + */ +unsigned int get_lcdclk_frequency_10khz(void) +{ + return get_memclk_frequency_10khz(); +} + +EXPORT_SYMBOL(get_lcdclk_frequency_10khz); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c new file mode 100644 index 0000000..7e863af --- /dev/null +++ b/arch/arm/mach-pxa/pxa27x.c @@ -0,0 +1,163 @@ +/* + * linux/arch/arm/mach-pxa/pxa27x.c + * + * Author: Nicolas Pitre + * Created: Nov 05, 2002 + * Copyright: MontaVista Software Inc. + * + * Code specific to PXA27x aka Bulverde. + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pm.h> +#include <linux/device.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/arch/pxa-regs.h> + +#include "generic.h" + +/* Crystal clock: 13MHz */ +#define BASE_CLK 13000000 + +/* + * Get the clock frequency as reflected by CCSR and the turbo flag. + * We assume these values have been applied via a fcs. + * If info is not 0 we also display the current settings. + */ +unsigned int get_clk_frequency_khz( int info) +{ + unsigned long ccsr, clkcfg; + unsigned int l, L, m, M, n2, N, S; + int cccr_a, t, ht, b; + + ccsr = CCSR; + cccr_a = CCCR & (1 << 25); + + /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ + asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); + t = clkcfg & (1 << 1); + ht = clkcfg & (1 << 2); + b = clkcfg & (1 << 3); + + l = ccsr & 0x1f; + n2 = (ccsr>>7) & 0xf; + m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; + + L = l * BASE_CLK; + N = (L * n2) / 2; + M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); + S = (b) ? L : (L/2); + + if (info) { + printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n", + L / 1000000, (L % 1000000) / 10000, l ); + printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n", + N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5, + (t) ? "" : "in" ); + printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n", + M / 1000000, (M % 1000000) / 10000, m ); + printk( KERN_INFO "System bus clock: %d.%02dMHz \n", + S / 1000000, (S % 1000000) / 10000 ); + } + + return (t) ? (N/1000) : (L/1000); +} + +/* + * Return the current mem clock frequency in units of 10kHz as + * reflected by CCCR[A], B, and L + */ +unsigned int get_memclk_frequency_10khz(void) +{ + unsigned long ccsr, clkcfg; + unsigned int l, L, m, M; + int cccr_a, b; + + ccsr = CCSR; + cccr_a = CCCR & (1 << 25); + + /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ + asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); + b = clkcfg & (1 << 3); + + l = ccsr & 0x1f; + m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; + + L = l * BASE_CLK; + M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); + + return (M / 10000); +} + +/* + * Return the current LCD clock frequency in units of 10kHz as + */ +unsigned int get_lcdclk_frequency_10khz(void) +{ + unsigned long ccsr; + unsigned int l, L, k, K; + + ccsr = CCSR; + + l = ccsr & 0x1f; + k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4; + + L = l * BASE_CLK; + K = L / k; + + return (K / 10000); +} + +EXPORT_SYMBOL(get_clk_frequency_khz); +EXPORT_SYMBOL(get_memclk_frequency_10khz); +EXPORT_SYMBOL(get_lcdclk_frequency_10khz); + + +/* + * device registration specific to PXA27x. + */ + +static u64 pxa27x_dmamask = 0xffffffffUL; + +static struct resource pxa27x_ohci_resources[] = { + [0] = { + .start = 0x4C000000, + .end = 0x4C00ff6f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USBH1, + .end = IRQ_USBH1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ohci_device = { + .name = "pxa27x-ohci", + .id = -1, + .dev = { + .dma_mask = &pxa27x_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa27x_ohci_resources), + .resource = pxa27x_ohci_resources, +}; + +static struct platform_device *devices[] __initdata = { + &ohci_device, +}; + +static int __init pxa27x_init(void) +{ + return platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +subsys_initcall(pxa27x_init); diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S new file mode 100644 index 0000000..16cad2c --- /dev/null +++ b/arch/arm/mach-pxa/sleep.S @@ -0,0 +1,194 @@ +/* + * Low-level PXA250/210 sleep/wakeUp support + * + * Initial SA1110 code: + * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> + * + * Adapted for PXA by Nicolas Pitre: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + */ + +#include <linux/config.h> +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> + +#include <asm/arch/pxa-regs.h> + + .text + +/* + * pxa_cpu_suspend() + * + * Forces CPU into sleep state + */ + +ENTRY(pxa_cpu_suspend) + + mra r2, r3, acc0 + stmfd sp!, {r2 - r12, lr} @ save registers on stack + + @ get coprocessor registers + mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode + mrc p15, 0, r4, c15, c1, 0 @ CP access reg + mrc p15, 0, r5, c13, c0, 0 @ PID + mrc p15, 0, r6, c3, c0, 0 @ domain ID + mrc p15, 0, r7, c2, c0, 0 @ translation table base addr + mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg + mrc p15, 0, r9, c1, c0, 0 @ control reg + + bic r3, r3, #2 @ clear frequency change bit + + @ store them plus current virtual stack ptr on stack + mov r10, sp + stmfd sp!, {r3 - r10} + + @ preserve phys address of stack + mov r0, sp + bl sleep_phys_sp + ldr r1, =sleep_save_sp + str r0, [r1] + + @ clean data cache + bl xscale_flush_kern_cache_all + + @ Put the processor to sleep + @ (also workaround for sighting 28071) + + @ prepare value for sleep mode + mov r1, #3 @ sleep mode + + @ prepare to put SDRAM into self-refresh manually + ldr r4, =MDREFR + ldr r5, [r4] + orr r5, r5, #MDREFR_SLFRSH + + @ prepare pointer to physical address 0 (virtual mapping in generic.c) + mov r2, #UNCACHED_PHYS_0 + + @ Intel PXA255 Specification Update notes problems + @ about suspending with PXBus operating above 133MHz + @ (see Errata 31, GPIO output signals, ... unpredictable in sleep + @ + @ We keep the change-down close to the actual suspend on SDRAM + @ as possible to eliminate messing about with the refresh clock + @ as the system will restore with the original speed settings + @ + @ Ben Dooks, 13-Sep-2004 + + ldr r6, =CCCR + ldr r8, [r6] @ keep original value for resume + + @ ensure x1 for run and turbo mode with memory clock + bic r7, r8, #CCCR_M_MASK | CCCR_N_MASK + orr r7, r7, #(1<<5) | (2<<7) + + @ check that the memory frequency is within limits + and r14, r7, #CCCR_L_MASK + teq r14, #1 + bicne r7, r7, #CCCR_L_MASK + orrne r7, r7, #1 @@ 99.53MHz + + @ get ready for the change + + @ note, turbo is not preserved over sleep so there is no + @ point in preserving it here. we save it on the stack with the + @ other CP registers instead. + mov r0, #0 + mcr p14, 0, r0, c6, c0, 0 + orr r0, r0, #2 @ initiate change bit + + @ align execution to a cache line + b 1f + + .ltorg + .align 5 +1: + + @ All needed values are now in registers. + @ These last instructions should be in cache + + @ initiate the frequency change... + str r7, [r6] + mcr p14, 0, r0, c6, c0, 0 + + @ restore the original cpu speed value for resume + str r8, [r6] + + @ put SDRAM into self-refresh + str r5, [r4] + + @ force address lines low by reading at physical address 0 + ldr r3, [r2] + + @ enter sleep mode + mcr p14, 0, r1, c7, c0, 0 + +20: b 20b @ loop waiting for sleep + +/* + * cpu_pxa_resume() + * + * entry point from bootloader into kernel during resume + * + * Note: Yes, part of the following code is located into the .data section. + * This is to allow sleep_save_sp to be accessed with a relative load + * while we can't rely on any MMU translation. We could have put + * sleep_save_sp in the .text section as well, but some setups might + * insist on it to be truly read-only. + */ + + .data + .align 5 +ENTRY(pxa_cpu_resume) + mov r0, #PSR_I_BIT | PSR_F_BIT | MODE_SVC @ set SVC, irqs off + msr cpsr_c, r0 + + ldr r0, sleep_save_sp @ stack phys addr + ldr r2, =resume_after_mmu @ its absolute virtual address + ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr + + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB + +#ifdef CONFIG_XSCALE_CACHE_ERRATA + bic r9, r9, #0x0004 @ see cpu_xscale_proc_init +#endif + + mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode. + mcr p15, 0, r4, c15, c1, 0 @ CP access reg + mcr p15, 0, r5, c13, c0, 0 @ PID + mcr p15, 0, r6, c3, c0, 0 @ domain ID + mcr p15, 0, r7, c2, c0, 0 @ translation table base addr + mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg + b resume_turn_on_mmu @ cache align execution + + .align 5 +resume_turn_on_mmu: + mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, caches, etc. + + @ Let us ensure we jump to resume_after_mmu only when the mcr above + @ actually took effect. They call it the "cpwait" operation. + mrc p15, 0, r1, c2, c0, 0 @ queue a dependency on CP15 + sub pc, r2, r1, lsr #32 @ jump to virtual addr + nop + nop + nop + +sleep_save_sp: + .word 0 @ preserve stack phys ptr here + + .text +resume_after_mmu: +#ifdef CONFIG_XSCALE_CACHE_ERRATA + bl cpu_xscale_proc_init +#endif + ldmfd sp!, {r2, r3} + mar acc0, r2, r3 + ldmfd sp!, {r4 - r12, pc} @ return to caller + + diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c new file mode 100644 index 0000000..4d826c0 --- /dev/null +++ b/arch/arm/mach-pxa/ssp.c @@ -0,0 +1,363 @@ +/* + * linux/arch/arm/mach-pxa/ssp.c + * + * based on linux/arch/arm/mach-sa1100/ssp.c by Russell King + * + * Copyright (C) 2003 Russell King. + * Copyright (C) 2003 Wolfson Microelectronics PLC + * + * 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. + * + * PXA2xx SSP driver. This provides the generic core for simple + * IO-based SSP applications and allows easy port setup for DMA access. + * + * Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com> + * + * Revision history: + * 22nd Aug 2003 Initial version. + * 20th Dec 2004 Added ssp_config for changing port config without + * closing the port. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/init.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/arch/ssp.h> +#include <asm/arch/pxa-regs.h> + +#define PXA_SSP_PORTS 3 + +static DECLARE_MUTEX(sem); +static int use_count[PXA_SSP_PORTS] = {0, 0, 0}; + +static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct ssp_dev *dev = (struct ssp_dev*) dev_id; + unsigned int status = SSSR_P(dev->port); + + SSSR_P(dev->port) = status; /* clear status bits */ + + if (status & SSSR_ROR) + printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port); + + if (status & SSSR_TUR) + printk(KERN_WARNING "SSP(%d): transmitter underrun\n", dev->port); + + if (status & SSSR_BCE) + printk(KERN_WARNING "SSP(%d): bit count error\n", dev->port); + + return IRQ_HANDLED; +} + +/** + * ssp_write_word - write a word to the SSP port + * @data: 32-bit, MSB justified data to write. + * + * Wait for a free entry in the SSP transmit FIFO, and write a data + * word to the SSP port. + * + * The caller is expected to perform the necessary locking. + * + * Returns: + * %-ETIMEDOUT timeout occurred (for future) + * 0 success + */ +int ssp_write_word(struct ssp_dev *dev, u32 data) +{ + while (!(SSSR_P(dev->port) & SSSR_TNF)) + cpu_relax(); + + SSDR_P(dev->port) = data; + + return 0; +} + +/** + * ssp_read_word - read a word from the SSP port + * + * Wait for a data word in the SSP receive FIFO, and return the + * received data. Data is LSB justified. + * + * Note: Currently, if data is not expected to be received, this + * function will wait for ever. + * + * The caller is expected to perform the necessary locking. + * + * Returns: + * %-ETIMEDOUT timeout occurred (for future) + * 32-bit data success + */ +int ssp_read_word(struct ssp_dev *dev) +{ + while (!(SSSR_P(dev->port) & SSSR_RNE)) + cpu_relax(); + + return SSDR_P(dev->port); +} + +/** + * ssp_flush - flush the transmit and receive FIFOs + * + * Wait for the SSP to idle, and ensure that the receive FIFO + * is empty. + * + * The caller is expected to perform the necessary locking. + */ +void ssp_flush(struct ssp_dev *dev) +{ + do { + while (SSSR_P(dev->port) & SSSR_RNE) { + (void) SSDR_P(dev->port); + } + } while (SSSR_P(dev->port) & SSSR_BSY); +} + +/** + * ssp_enable - enable the SSP port + * + * Turn on the SSP port. + */ +void ssp_enable(struct ssp_dev *dev) +{ + SSCR0_P(dev->port) |= SSCR0_SSE; +} + +/** + * ssp_disable - shut down the SSP port + * + * Turn off the SSP port, optionally powering it down. + */ +void ssp_disable(struct ssp_dev *dev) +{ + SSCR0_P(dev->port) &= ~SSCR0_SSE; +} + +/** + * ssp_save_state - save the SSP configuration + * @ssp: pointer to structure to save SSP configuration + * + * Save the configured SSP state for suspend. + */ +void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp) +{ + ssp->cr0 = SSCR0_P(dev->port); + ssp->cr1 = SSCR1_P(dev->port); + ssp->to = SSTO_P(dev->port); + ssp->psp = SSPSP_P(dev->port); + + SSCR0_P(dev->port) &= ~SSCR0_SSE; +} + +/** + * ssp_restore_state - restore a previously saved SSP configuration + * @ssp: pointer to configuration saved by ssp_save_state + * + * Restore the SSP configuration saved previously by ssp_save_state. + */ +void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp) +{ + SSSR_P(dev->port) = SSSR_ROR | SSSR_TUR | SSSR_BCE; + + SSCR0_P(dev->port) = ssp->cr0 & ~SSCR0_SSE; + SSCR1_P(dev->port) = ssp->cr1; + SSTO_P(dev->port) = ssp->to; + SSPSP_P(dev->port) = ssp->psp; + + SSCR0_P(dev->port) = ssp->cr0; +} + +/** + * ssp_config - configure SSP port settings + * @mode: port operating mode + * @flags: port config flags + * @psp_flags: port PSP config flags + * @speed: port speed + * + * Port MUST be disabled by ssp_disable before making any config changes. + */ +int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed) +{ + dev->mode = mode; + dev->flags = flags; + dev->psp_flags = psp_flags; + dev->speed = speed; + + /* set up port type, speed, port settings */ + SSCR0_P(dev->port) = (dev->speed | dev->mode); + SSCR1_P(dev->port) = dev->flags; + SSPSP_P(dev->port) = dev->psp_flags; + + return 0; +} + +/** + * ssp_init - setup the SSP port + * + * initialise and claim resources for the SSP port. + * + * Returns: + * %-ENODEV if the SSP port is unavailable + * %-EBUSY if the resources are already in use + * %0 on success + */ +int ssp_init(struct ssp_dev *dev, u32 port) +{ + int ret, irq; + + if (port > PXA_SSP_PORTS || port == 0) + return -ENODEV; + + down(&sem); + if (use_count[port - 1]) { + up(&sem); + return -EBUSY; + } + use_count[port - 1]++; + + if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) { + use_count[port - 1]--; + up(&sem); + return -EBUSY; + } + + switch (port) { + case 1: + irq = IRQ_SSP; + break; +#if defined (CONFIG_PXA27x) + case 2: + irq = IRQ_SSP2; + break; + case 3: + irq = IRQ_SSP3; + break; +#else + case 2: + irq = IRQ_NSSP; + break; + case 3: + irq = IRQ_ASSP; + break; +#endif + default: + return -ENODEV; + } + + dev->port = port; + + ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev); + if (ret) + goto out_region; + + /* turn on SSP port clock */ + switch (dev->port) { +#if defined (CONFIG_PXA27x) + case 1: + pxa_set_cken(CKEN23_SSP1, 1); + break; + case 2: + pxa_set_cken(CKEN3_SSP2, 1); + break; + case 3: + pxa_set_cken(CKEN4_SSP3, 1); + break; +#else + case 1: + pxa_set_cken(CKEN3_SSP, 1); + break; + case 2: + pxa_set_cken(CKEN9_NSSP, 1); + break; + case 3: + pxa_set_cken(CKEN10_ASSP, 1); + break; +#endif + } + + up(&sem); + return 0; + +out_region: + release_mem_region(__PREG(SSCR0_P(port)), 0x2c); + use_count[port - 1]--; + up(&sem); + return ret; +} + +/** + * ssp_exit - undo the effects of ssp_init + * + * release and free resources for the SSP port. + */ +void ssp_exit(struct ssp_dev *dev) +{ + int irq; + + down(&sem); + SSCR0_P(dev->port) &= ~SSCR0_SSE; + + /* find irq, save power and turn off SSP port clock */ + switch (dev->port) { +#if defined (CONFIG_PXA27x) + case 1: + irq = IRQ_SSP; + pxa_set_cken(CKEN23_SSP1, 0); + break; + case 2: + irq = IRQ_SSP2; + pxa_set_cken(CKEN3_SSP2, 0); + break; + case 3: + irq = IRQ_SSP3; + pxa_set_cken(CKEN4_SSP3, 0); + break; +#else + case 1: + irq = IRQ_SSP; + pxa_set_cken(CKEN3_SSP, 0); + break; + case 2: + irq = IRQ_NSSP; + pxa_set_cken(CKEN9_NSSP, 0); + break; + case 3: + irq = IRQ_ASSP; + pxa_set_cken(CKEN10_ASSP, 0); + break; +#endif + default: + printk(KERN_WARNING "SSP: tried to close invalid port\n"); + return; + } + + free_irq(irq, dev); + release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c); + use_count[dev->port - 1]--; + up(&sem); +} + +EXPORT_SYMBOL(ssp_write_word); +EXPORT_SYMBOL(ssp_read_word); +EXPORT_SYMBOL(ssp_flush); +EXPORT_SYMBOL(ssp_enable); +EXPORT_SYMBOL(ssp_disable); +EXPORT_SYMBOL(ssp_save_state); +EXPORT_SYMBOL(ssp_restore_state); +EXPORT_SYMBOL(ssp_init); +EXPORT_SYMBOL(ssp_exit); +EXPORT_SYMBOL(ssp_config); + +MODULE_DESCRIPTION("PXA SSP driver"); +MODULE_AUTHOR("Liam Girdwood"); +MODULE_LICENSE("GPL"); + diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c new file mode 100644 index 0000000..473fb61 --- /dev/null +++ b/arch/arm/mach-pxa/time.c @@ -0,0 +1,164 @@ +/* + * arch/arm/mach-pxa/time.c + * + * Author: Nicolas Pitre + * Created: Jun 15, 2001 + * Copyright: MontaVista Software Inc. + * + * 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/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/time.h> +#include <linux/signal.h> +#include <linux/errno.h> +#include <linux/sched.h> + +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include <asm/arch/pxa-regs.h> + + +static inline unsigned long pxa_get_rtc_time(void) +{ + return RCNR; +} + +static int pxa_set_rtc(void) +{ + unsigned long current_time = xtime.tv_sec; + + if (RTSR & RTSR_ALE) { + /* make sure not to forward the clock over an alarm */ + unsigned long alarm = RTAR; + if (current_time >= alarm && alarm >= RCNR) + return -ERESTARTSYS; + } + RCNR = current_time; + return 0; +} + +/* IRQs are disabled before entering here from do_gettimeofday() */ +static unsigned long pxa_gettimeoffset (void) +{ + long ticks_to_match, elapsed, usec; + + /* Get ticks before next timer match */ + ticks_to_match = OSMR0 - OSCR; + + /* We need elapsed ticks since last match */ + elapsed = LATCH - ticks_to_match; + + /* don't get fooled by the workaround in pxa_timer_interrupt() */ + if (elapsed <= 0) + return 0; + + /* Now convert them to usec */ + usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; + + return usec; +} + +static irqreturn_t +pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int next_match; + + write_seqlock(&xtime_lock); + + /* Loop until we get ahead of the free running timer. + * This ensures an exact clock tick count and time accuracy. + * IRQs are disabled inside the loop to ensure coherence between + * lost_ticks (updated in do_timer()) and the match reg value, so we + * can use do_gettimeofday() from interrupt handlers. + * + * HACK ALERT: it seems that the PXA timer regs aren't updated right + * away in all cases when a write occurs. We therefore compare with + * 8 instead of 0 in the while() condition below to avoid missing a + * match if OSCR has already reached the next OSMR value. + * Experience has shown that up to 6 ticks are needed to work around + * this problem, but let's use 8 to be conservative. Note that this + * affect things only when the timer IRQ has been delayed by nearly + * exactly one tick period which should be a pretty rare event. + */ + do { + timer_tick(regs); + OSSR = OSSR_M0; /* Clear match on timer 0 */ + next_match = (OSMR0 += LATCH); + } while( (signed long)(next_match - OSCR) <= 8 ); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction pxa_timer_irq = { + .name = "PXA Timer Tick", + .flags = SA_INTERRUPT, + .handler = pxa_timer_interrupt +}; + +static void __init pxa_timer_init(void) +{ + struct timespec tv; + + set_rtc = pxa_set_rtc; + + tv.tv_nsec = 0; + tv.tv_sec = pxa_get_rtc_time(); + do_settimeofday(&tv); + + OSMR0 = 0; /* set initial match at 0 */ + OSSR = 0xf; /* clear status on all timers */ + setup_irq(IRQ_OST0, &pxa_timer_irq); + OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ + OSCR = 0; /* initialize free-running timer, force first match */ +} + +#ifdef CONFIG_PM +static unsigned long osmr[4], oier; + +static void pxa_timer_suspend(void) +{ + osmr[0] = OSMR0; + osmr[1] = OSMR1; + osmr[2] = OSMR2; + osmr[3] = OSMR3; + oier = OIER; +} + +static void pxa_timer_resume(void) +{ + OSMR0 = osmr[0]; + OSMR1 = osmr[1]; + OSMR2 = osmr[2]; + OSMR3 = osmr[3]; + OIER = oier; + + /* + * OSMR0 is the system timer: make sure OSCR is sufficiently behind + */ + OSCR = OSMR0 - LATCH; +} +#else +#define pxa_timer_suspend NULL +#define pxa_timer_resume NULL +#endif + +struct sys_timer pxa_timer = { + .init = pxa_timer_init, + .suspend = pxa_timer_suspend, + .resume = pxa_timer_resume, + .offset = pxa_gettimeoffset, +}; diff --git a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile new file mode 100644 index 0000000..aa77bc9 --- /dev/null +++ b/arch/arm/mach-rpc/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := dma.o irq.o riscpc.o +obj-m := +obj-n := +obj- := + diff --git a/arch/arm/mach-rpc/Makefile.boot b/arch/arm/mach-rpc/Makefile.boot new file mode 100644 index 0000000..9c9e7685 --- /dev/null +++ b/arch/arm/mach-rpc/Makefile.boot @@ -0,0 +1,4 @@ + zreladdr-y := 0x10008000 +params_phys-y := 0x10000100 +initrd_phys-y := 0x18000000 + diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c new file mode 100644 index 0000000..bc07474 --- /dev/null +++ b/arch/arm/mach-rpc/dma.c @@ -0,0 +1,338 @@ +/* + * linux/arch/arm/mach-rpc/dma.c + * + * Copyright (C) 1998 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. + * + * DMA functions specific to RiscPC architecture + */ +#include <linux/slab.h> +#include <linux/mman.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/pci.h> + +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/fiq.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/uaccess.h> + +#include <asm/mach/dma.h> +#include <asm/hardware/iomd.h> + +#if 0 +typedef enum { + dma_size_8 = 1, + dma_size_16 = 2, + dma_size_32 = 4, + dma_size_128 = 16 +} dma_size_t; +#endif + +#define TRANSFER_SIZE 2 + +#define CURA (0) +#define ENDA (IOMD_IO0ENDA - IOMD_IO0CURA) +#define CURB (IOMD_IO0CURB - IOMD_IO0CURA) +#define ENDB (IOMD_IO0ENDB - IOMD_IO0CURA) +#define CR (IOMD_IO0CR - IOMD_IO0CURA) +#define ST (IOMD_IO0ST - IOMD_IO0CURA) + +static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma) +{ + unsigned long end, offset, flags = 0; + + if (dma->sg) { + sg->dma_address = dma->sg->dma_address; + offset = sg->dma_address & ~PAGE_MASK; + + end = offset + dma->sg->length; + + if (end > PAGE_SIZE) + end = PAGE_SIZE; + + if (offset + TRANSFER_SIZE >= end) + flags |= DMA_END_L; + + sg->length = end - TRANSFER_SIZE; + + dma->sg->length -= end - offset; + dma->sg->dma_address += end - offset; + + if (dma->sg->length == 0) { + if (dma->sgcount > 1) { + dma->sg++; + dma->sgcount--; + } else { + dma->sg = NULL; + flags |= DMA_END_S; + } + } + } else { + flags = DMA_END_S | DMA_END_L; + sg->dma_address = 0; + sg->length = 0; + } + + sg->length |= flags; +} + +static irqreturn_t iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) +{ + dma_t *dma = (dma_t *)dev_id; + unsigned long base = dma->dma_base; + + do { + unsigned int status; + + status = iomd_readb(base + ST); + if (!(status & DMA_ST_INT)) + return IRQ_HANDLED; + + if ((dma->state ^ status) & DMA_ST_AB) + iomd_get_next_sg(&dma->cur_sg, dma); + + switch (status & (DMA_ST_OFL | DMA_ST_AB)) { + case DMA_ST_OFL: /* OIA */ + case DMA_ST_AB: /* .IB */ + iomd_writel(dma->cur_sg.dma_address, base + CURA); + iomd_writel(dma->cur_sg.length, base + ENDA); + dma->state = DMA_ST_AB; + break; + + case DMA_ST_OFL | DMA_ST_AB: /* OIB */ + case 0: /* .IA */ + iomd_writel(dma->cur_sg.dma_address, base + CURB); + iomd_writel(dma->cur_sg.length, base + ENDB); + dma->state = 0; + break; + } + + if (status & DMA_ST_OFL && + dma->cur_sg.length == (DMA_END_S|DMA_END_L)) + break; + } while (1); + + dma->state = ~DMA_ST_AB; + disable_irq(irq); + + return IRQ_HANDLED; +} + +static int iomd_request_dma(dmach_t channel, dma_t *dma) +{ + return request_irq(dma->dma_irq, iomd_dma_handle, + SA_INTERRUPT, dma->device_id, dma); +} + +static void iomd_free_dma(dmach_t channel, dma_t *dma) +{ + free_irq(dma->dma_irq, dma); +} + +static void iomd_enable_dma(dmach_t channel, dma_t *dma) +{ + unsigned long dma_base = dma->dma_base; + unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E; + + if (dma->invalid) { + dma->invalid = 0; + + /* + * Cope with ISA-style drivers which expect cache + * coherence. + */ + if (!dma->using_sg) { + dma->buf.dma_address = pci_map_single(NULL, + dma->buf.__address, dma->buf.length, + dma->dma_mode == DMA_MODE_READ ? + PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + } + + iomd_writeb(DMA_CR_C, dma_base + CR); + dma->state = DMA_ST_AB; + } + + if (dma->dma_mode == DMA_MODE_READ) + ctrl |= DMA_CR_D; + + iomd_writeb(ctrl, dma_base + CR); + enable_irq(dma->dma_irq); +} + +static void iomd_disable_dma(dmach_t channel, dma_t *dma) +{ + unsigned long dma_base = dma->dma_base; + unsigned long flags; + + local_irq_save(flags); + if (dma->state != ~DMA_ST_AB) + disable_irq(dma->dma_irq); + iomd_writeb(0, dma_base + CR); + local_irq_restore(flags); +} + +static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle) +{ + int tcr, speed; + + if (cycle < 188) + speed = 3; + else if (cycle <= 250) + speed = 2; + else if (cycle < 438) + speed = 1; + else + speed = 0; + + tcr = iomd_readb(IOMD_DMATCR); + speed &= 3; + + switch (channel) { + case DMA_0: + tcr = (tcr & ~0x03) | speed; + break; + + case DMA_1: + tcr = (tcr & ~0x0c) | (speed << 2); + break; + + case DMA_2: + tcr = (tcr & ~0x30) | (speed << 4); + break; + + case DMA_3: + tcr = (tcr & ~0xc0) | (speed << 6); + break; + + default: + break; + } + + iomd_writeb(tcr, IOMD_DMATCR); + + 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->using_sg) + BUG(); + + 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 = (unsigned long)dma->buf.__address; + regs.ARM_fp = (unsigned long)FLOPPYDMA_BASE; + + if (claim_fiq(&fh)) { + printk("floppydma: couldn't claim FIQ.\n"); + return; + } + + set_fiq_handler(fiqhandler_start, fiqhandler_length); + set_fiq_regs(®s); + enable_fiq(dma->dma_irq); +} + +static void floppy_disable_dma(dmach_t channel, dma_t *dma) +{ + disable_fiq(dma->dma_irq); + release_fiq(&fh); +} + +static int floppy_get_residue(dmach_t channel, dma_t *dma) +{ + struct pt_regs regs; + get_fiq_regs(®s); + 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 void 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) +{ + iomd_writeb(0, IOMD_IO0CR); + iomd_writeb(0, IOMD_IO1CR); + iomd_writeb(0, IOMD_IO2CR); + iomd_writeb(0, IOMD_IO3CR); + + iomd_writeb(0xa0, IOMD_DMATCR); + + dma[DMA_0].dma_base = IOMD_IO0CURA; + dma[DMA_0].dma_irq = IRQ_DMA0; + dma[DMA_0].d_ops = &iomd_dma_ops; + dma[DMA_1].dma_base = IOMD_IO1CURA; + dma[DMA_1].dma_irq = IRQ_DMA1; + dma[DMA_1].d_ops = &iomd_dma_ops; + dma[DMA_2].dma_base = IOMD_IO2CURA; + dma[DMA_2].dma_irq = IRQ_DMA2; + dma[DMA_2].d_ops = &iomd_dma_ops; + dma[DMA_3].dma_base = IOMD_IO3CURA; + dma[DMA_3].dma_irq = IRQ_DMA3; + dma[DMA_3].d_ops = &iomd_dma_ops; + dma[DMA_S0].dma_base = IOMD_SD0CURA; + dma[DMA_S0].dma_irq = IRQ_DMAS0; + dma[DMA_S0].d_ops = &iomd_dma_ops; + dma[DMA_S1].dma_base = IOMD_SD1CURA; + dma[DMA_S1].dma_irq = IRQ_DMAS1; + dma[DMA_S1].d_ops = &iomd_dma_ops; + dma[DMA_VIRTUAL_FLOPPY].dma_irq = FIQ_FLOPPYDATA; + 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 + */ + iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT); +} diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c new file mode 100644 index 0000000..56b2716 --- /dev/null +++ b/arch/arm/mach-rpc/irq.c @@ -0,0 +1,162 @@ +#include <linux/init.h> +#include <linux/list.h> + +#include <asm/mach/irq.h> +#include <asm/hardware/iomd.h> +#include <asm/irq.h> +#include <asm/io.h> + +static void iomd_ack_irq_a(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << irq; + val = iomd_readb(IOMD_IRQMASKA); + iomd_writeb(val & ~mask, IOMD_IRQMASKA); + iomd_writeb(mask, IOMD_IRQCLRA); +} + +static void iomd_mask_irq_a(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << irq; + val = iomd_readb(IOMD_IRQMASKA); + iomd_writeb(val & ~mask, IOMD_IRQMASKA); +} + +static void iomd_unmask_irq_a(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << irq; + val = iomd_readb(IOMD_IRQMASKA); + iomd_writeb(val | mask, IOMD_IRQMASKA); +} + +static struct irqchip iomd_a_chip = { + .ack = iomd_ack_irq_a, + .mask = iomd_mask_irq_a, + .unmask = iomd_unmask_irq_a, +}; + +static void iomd_mask_irq_b(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_IRQMASKB); + iomd_writeb(val & ~mask, IOMD_IRQMASKB); +} + +static void iomd_unmask_irq_b(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_IRQMASKB); + iomd_writeb(val | mask, IOMD_IRQMASKB); +} + +static struct irqchip iomd_b_chip = { + .ack = iomd_mask_irq_b, + .mask = iomd_mask_irq_b, + .unmask = iomd_unmask_irq_b, +}; + +static void iomd_mask_irq_dma(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_DMAMASK); + iomd_writeb(val & ~mask, IOMD_DMAMASK); +} + +static void iomd_unmask_irq_dma(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_DMAMASK); + iomd_writeb(val | mask, IOMD_DMAMASK); +} + +static struct irqchip iomd_dma_chip = { + .ack = iomd_mask_irq_dma, + .mask = iomd_mask_irq_dma, + .unmask = iomd_unmask_irq_dma, +}; + +static void iomd_mask_irq_fiq(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_FIQMASK); + iomd_writeb(val & ~mask, IOMD_FIQMASK); +} + +static void iomd_unmask_irq_fiq(unsigned int irq) +{ + unsigned int val, mask; + + mask = 1 << (irq & 7); + val = iomd_readb(IOMD_FIQMASK); + iomd_writeb(val | mask, IOMD_FIQMASK); +} + +static struct irqchip iomd_fiq_chip = { + .ack = iomd_mask_irq_fiq, + .mask = iomd_mask_irq_fiq, + .unmask = iomd_unmask_irq_fiq, +}; + +void __init rpc_init_irq(void) +{ + unsigned int irq, flags; + + iomd_writeb(0, IOMD_IRQMASKA); + iomd_writeb(0, IOMD_IRQMASKB); + iomd_writeb(0, IOMD_FIQMASK); + iomd_writeb(0, IOMD_DMAMASK); + + for (irq = 0; irq < NR_IRQS; irq++) { + flags = IRQF_VALID; + + if (irq <= 6 || (irq >= 9 && irq <= 15)) + flags |= IRQF_PROBE; + + if (irq == 21 || (irq >= 16 && irq <= 19) || + irq == IRQ_KEYBOARDTX) + flags |= IRQF_NOAUTOEN; + + switch (irq) { + case 0 ... 7: + set_irq_chip(irq, &iomd_a_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 8 ... 15: + set_irq_chip(irq, &iomd_b_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 16 ... 21: + set_irq_chip(irq, &iomd_dma_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, flags); + break; + + case 64 ... 71: + set_irq_chip(irq, &iomd_fiq_chip); + set_irq_flags(irq, IRQF_VALID); + break; + } + } + + init_FIQ(); +} + diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c new file mode 100644 index 0000000..815c532 --- /dev/null +++ b/arch/arm/mach-rpc/riscpc.c @@ -0,0 +1,179 @@ +/* + * linux/arch/arm/mach-rpc/riscpc.c + * + * Copyright (C) 1998-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. + * + * Architecture specific fixups. + */ +#include <linux/kernel.h> +#include <linux/tty.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/device.h> +#include <linux/serial_8250.h> + +#include <asm/elf.h> +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include <asm/domain.h> +#include <asm/setup.h> + +#include <asm/mach/map.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +extern void rpc_init_irq(void); + +extern unsigned int vram_size; + +#if 0 + +unsigned int memc_ctrl_reg; +unsigned int number_mfm_drives; + +static int __init parse_tag_acorn(const struct tag *tag) +{ + memc_ctrl_reg = tag->u.acorn.memc_control_reg; + number_mfm_drives = tag->u.acorn.adfsdrives; + + switch (tag->u.acorn.vram_pages) { + case 512: + vram_size += PAGE_SIZE * 256; + case 256: + vram_size += PAGE_SIZE * 256; + default: + break; + } +#if 0 + if (vram_size) { + desc->video_start = 0x02000000; + desc->video_end = 0x02000000 + vram_size; + } +#endif + return 0; +} + +__tagtable(ATAG_ACORN, parse_tag_acorn); + +#endif + +static struct map_desc rpc_io_desc[] __initdata = { + { SCREEN_BASE, SCREEN_START, 2*1048576, MT_DEVICE }, /* VRAM */ + { (u32)IO_BASE, IO_START, IO_SIZE , MT_DEVICE }, /* IO space */ + { EASI_BASE, EASI_START, EASI_SIZE, MT_DEVICE } /* EASI space */ +}; + +static void __init rpc_map_io(void) +{ + iotable_init(rpc_io_desc, ARRAY_SIZE(rpc_io_desc)); + + /* + * Turn off floppy. + */ + outb(0xc, 0x3f2); + + /* + * RiscPC can't handle half-word loads and stores + */ + elf_hwcap &= ~HWCAP_HALF; +} + +static struct resource acornfb_resources[] = { + { /* VIDC */ + .start = 0x03400000, + .end = 0x035fffff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_VSYNCPULSE, + .end = IRQ_VSYNCPULSE, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device acornfb_device = { + .name = "acornfb", + .id = -1, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(acornfb_resources), + .resource = acornfb_resources, +}; + +static struct resource iomd_resources[] = { + { + .start = 0x03200000, + .end = 0x0320ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device iomd_device = { + .name = "iomd", + .id = -1, + .num_resources = ARRAY_SIZE(iomd_resources), + .resource = iomd_resources, +}; + +static struct platform_device kbd_device = { + .name = "kart", + .id = -1, + .dev = { + .parent = &iomd_device.dev, + }, +}; + +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = 0x03010fe0, + .irq = 10, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static struct platform_device *devs[] __initdata = { + &iomd_device, + &kbd_device, + &serial_device, + &acornfb_device, +}; + +static int __init rpc_init(void) +{ + return platform_add_devices(devs, ARRAY_SIZE(devs)); +} + +arch_initcall(rpc_init); + +extern struct sys_timer ioc_timer; + +MACHINE_START(RISCPC, "Acorn-RiscPC") + MAINTAINER("Russell King") + BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) + BOOT_PARAMS(0x10000100) + DISABLE_PARPORT(0) + DISABLE_PARPORT(1) + MAPIO(rpc_map_io) + INITIRQ(rpc_init_irq) + .timer = &ioc_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig new file mode 100644 index 0000000..534df0c --- /dev/null +++ b/arch/arm/mach-s3c2410/Kconfig @@ -0,0 +1,169 @@ +if ARCH_S3C2410 + +menu "S3C24XX Implementations" + +config ARCH_BAST + bool "Simtec Electronics BAST (EB2410ITX)" + select CPU_S3C2410 + help + Say Y here if you are using the Simtec Electronics EB2410ITX + development board (also known as BAST) + + Product page: <http://www.simtec.co.uk/products/EB2410ITX/>. + +config ARCH_H1940 + bool "IPAQ H1940" + select CPU_S3C2410 + help + Say Y here if you are using the HP IPAQ H1940 + + <http://www.handhelds.org/projects/h1940.html>. + +config MACH_N30 + bool "Acer N30" + select CPU_S3C2410 + help + Say Y here if you are using the Acer N30 + + <http://zoo.weinigel.se/n30>. + +config ARCH_SMDK2410 + bool "SMDK2410/A9M2410" + select CPU_S3C2410 + help + Say Y here if you are using the SMDK2410 or the derived module A9M2410 + <http://www.fsforth.de> + +config ARCH_S3C2440 + bool "SMDK2440" + select CPU_S3C2440 + help + Say Y here if you are using the SMDK2440. + +config MACH_VR1000 + bool "Thorcom VR1000" + select CPU_S3C2410 + help + Say Y here if you are using the Thorcom VR1000 board. + + This linux port is currently being maintained by Simtec, on behalf + of Thorcom. Any queries, please contact Thorcom first. + +config MACH_RX3715 + bool "HP iPAQ rx3715" + select CPU_S3C2440 + help + Say Y here if you are using the HP iPAQ rx3715. + + See <http://www.handhelds.org/projects/rx3715.html> for more + information on this project + +config MACH_OTOM + bool "NexVision OTOM Board" + select CPU_S3C2410 + help + Say Y here if you are using the Nex Vision OTOM board + +config MACH_NEXCODER_2440 + bool "NexVision NEXCODER 2440 Light Board" + select CPU_S3C2440 + help + Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board + +endmenu + +config CPU_S3C2410 + bool + depends on ARCH_S3C2410 + help + Support for S3C2410 and S3C2410A family from the S3C24XX line + of Samsung Mobile CPUs. + +config CPU_S3C2440 + bool + depends on ARCH_S3C2410 + help + Support for S3C2440 Samsung Mobile CPU based systems. + +comment "S3C2410 Boot" + +config S3C2410_BOOT_WATCHDOG + bool "S3C2410 Initialisation watchdog" + depends on ARCH_S3C2410 && S3C2410_WATCHDOG + help + Say y to enable the watchdog during the kernel decompression + stage. If the kernel fails to uncompress, then the watchdog + will trigger a reset and the system should restart. + + Although this uses the same hardware unit as the kernel watchdog + driver, it is not a replacement for it. If you use this option, + you will have to use the watchdg driver to either stop the timeout + or restart it. If you do not, then your kernel will reboot after + startup. + + The driver uses a fixed timeout value, so the exact time till the + system resets depends on the value of PCLK. The timeout on an + 200MHz s3c2410 should be about 30 seconds. + +comment "S3C2410 Setup" + +config S3C2410_DMA + bool "S3C2410 DMA support" + depends on ARCH_S3C2410 + help + S3C2410 DMA support. This is needed for drivers like sound which + use the S3C2410's DMA system to move data to and from the + peripheral blocks. + +config S3C2410_DMA_DEBUG + bool "S3C2410 DMA support debug" + depends on ARCH_S3C2410 && S3C2410_DMA + help + Enable debugging output for the DMA code. This option sends info + to the kernel log, at priority KERN_DEBUG. + + Note, it is easy to create and fill the log buffer in a small + amount of time, as well as using an significant percentage of + the CPU time doing so. + + +config S3C2410_PM_DEBUG + bool "S3C2410 PM Suspend debug" + depends on ARCH_S3C2410 && PM + help + Say Y here if you want verbose debugging from the PM Suspend and + Resume code. See `Documentation/arm/Samsing-S3C24XX/Suspend.txt` + for more information. + +config S3C2410_PM_CHECK + bool "S3C2410 PM Suspend Memory CRC" + depends on ARCH_S3C2410 && PM && CRC32 + help + Enable the PM code's memory area checksum over sleep. This option + will generate CRCs of all blocks of memory, and store them before + going to sleep. The blocks are then checked on resume for any + errors. + +config S3C2410_PM_CHECK_CHUNKSIZE + int "S3C2410 PM Suspend CRC Chunksize (KiB)" + depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK + default 64 + help + Set the chunksize in Kilobytes of the CRC for checking memory + corruption over suspend and resume. A smaller value will mean that + the CRC data block will take more memory, but wil identify any + faults with better precision. + +config S3C2410_LOWLEVEL_UART_PORT + int "S3C2410 UART to use for low-level messages" + default 0 + help + Choice of which UART port to use for the low-level messages, + such as the `Uncompressing...` at start time. The value of + this configuration should be between zero and two. The port + must have been initialised by the boot-loader before use. + + Note, this does not affect the port used by the debug messages, + which is a separate configuration. + +endif diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile new file mode 100644 index 0000000..7c379aa --- /dev/null +++ b/arch/arm/mach-s3c2410/Makefile @@ -0,0 +1,36 @@ + +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := cpu.o irq.o time.o gpio.o clock.o devs.o +obj-m := +obj-n := +obj- := + +# S3C2410 support files + +obj-$(CONFIG_CPU_S3C2410) += s3c2410.o +obj-$(CONFIG_S3C2410_DMA) += dma.o + +# Power Management support + +obj-$(CONFIG_PM) += pm.o sleep.o + +# S3C2440 support + +obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o + +# machine specific support + +obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o +obj-$(CONFIG_ARCH_H1940) += mach-h1940.o +obj-$(CONFIG_MACH_N30) += mach-n30.o +obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o +obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o +obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o +obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o +obj-$(CONFIG_MACH_OTOM) += mach-otom.o +obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o diff --git a/arch/arm/mach-s3c2410/Makefile.boot b/arch/arm/mach-s3c2410/Makefile.boot new file mode 100644 index 0000000..7dab2a0 --- /dev/null +++ b/arch/arm/mach-s3c2410/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x30008000 +params_phys-y := 0x30000100 + diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c new file mode 100644 index 0000000..5e5bbe8 --- /dev/null +++ b/arch/arm/mach-s3c2410/bast-irq.c @@ -0,0 +1,132 @@ +/* linux/arch/arm/mach-s3c2410/bast-irq.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * 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 + * + * Modifications: + * 08-Jan-2003 BJD Moved from central IRQ code + */ + + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/ptrace.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/irq.h> +#include <asm/hardware/s3c2410/irq.h> + +#if 0 +#include <asm/debug-ll.h> +#endif + +#define irqdbf(x...) +#define irqdbf2(x...) + + +/* handle PC104 ISA interrupts from the system CPLD */ + +/* table of ISA irq nos to the relevant mask... zero means + * the irq is not implemented +*/ +static unsigned char bast_pc104_irqmasks[] = { + 0, /* 0 */ + 0, /* 1 */ + 0, /* 2 */ + 1, /* 3 */ + 0, /* 4 */ + 2, /* 5 */ + 0, /* 6 */ + 4, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 8, /* 10 */ + 0, /* 11 */ + 0, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + 0, /* 15 */ +}; + +static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 }; + +static void +bast_pc104_mask(unsigned int irqno) +{ + unsigned long temp; + + temp = __raw_readb(BAST_VA_PC104_IRQMASK); + temp &= ~bast_pc104_irqmasks[irqno]; + __raw_writeb(temp, BAST_VA_PC104_IRQMASK); + + if (temp == 0) + bast_extint_mask(IRQ_ISA); +} + +static void +bast_pc104_ack(unsigned int irqno) +{ + bast_extint_ack(IRQ_ISA); +} + +static void +bast_pc104_unmask(unsigned int irqno) +{ + unsigned long temp; + + temp = __raw_readb(BAST_VA_PC104_IRQMASK); + temp |= bast_pc104_irqmasks[irqno]; + __raw_writeb(temp, BAST_VA_PC104_IRQMASK); + + bast_extint_unmask(IRQ_ISA); +} + +static struct bast_pc104_chip = { + .mask = bast_pc104_mask, + .unmask = bast_pc104_unmask, + .ack = bast_pc104_ack +}; + +static void +bast_irq_pc104_demux(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int stat; + unsigned int irqno; + int i; + + stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf; + + for (i = 0; i < 4 && stat != 0; i++) { + if (stat & 1) { + irqno = bast_pc104_irqs[i]; + desc = irq_desc + irqno; + + desc->handle(irqno, desc, regs); + } + + stat >>= 1; + } +} diff --git a/arch/arm/mach-s3c2410/bast.h b/arch/arm/mach-s3c2410/bast.h new file mode 100644 index 0000000..e5d0331 --- /dev/null +++ b/arch/arm/mach-s3c2410/bast.h @@ -0,0 +1,2 @@ + +extern void bast_init_irq(void); diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c new file mode 100644 index 0000000..e23f534 --- /dev/null +++ b/arch/arm/mach-s3c2410/clock.c @@ -0,0 +1,507 @@ +/* linux/arch/arm/mach-s3c2410/clock.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 Clock control support + * + * Based on, and code from linux/arch/arm/mach-versatile/clock.c + ** + ** Copyright (C) 2004 ARM Limited. + ** Written by Deep Blue Solutions 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 <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/device.h> +#include <linux/sysdev.h> + +#include <linux/interrupt.h> +#include <linux/ioport.h> + +#include <asm/hardware.h> +#include <asm/atomic.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/hardware/clock.h> +#include <asm/arch/regs-clock.h> + +#include "clock.h" +#include "cpu.h" + +/* clock information */ + +static LIST_HEAD(clocks); +static DECLARE_MUTEX(clocks_sem); + +/* old functions */ + +void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable) +{ + unsigned long clkcon; + unsigned long flags; + + local_irq_save(flags); + + clkcon = __raw_readl(S3C2410_CLKCON); + clkcon &= ~clocks; + + if (enable) + clkcon |= clocks; + + /* ensure none of the special function bits set */ + clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); + + __raw_writel(clkcon, S3C2410_CLKCON); + + local_irq_restore(flags); +} + +/* enable and disable calls for use with the clk struct */ + +static int clk_null_enable(struct clk *clk, int enable) +{ + return 0; +} + +int s3c24xx_clkcon_enable(struct clk *clk, int enable) +{ + s3c24xx_clk_enable(clk->ctrlbit, enable); + return 0; +} + +/* Clock API calls */ + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p; + struct clk *clk = ERR_PTR(-ENOENT); + int idno; + + idno = (dev == NULL) ? -1 : to_platform_device(dev)->id; + + down(&clocks_sem); + + list_for_each_entry(p, &clocks, list) { + if (p->id == idno && + strcmp(id, p->name) == 0 && + try_module_get(p->owner)) { + clk = p; + break; + } + } + + /* check for the case where a device was supplied, but the + * clock that was being searched for is not device specific */ + + if (IS_ERR(clk)) { + list_for_each_entry(p, &clocks, list) { + if (p->id == -1 && strcmp(id, p->name) == 0 && + try_module_get(p->owner)) { + clk = p; + break; + } + } + } + + up(&clocks_sem); + return clk; +} + +void clk_put(struct clk *clk) +{ + module_put(clk->owner); +} + +int clk_enable(struct clk *clk) +{ + if (IS_ERR(clk)) + return -EINVAL; + + return (clk->enable)(clk, 1); +} + +void clk_disable(struct clk *clk) +{ + if (!IS_ERR(clk)) + (clk->enable)(clk, 0); +} + + +int clk_use(struct clk *clk) +{ + atomic_inc(&clk->used); + return 0; +} + + +void clk_unuse(struct clk *clk) +{ + atomic_dec(&clk->used); +} + +unsigned long clk_get_rate(struct clk *clk) +{ + if (IS_ERR(clk)) + return 0; + + if (clk->rate != 0) + return clk->rate; + + while (clk->parent != NULL && clk->rate == 0) + clk = clk->parent; + + return clk->rate; +} + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return rate; +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return -EINVAL; +} + +struct clk *clk_get_parent(struct clk *clk) +{ + return clk->parent; +} + +EXPORT_SYMBOL(clk_get); +EXPORT_SYMBOL(clk_put); +EXPORT_SYMBOL(clk_enable); +EXPORT_SYMBOL(clk_disable); +EXPORT_SYMBOL(clk_use); +EXPORT_SYMBOL(clk_unuse); +EXPORT_SYMBOL(clk_get_rate); +EXPORT_SYMBOL(clk_round_rate); +EXPORT_SYMBOL(clk_set_rate); +EXPORT_SYMBOL(clk_get_parent); + +/* base clocks */ + +static struct clk clk_xtal = { + .name = "xtal", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, +}; + +static struct clk clk_f = { + .name = "fclk", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, +}; + +static struct clk clk_h = { + .name = "hclk", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, +}; + +static struct clk clk_p = { + .name = "pclk", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, +}; + +/* clocks that could be registered by external code */ + +struct clk s3c24xx_dclk0 = { + .name = "dclk0", + .id = -1, +}; + +struct clk s3c24xx_dclk1 = { + .name = "dclk1", + .id = -1, +}; + +struct clk s3c24xx_clkout0 = { + .name = "clkout0", + .id = -1, +}; + +struct clk s3c24xx_clkout1 = { + .name = "clkout1", + .id = -1, +}; + +struct clk s3c24xx_uclk = { + .name = "uclk", + .id = -1, +}; + + +/* clock definitions */ + +static struct clk init_clocks[] = { + { .name = "nand", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_NAND + }, + { .name = "lcd", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_LCDC + }, + { .name = "usb-host", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_USBH + }, + { .name = "usb-device", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_USBD + }, + { .name = "timers", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_PWMT + }, + { .name = "sdi", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_SDI + }, + { .name = "uart", + .id = 0, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART0 + }, + { .name = "uart", + .id = 1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART1 + }, + { .name = "uart", + .id = 2, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART2 + }, + { .name = "gpio", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_GPIO + }, + { .name = "rtc", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_RTC + }, + { .name = "adc", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_ADC + }, + { .name = "i2c", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_IIC + }, + { .name = "iis", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_IIS + }, + { .name = "spi", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_SPI + }, + { .name = "watchdog", + .id = -1, + .parent = &clk_p, + .ctrlbit = 0 + } +}; + +/* initialise the clock system */ + +int s3c24xx_register_clock(struct clk *clk) +{ + clk->owner = THIS_MODULE; + atomic_set(&clk->used, 0); + + if (clk->enable == NULL) + clk->enable = clk_null_enable; + + /* add to the list of available clocks */ + + down(&clocks_sem); + list_add(&clk->list, &clocks); + up(&clocks_sem); + + return 0; +} + +/* initalise all the clocks */ + +int __init s3c24xx_setup_clocks(unsigned long xtal, + unsigned long fclk, + unsigned long hclk, + unsigned long pclk) +{ + struct clk *clkp = init_clocks; + int ptr; + int ret; + + printk(KERN_INFO "S3C2410 Clocks, (c) 2004 Simtec Electronics\n"); + + /* initialise the main system clocks */ + + clk_xtal.rate = xtal; + + clk_h.rate = hclk; + clk_p.rate = pclk; + clk_f.rate = fclk; + + /* it looks like just setting the register here is not good + * enough, and causes the odd hang at initial boot time, so + * do all of them indivdually. + * + * I think disabling the LCD clock if the LCD is active is + * very dangerous, and therefore the bootloader should be + * careful to not enable the LCD clock if it is not needed. + * + * and of course, this looks neater + */ + + s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0); + + /* assume uart clocks are correctly setup */ + + /* register our clocks */ + + if (s3c24xx_register_clock(&clk_xtal) < 0) + printk(KERN_ERR "failed to register master xtal\n"); + + if (s3c24xx_register_clock(&clk_f) < 0) + printk(KERN_ERR "failed to register cpu fclk\n"); + + if (s3c24xx_register_clock(&clk_h) < 0) + printk(KERN_ERR "failed to register cpu hclk\n"); + + if (s3c24xx_register_clock(&clk_p) < 0) + printk(KERN_ERR "failed to register cpu pclk\n"); + + /* register clocks from clock array */ + + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + } + + return 0; +} + +/* S3C2440 extended clock support */ + +#ifdef CONFIG_CPU_S3C2440 + +static struct clk s3c2440_clk_upll = { + .name = "upll", + .id = -1, +}; + +static struct clk s3c2440_clk_cam = { + .name = "camif", + .parent = &clk_h, + .id = -1, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2440_CLKCON_CAMERA, +}; + +static struct clk s3c2440_clk_ac97 = { + .name = "ac97", + .parent = &clk_p, + .id = -1, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2440_CLKCON_CAMERA, +}; + +static int s3c2440_clk_add(struct sys_device *sysdev) +{ + unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); + + s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2; + + printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", + print_mhz(s3c2440_clk_upll.rate)); + + s3c24xx_register_clock(&s3c2440_clk_ac97); + s3c24xx_register_clock(&s3c2440_clk_cam); + s3c24xx_register_clock(&s3c2440_clk_upll); + + clk_disable(&s3c2440_clk_ac97); + clk_disable(&s3c2440_clk_cam); + + return 0; +} + +static struct sysdev_driver s3c2440_clk_driver = { + .add = s3c2440_clk_add, +}; + +static int s3c24xx_clk_driver(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver); +} + +arch_initcall(s3c24xx_clk_driver); + +#endif /* CONFIG_CPU_S3C2440 */ diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h new file mode 100644 index 0000000..7953b6f --- /dev/null +++ b/arch/arm/mach-s3c2410/clock.h @@ -0,0 +1,44 @@ +/* + * linux/arch/arm/mach-s3c2410/clock.h + * + * Copyright (c) 2004-2005 Simtec Electronics + * http://www.simtec.co.uk/products/SWLINUX/ + * Written by Ben Dooks, <ben@simtec.co.uk> + * + * 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. +*/ + +struct clk { + struct list_head list; + struct module *owner; + struct clk *parent; + const char *name; + int id; + atomic_t used; + unsigned long rate; + unsigned long ctrlbit; + int (*enable)(struct clk *, int enable); +}; + +/* other clocks which may be registered by board support */ + +extern struct clk s3c24xx_dclk0; +extern struct clk s3c24xx_dclk1; +extern struct clk s3c24xx_clkout0; +extern struct clk s3c24xx_clkout1; +extern struct clk s3c24xx_uclk; + +/* exports for arch/arm/mach-s3c2410 + * + * Please DO NOT use these outside of arch/arm/mach-s3c2410 +*/ + +extern int s3c24xx_clkcon_enable(struct clk *clk, int enable); +extern int s3c24xx_register_clock(struct clk *clk); + +extern int s3c24xx_setup_clocks(unsigned long xtal, + unsigned long fclk, + unsigned long hclk, + unsigned long pclk); diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c new file mode 100644 index 0000000..ca366e9 --- /dev/null +++ b/arch/arm/mach-s3c2410/cpu.c @@ -0,0 +1,241 @@ +/* linux/arch/arm/mach-s3c2410/cpu.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * http://www.simtec.co.uk/products/SWLINUX/ + * Ben Dooks <ben@simtec.co.uk> + * + * S3C24XX CPU Support + * + * 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 <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/device.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/delay.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <asm/arch/regs-gpio.h> + +#include "cpu.h" +#include "clock.h" +#include "s3c2410.h" +#include "s3c2440.h" + +struct cpu_table { + unsigned long idcode; + unsigned long idmask; + void (*map_io)(struct map_desc *mach_desc, int size); + void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no); + void (*init_clocks)(int xtal); + int (*init)(void); + const char *name; +}; + +/* table of supported CPUs */ + +static const char name_s3c2410[] = "S3C2410"; +static const char name_s3c2440[] = "S3C2440"; +static const char name_s3c2410a[] = "S3C2410A"; +static const char name_s3c2440a[] = "S3C2440A"; + +static struct cpu_table cpu_ids[] __initdata = { + { + .idcode = 0x32410000, + .idmask = 0xffffffff, + .map_io = s3c2410_map_io, + .init_clocks = s3c2410_init_clocks, + .init_uarts = s3c2410_init_uarts, + .init = s3c2410_init, + .name = name_s3c2410 + }, + { + .idcode = 0x32410002, + .idmask = 0xffffffff, + .map_io = s3c2410_map_io, + .init_clocks = s3c2410_init_clocks, + .init_uarts = s3c2410_init_uarts, + .init = s3c2410_init, + .name = name_s3c2410a + }, + { + .idcode = 0x32440000, + .idmask = 0xffffffff, + .map_io = s3c2440_map_io, + .init_clocks = s3c2440_init_clocks, + .init_uarts = s3c2440_init_uarts, + .init = s3c2440_init, + .name = name_s3c2440 + }, + { + .idcode = 0x32440001, + .idmask = 0xffffffff, + .map_io = s3c2440_map_io, + .init_clocks = s3c2440_init_clocks, + .init_uarts = s3c2440_init_uarts, + .init = s3c2440_init, + .name = name_s3c2440a + } +}; + +/* minimal IO mapping */ + +static struct map_desc s3c_iodesc[] __initdata = { + IODESC_ENT(GPIO), + IODESC_ENT(IRQ), + IODESC_ENT(MEMCTRL), + IODESC_ENT(UART) +}; + + +static struct cpu_table * +s3c_lookup_cpu(unsigned long idcode) +{ + struct cpu_table *tab; + int count; + + tab = cpu_ids; + for (count = 0; count < ARRAY_SIZE(cpu_ids); count++, tab++) { + if ((idcode & tab->idmask) == tab->idcode) + return tab; + } + + return NULL; +} + +/* board information */ + +static struct s3c24xx_board *board; + +void s3c24xx_set_board(struct s3c24xx_board *b) +{ + int i; + + board = b; + + if (b->clocks_count != 0) { + struct clk **ptr = b->clocks;; + + for (i = b->clocks_count; i > 0; i--, ptr++) + s3c24xx_register_clock(*ptr); + } +} + +/* cpu information */ + +static struct cpu_table *cpu; + +void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) +{ + unsigned long idcode; + + /* initialise the io descriptors we need for initialisation */ + iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); + + idcode = __raw_readl(S3C2410_GSTATUS1); + cpu = s3c_lookup_cpu(idcode); + + if (cpu == NULL) { + printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode); + panic("Unknown S3C24XX CPU"); + } + + if (cpu->map_io == NULL || cpu->init == NULL) { + printk(KERN_ERR "CPU %s support not enabled\n", cpu->name); + panic("Unsupported S3C24XX CPU"); + } + + printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode); + + (cpu->map_io)(mach_desc, size); +} + +/* s3c24xx_init_clocks + * + * Initialise the clock subsystem and associated information from the + * given master crystal value. + * + * xtal = 0 -> use default PLL crystal value (normally 12MHz) + * != 0 -> PLL crystal value in Hz +*/ + +void __init s3c24xx_init_clocks(int xtal) +{ + if (xtal == 0) + xtal = 12*1000*1000; + + if (cpu == NULL) + panic("s3c24xx_init_clocks: no cpu setup?\n"); + + if (cpu->init_clocks == NULL) + panic("s3c24xx_init_clocks: cpu has no clock init\n"); + else + (cpu->init_clocks)(xtal); +} + +void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + if (cpu == NULL) + return; + + if (cpu->init_uarts == NULL) { + printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n"); + } else + (cpu->init_uarts)(cfg, no); +} + +static int __init s3c_arch_init(void) +{ + int ret; + + // do the correct init for cpu + + if (cpu == NULL) + panic("s3c_arch_init: NULL cpu\n"); + + ret = (cpu->init)(); + if (ret != 0) + return ret; + + if (board != NULL) { + struct platform_device **ptr = board->devices; + int i; + + for (i = 0; i < board->devices_count; i++, ptr++) { + ret = platform_device_register(*ptr); + + if (ret) { + printk(KERN_ERR "s3c24xx: failed to add board device %s (%d) @%p\n", (*ptr)->name, ret, *ptr); + } + } + + /* mask any error, we may not need all these board + * devices */ + ret = 0; + } + + return ret; +} + +arch_initcall(s3c_arch_init); diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h new file mode 100644 index 0000000..478c15c --- /dev/null +++ b/arch/arm/mach-s3c2410/cpu.h @@ -0,0 +1,69 @@ +/* arch/arm/mach-s3c2410/cpu.h + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Header file for S3C24XX CPU support + * + * 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. + * + * Modifications: + * 24-Aug-2004 BJD Start of generic S3C24XX support + * 18-Oct-2004 BJD Moved board struct into this file + * 04-Jan-2005 BJD New uart initialisation + * 10-Jan-2005 BJD Moved generic init here, specific to cpu headers + * 14-Jan-2005 BJD Added s3c24xx_init_clocks() call + * 10-Mar-2005 LCVR Changed S3C2410_{VA,SZ} to S3C24XX_{VA,SZ} & IODESC_ENT + * 14-Mar-2005 BJD Updated for __iomem +*/ + +/* todo - fix when rmk changes iodescs to use `void __iomem *` */ + +#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, S3C2410_PA_##x, S3C24XX_SZ_##x, MT_DEVICE } + +#ifndef MHZ +#define MHZ (1000*1000) +#endif + +#define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000) + +/* forward declaration */ +struct s3c2410_uartcfg; +struct map_desc; + +/* core initialisation functions */ + +extern void s3c24xx_init_irq(void); + +extern void s3c24xx_init_io(struct map_desc *mach_desc, int size); + +extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no); + +extern void s3c24xx_init_clocks(int xtal); + +/* the board structure is used at first initialsation time + * to get info such as the devices to register for this + * board. This is done because platfrom_add_devices() cannot + * be called from the map_io entry. +*/ + +struct s3c24xx_board { + struct platform_device **devices; + unsigned int devices_count; + + struct clk **clocks; + unsigned int clocks_count; +}; + +extern void s3c24xx_set_board(struct s3c24xx_board *board); + +/* timer for 2410/2440 */ + +struct sys_timer; +extern struct sys_timer s3c24xx_timer; + +/* system device classes */ + +extern struct sysdev_class s3c2440_sysclass; diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c new file mode 100644 index 0000000..64792f6 --- /dev/null +++ b/arch/arm/mach-s3c2410/devs.c @@ -0,0 +1,485 @@ +/* linux/arch/arm/mach-s3c2410/devs.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Base S3C2410 platform device definitions + * + * 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. + * + * Modifications: + * 10-Mar-2005 LCVR Changed S3C2410_{VA,SZ} to S3C24XX_{VA,SZ} + * 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv + * 29-Aug-2004 BJD Added timers 0 through 3 + * 29-Aug-2004 BJD Changed index of devices we only have one of to -1 + * 21-Aug-2004 BJD Added IRQ_TICK to RTC resources + * 18-Aug-2004 BJD Created initial version +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> + +#include <asm/arch/regs-serial.h> + +#include "devs.h" + +/* Serial port registrations */ + +struct platform_device *s3c24xx_uart_devs[3]; + +/* USB Host Controller */ + +static struct resource s3c_usb_resource[] = { + [0] = { + .start = S3C2410_PA_USBHOST, + .end = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USBH, + .end = IRQ_USBH, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 s3c_device_usb_dmamask = 0xffffffffUL; + +struct platform_device s3c_device_usb = { + .name = "s3c2410-ohci", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usb_resource), + .resource = s3c_usb_resource, + .dev = { + .dma_mask = &s3c_device_usb_dmamask, + .coherent_dma_mask = 0xffffffffUL + } +}; + +EXPORT_SYMBOL(s3c_device_usb); + +/* LCD Controller */ + +static struct resource s3c_lcd_resource[] = { + [0] = { + .start = S3C2410_PA_LCD, + .end = S3C2410_PA_LCD + S3C24XX_SZ_LCD, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + } + +}; + +static u64 s3c_device_lcd_dmamask = 0xffffffffUL; + +struct platform_device s3c_device_lcd = { + .name = "s3c2410-lcd", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_lcd_resource), + .resource = s3c_lcd_resource, + .dev = { + .dma_mask = &s3c_device_lcd_dmamask, + .coherent_dma_mask = 0xffffffffUL + } +}; + +EXPORT_SYMBOL(s3c_device_lcd); + +/* NAND Controller */ + +static struct resource s3c_nand_resource[] = { + [0] = { + .start = S3C2410_PA_NAND, + .end = S3C2410_PA_NAND + S3C24XX_SZ_NAND, + .flags = IORESOURCE_MEM, + } +}; + +struct platform_device s3c_device_nand = { + .name = "s3c2410-nand", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_nand_resource), + .resource = s3c_nand_resource, +}; + +EXPORT_SYMBOL(s3c_device_nand); + +/* USB Device (Gadget)*/ + +static struct resource s3c_usbgadget_resource[] = { + [0] = { + .start = S3C2410_PA_USBDEV, + .end = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USBD, + .end = IRQ_USBD, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_usbgadget = { + .name = "s3c2410-usbgadget", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_usbgadget_resource), + .resource = s3c_usbgadget_resource, +}; + +EXPORT_SYMBOL(s3c_device_usbgadget); + +/* Watchdog */ + +static struct resource s3c_wdt_resource[] = { + [0] = { + .start = S3C2410_PA_WATCHDOG, + .end = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_WDT, + .end = IRQ_WDT, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_wdt = { + .name = "s3c2410-wdt", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_wdt_resource), + .resource = s3c_wdt_resource, +}; + +EXPORT_SYMBOL(s3c_device_wdt); + +/* I2C */ + +static struct resource s3c_i2c_resource[] = { + [0] = { + .start = S3C2410_PA_IIC, + .end = S3C2410_PA_IIC + S3C24XX_SZ_IIC, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IIC, + .end = IRQ_IIC, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_i2c = { + .name = "s3c2410-i2c", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_i2c_resource), + .resource = s3c_i2c_resource, +}; + +EXPORT_SYMBOL(s3c_device_i2c); + +/* IIS */ + +static struct resource s3c_iis_resource[] = { + [0] = { + .start = S3C2410_PA_IIS, + .end = S3C2410_PA_IIS + S3C24XX_SZ_IIS, + .flags = IORESOURCE_MEM, + } +}; + +static u64 s3c_device_iis_dmamask = 0xffffffffUL; + +struct platform_device s3c_device_iis = { + .name = "s3c2410-iis", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_iis_resource), + .resource = s3c_iis_resource, + .dev = { + .dma_mask = &s3c_device_iis_dmamask, + .coherent_dma_mask = 0xffffffffUL + } +}; + +EXPORT_SYMBOL(s3c_device_iis); + +/* RTC */ + +static struct resource s3c_rtc_resource[] = { + [0] = { + .start = S3C2410_PA_RTC, + .end = S3C2410_PA_RTC + 0xff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC, + .end = IRQ_RTC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_TICK, + .end = IRQ_TICK, + .flags = IORESOURCE_IRQ + } +}; + +struct platform_device s3c_device_rtc = { + .name = "s3c2410-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_rtc_resource), + .resource = s3c_rtc_resource, +}; + +EXPORT_SYMBOL(s3c_device_rtc); + +/* ADC */ + +static struct resource s3c_adc_resource[] = { + [0] = { + .start = S3C2410_PA_ADC, + .end = S3C2410_PA_ADC + S3C24XX_SZ_ADC, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TC, + .end = IRQ_ADC, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_adc = { + .name = "s3c2410-adc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_adc_resource), + .resource = s3c_adc_resource, +}; + +/* SDI */ + +static struct resource s3c_sdi_resource[] = { + [0] = { + .start = S3C2410_PA_SDI, + .end = S3C2410_PA_SDI + S3C24XX_SZ_SDI, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SDI, + .end = IRQ_SDI, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_sdi = { + .name = "s3c2410-sdi", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_sdi_resource), + .resource = s3c_sdi_resource, +}; + +EXPORT_SYMBOL(s3c_device_sdi); + +/* SPI (0) */ + +static struct resource s3c_spi0_resource[] = { + [0] = { + .start = S3C2410_PA_SPI, + .end = S3C2410_PA_SPI + 0x1f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SPI0, + .end = IRQ_SPI0, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_spi0 = { + .name = "s3c2410-spi", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_spi0_resource), + .resource = s3c_spi0_resource, +}; + +EXPORT_SYMBOL(s3c_device_spi0); + +/* SPI (1) */ + +static struct resource s3c_spi1_resource[] = { + [0] = { + .start = S3C2410_PA_SPI + 0x20, + .end = S3C2410_PA_SPI + 0x20 + 0x1f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SPI1, + .end = IRQ_SPI1, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_spi1 = { + .name = "s3c2410-spi", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_spi1_resource), + .resource = s3c_spi1_resource, +}; + +EXPORT_SYMBOL(s3c_device_spi1); + +/* pwm timer blocks */ + +static struct resource s3c_timer0_resource[] = { + [0] = { + .start = S3C2410_PA_TIMER + 0x0C, + .end = S3C2410_PA_TIMER + 0x0C + 0xB, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TIMER0, + .end = IRQ_TIMER0, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_timer0 = { + .name = "s3c2410-timer", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_timer0_resource), + .resource = s3c_timer0_resource, +}; + +EXPORT_SYMBOL(s3c_device_timer0); + +/* timer 1 */ + +static struct resource s3c_timer1_resource[] = { + [0] = { + .start = S3C2410_PA_TIMER + 0x18, + .end = S3C2410_PA_TIMER + 0x23, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TIMER1, + .end = IRQ_TIMER1, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_timer1 = { + .name = "s3c2410-timer", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_timer1_resource), + .resource = s3c_timer1_resource, +}; + +EXPORT_SYMBOL(s3c_device_timer1); + +/* timer 2 */ + +static struct resource s3c_timer2_resource[] = { + [0] = { + .start = S3C2410_PA_TIMER + 0x24, + .end = S3C2410_PA_TIMER + 0x2F, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TIMER2, + .end = IRQ_TIMER2, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_timer2 = { + .name = "s3c2410-timer", + .id = 2, + .num_resources = ARRAY_SIZE(s3c_timer2_resource), + .resource = s3c_timer2_resource, +}; + +EXPORT_SYMBOL(s3c_device_timer2); + +/* timer 3 */ + +static struct resource s3c_timer3_resource[] = { + [0] = { + .start = S3C2410_PA_TIMER + 0x30, + .end = S3C2410_PA_TIMER + 0x3B, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TIMER3, + .end = IRQ_TIMER3, + .flags = IORESOURCE_IRQ, + } + +}; + +struct platform_device s3c_device_timer3 = { + .name = "s3c2410-timer", + .id = 3, + .num_resources = ARRAY_SIZE(s3c_timer3_resource), + .resource = s3c_timer3_resource, +}; + +EXPORT_SYMBOL(s3c_device_timer3); + +#ifdef CONFIG_CPU_S3C2440 + +/* Camif Controller */ + +static struct resource s3c_camif_resource[] = { + [0] = { + .start = S3C2440_PA_CAMIF, + .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CAM, + .end = IRQ_CAM, + .flags = IORESOURCE_IRQ, + } + +}; + +static u64 s3c_device_camif_dmamask = 0xffffffffUL; + +struct platform_device s3c_device_camif = { + .name = "s3c2440-camif", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_camif_resource), + .resource = s3c_camif_resource, + .dev = { + .dma_mask = &s3c_device_camif_dmamask, + .coherent_dma_mask = 0xffffffffUL + } +}; + +EXPORT_SYMBOL(s3c_device_camif); + +#endif // CONFIG_CPU_S32440 diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h new file mode 100644 index 0000000..d6328f9 --- /dev/null +++ b/arch/arm/mach-s3c2410/devs.h @@ -0,0 +1,48 @@ +/* arch/arm/mach-s3c2410/devs.h + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Header file for s3c2410 standard platform devices + * + * 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. + * + * Modifications: + * 18-Aug-2004 BJD Created initial version + * 27-Aug-2004 BJD Added timers 0 through 3 + * 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv +*/ +#include <linux/config.h> + +extern struct platform_device *s3c24xx_uart_devs[]; + +extern struct platform_device s3c_device_usb; +extern struct platform_device s3c_device_lcd; +extern struct platform_device s3c_device_wdt; +extern struct platform_device s3c_device_i2c; +extern struct platform_device s3c_device_iis; +extern struct platform_device s3c_device_rtc; +extern struct platform_device s3c_device_adc; +extern struct platform_device s3c_device_sdi; + +extern struct platform_device s3c_device_spi0; +extern struct platform_device s3c_device_spi1; + +extern struct platform_device s3c_device_nand; + +extern struct platform_device s3c_device_timer0; +extern struct platform_device s3c_device_timer1; +extern struct platform_device s3c_device_timer2; +extern struct platform_device s3c_device_timer3; + +extern struct platform_device s3c_device_usbgadget; + +/* s3c2440 specific devices */ + +#ifdef CONFIG_CPU_S3C2440 + +extern struct platform_device s3c_device_camif; + +#endif diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c new file mode 100644 index 0000000..bc229fa --- /dev/null +++ b/arch/arm/mach-s3c2410/dma.c @@ -0,0 +1,1210 @@ +/* linux/arch/arm/mach-bast/dma.c + * + * (c) 2003-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 DMA core + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * 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. + * + * Changelog: + * 27-Feb-2005 BJD Added kmem cache for dma descriptors + * 18-Nov-2004 BJD Removed error for loading onto stopped channel + * 10-Nov-2004 BJD Ensure all external symbols exported for modules + * 10-Nov-2004 BJD Use sys_device and sysdev_class for power management + * 08-Aug-2004 BJD Apply rmk's suggestions + * 21-Jul-2004 BJD Ported to linux 2.6 + * 12-Jul-2004 BJD Finished re-write and change of API + * 06-Jul-2004 BJD Rewrote dma code to try and cope with various problems + * 23-May-2003 BJD Created file + * 19-Aug-2003 BJD Cleanup, header fix, added URL + * + * This file is based on the Sangwook Lee/Samsung patches, re-written due + * to various ommisions from the code (such as flexible dma configuration) + * for use with the BAST system board. + * + * The re-write is pretty much complete, and should be good enough for any + * possible DMA function + */ + +#include <linux/config.h> + +#ifdef CONFIG_S3C2410_DMA_DEBUG +#define DEBUG +#endif + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/sysdev.h> +#include <linux/slab.h> +#include <linux/errno.h> +#include <linux/delay.h> + +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/dma.h> + +#include <asm/mach/dma.h> +#include <asm/arch/map.h> + +/* io map for dma */ +static void __iomem *dma_base; +static kmem_cache_t *dma_kmem; + +/* dma channel state information */ +s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS]; + +/* debugging functions */ + +#define BUF_MAGIC (0xcafebabe) + +#define dmawarn(fmt...) printk(KERN_DEBUG fmt) + +#define dma_regaddr(chan, reg) ((chan)->regs + (reg)) + +#if 1 +#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg)) +#else +static inline void +dma_wrreg(s3c2410_dma_chan_t *chan, int reg, unsigned long val) +{ + pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg); + writel(val, dma_regaddr(chan, reg)); +} + +#endif + +#define dma_rdreg(chan, reg) readl((chan)->regs + (reg)) + +/* captured register state for debug */ + +struct s3c2410_dma_regstate { + unsigned long dcsrc; + unsigned long disrc; + unsigned long dstat; + unsigned long dcon; + unsigned long dmsktrig; +}; + +#ifdef CONFIG_S3C2410_DMA_DEBUG + +/* dmadbg_showregs + * + * simple debug routine to print the current state of the dma registers +*/ + +static void +dmadbg_capture(s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs) +{ + regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC); + regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC); + regs->dstat = dma_rdreg(chan, S3C2410_DMA_DSTAT); + regs->dcon = dma_rdreg(chan, S3C2410_DMA_DCON); + regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); +} + +static void +dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan, + struct s3c2410_dma_regstate *regs) +{ + printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n", + chan->number, fname, line, + regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig, + regs->dcon); +} + +static void +dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan) +{ + struct s3c2410_dma_regstate state; + + dmadbg_capture(chan, &state); + + printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n", + chan->number, fname, line, chan->load_state, + chan->curr, chan->next, chan->end); + + dmadbg_showregs(fname, line, chan, &state); +} + +#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan)) +#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan)) +#else +#define dbg_showregs(chan) do { } while(0) +#define dbg_showchan(chan) do { } while(0) +#endif /* CONFIG_S3C2410_DMA_DEBUG */ + +#define check_channel(chan) \ + do { if ((chan) >= S3C2410_DMA_CHANNELS) { \ + printk(KERN_ERR "%s: invalid channel %d\n", __FUNCTION__, (chan)); \ + return -EINVAL; \ + } } while(0) + + +/* s3c2410_dma_stats_timeout + * + * Update DMA stats from timeout info +*/ + +static void +s3c2410_dma_stats_timeout(s3c2410_dma_stats_t *stats, int val) +{ + if (stats == NULL) + return; + + if (val > stats->timeout_longest) + stats->timeout_longest = val; + if (val < stats->timeout_shortest) + stats->timeout_shortest = val; + + stats->timeout_avg += val; +} + +/* s3c2410_dma_waitforload + * + * wait for the DMA engine to load a buffer, and update the state accordingly +*/ + +static int +s3c2410_dma_waitforload(s3c2410_dma_chan_t *chan, int line) +{ + int timeout = chan->load_timeout; + int took; + + if (chan->load_state != S3C2410_DMALOAD_1LOADED) { + printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line); + return 0; + } + + if (chan->stats != NULL) + chan->stats->loads++; + + while (--timeout > 0) { + if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) { + took = chan->load_timeout - timeout; + + s3c2410_dma_stats_timeout(chan->stats, took); + + switch (chan->load_state) { + case S3C2410_DMALOAD_1LOADED: + chan->load_state = S3C2410_DMALOAD_1RUNNING; + break; + + default: + printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state); + } + + return 1; + } + } + + if (chan->stats != NULL) { + chan->stats->timeout_failed++; + } + + return 0; +} + + + +/* s3c2410_dma_loadbuffer + * + * load a buffer, and update the channel state +*/ + +static inline int +s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan, + s3c2410_dma_buf_t *buf) +{ + unsigned long reload; + + pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n", + buf, (unsigned long)buf->data, buf->size); + + if (buf == NULL) { + dmawarn("buffer is NULL\n"); + return -EINVAL; + } + + /* check the state of the channel before we do anything */ + + if (chan->load_state == S3C2410_DMALOAD_1LOADED) { + dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n"); + } + + if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) { + dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n"); + } + + /* it would seem sensible if we are the last buffer to not bother + * with the auto-reload bit, so that the DMA engine will not try + * and load another transfer after this one has finished... + */ + if (chan->load_state == S3C2410_DMALOAD_NONE) { + pr_debug("load_state is none, checking for noreload (next=%p)\n", + buf->next); + reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0; + } else { + pr_debug("load_state is %d => autoreload\n", chan->load_state); + reload = S3C2410_DCON_AUTORELOAD; + } + + writel(buf->data, chan->addr_reg); + + dma_wrreg(chan, S3C2410_DMA_DCON, + chan->dcon | reload | (buf->size/chan->xfer_unit)); + + chan->next = buf->next; + + /* update the state of the channel */ + + switch (chan->load_state) { + case S3C2410_DMALOAD_NONE: + chan->load_state = S3C2410_DMALOAD_1LOADED; + break; + + case S3C2410_DMALOAD_1RUNNING: + chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING; + break; + + default: + dmawarn("dmaload: unknown state %d in loadbuffer\n", + chan->load_state); + break; + } + + return 0; +} + +/* s3c2410_dma_call_op + * + * small routine to call the op routine with the given op if it has been + * registered +*/ + +static void +s3c2410_dma_call_op(s3c2410_dma_chan_t *chan, s3c2410_chan_op_t op) +{ + if (chan->op_fn != NULL) { + (chan->op_fn)(chan, op); + } +} + +/* s3c2410_dma_buffdone + * + * small wrapper to check if callback routine needs to be called, and + * if so, call it +*/ + +static inline void +s3c2410_dma_buffdone(s3c2410_dma_chan_t *chan, s3c2410_dma_buf_t *buf, + s3c2410_dma_buffresult_t result) +{ + pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n", + chan->callback_fn, buf, buf->id, buf->size, result); + + if (chan->callback_fn != NULL) { + (chan->callback_fn)(chan, buf->id, buf->size, result); + } +} + +/* s3c2410_dma_start + * + * start a dma channel going +*/ + +static int s3c2410_dma_start(s3c2410_dma_chan_t *chan) +{ + unsigned long tmp; + unsigned long flags; + + pr_debug("s3c2410_start_dma: channel=%d\n", chan->number); + + local_irq_save(flags); + + if (chan->state == S3C2410_DMA_RUNNING) { + pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state); + local_irq_restore(flags); + return 0; + } + + chan->state = S3C2410_DMA_RUNNING; + + /* check wether there is anything to load, and if not, see + * if we can find anything to load + */ + + if (chan->load_state == S3C2410_DMALOAD_NONE) { + if (chan->next == NULL) { + printk(KERN_ERR "dma%d: channel has nothing loaded\n", + chan->number); + chan->state = S3C2410_DMA_IDLE; + local_irq_restore(flags); + return -EINVAL; + } + + s3c2410_dma_loadbuffer(chan, chan->next); + } + + dbg_showchan(chan); + + /* enable the channel */ + + if (!chan->irq_enabled) { + enable_irq(chan->irq); + chan->irq_enabled = 1; + } + + /* start the channel going */ + + tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); + tmp &= ~S3C2410_DMASKTRIG_STOP; + tmp |= S3C2410_DMASKTRIG_ON; + dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); + + pr_debug("wrote %08lx to DMASKTRIG\n", tmp); + +#if 0 + /* the dma buffer loads should take care of clearing the AUTO + * reloading feature */ + tmp = dma_rdreg(chan, S3C2410_DMA_DCON); + tmp &= ~S3C2410_DCON_NORELOAD; + dma_wrreg(chan, S3C2410_DMA_DCON, tmp); +#endif + + s3c2410_dma_call_op(chan, S3C2410_DMAOP_START); + + dbg_showchan(chan); + + local_irq_restore(flags); + return 0; +} + +/* s3c2410_dma_canload + * + * work out if we can queue another buffer into the DMA engine +*/ + +static int +s3c2410_dma_canload(s3c2410_dma_chan_t *chan) +{ + if (chan->load_state == S3C2410_DMALOAD_NONE || + chan->load_state == S3C2410_DMALOAD_1RUNNING) + return 1; + + return 0; +} + + +/* s3c2410_dma_enqueue + * + * queue an given buffer for dma transfer. + * + * id the device driver's id information for this buffer + * data the physical address of the buffer data + * size the size of the buffer in bytes + * + * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART + * is checked, and if set, the channel is started. If this flag isn't set, + * then an error will be returned. + * + * It is possible to queue more than one DMA buffer onto a channel at + * once, and the code will deal with the re-loading of the next buffer + * when necessary. +*/ + +int s3c2410_dma_enqueue(unsigned int channel, void *id, + dma_addr_t data, int size) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + s3c2410_dma_buf_t *buf; + unsigned long flags; + + check_channel(channel); + + pr_debug("%s: id=%p, data=%08x, size=%d\n", + __FUNCTION__, id, (unsigned int)data, size); + + buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC); + if (buf == NULL) { + pr_debug("%s: out of memory (%d alloc)\n", + __FUNCTION__, sizeof(*buf)); + return -ENOMEM; + } + + pr_debug("%s: new buffer %p\n", __FUNCTION__, buf); + + //dbg_showchan(chan); + + buf->next = NULL; + buf->data = buf->ptr = data; + buf->size = size; + buf->id = id; + buf->magic = BUF_MAGIC; + + local_irq_save(flags); + + if (chan->curr == NULL) { + /* we've got nothing loaded... */ + pr_debug("%s: buffer %p queued onto empty channel\n", + __FUNCTION__, buf); + + chan->curr = buf; + chan->end = buf; + chan->next = NULL; + } else { + pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", + chan->number, __FUNCTION__, buf); + + if (chan->end == NULL) + pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", + chan->number, __FUNCTION__, chan); + + chan->end->next = buf; + chan->end = buf; + } + + /* if necessary, update the next buffer field */ + if (chan->next == NULL) + chan->next = buf; + + /* check to see if we can load a buffer */ + if (chan->state == S3C2410_DMA_RUNNING) { + if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) { + if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { + printk(KERN_ERR "dma%d: loadbuffer:" + "timeout loading buffer\n", + chan->number); + dbg_showchan(chan); + local_irq_restore(flags); + return -EINVAL; + } + } + + while (s3c2410_dma_canload(chan) && chan->next != NULL) { + s3c2410_dma_loadbuffer(chan, chan->next); + } + } else if (chan->state == S3C2410_DMA_IDLE) { + if (chan->flags & S3C2410_DMAF_AUTOSTART) { + s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START); + } + } + + local_irq_restore(flags); + return 0; +} + +EXPORT_SYMBOL(s3c2410_dma_enqueue); + +static inline void +s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf) +{ + int magicok = (buf->magic == BUF_MAGIC); + + buf->magic = -1; + + if (magicok) { + kmem_cache_free(dma_kmem, buf); + } else { + printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf); + } +} + +/* s3c2410_dma_lastxfer + * + * called when the system is out of buffers, to ensure that the channel + * is prepared for shutdown. +*/ + +static inline void +s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan) +{ + pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n", + chan->number, chan->load_state); + + switch (chan->load_state) { + case S3C2410_DMALOAD_NONE: + break; + + case S3C2410_DMALOAD_1LOADED: + if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { + /* flag error? */ + printk(KERN_ERR "dma%d: timeout waiting for load\n", + chan->number); + return; + } + break; + + default: + pr_debug("dma%d: lastxfer: unhandled load_state %d with no next", + chan->number, chan->load_state); + return; + + } + + /* hopefully this'll shut the damned thing up after the transfer... */ + dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD); +} + + +#define dmadbg2(x...) + +static irqreturn_t +s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) +{ + s3c2410_dma_chan_t *chan = (s3c2410_dma_chan_t *)devpw; + s3c2410_dma_buf_t *buf; + + buf = chan->curr; + + dbg_showchan(chan); + + /* modify the channel state */ + + switch (chan->load_state) { + case S3C2410_DMALOAD_1RUNNING: + /* TODO - if we are running only one buffer, we probably + * want to reload here, and then worry about the buffer + * callback */ + + chan->load_state = S3C2410_DMALOAD_NONE; + break; + + case S3C2410_DMALOAD_1LOADED: + /* iirc, we should go back to NONE loaded here, we + * had a buffer, and it was never verified as being + * loaded. + */ + + chan->load_state = S3C2410_DMALOAD_NONE; + break; + + case S3C2410_DMALOAD_1LOADED_1RUNNING: + /* we'll worry about checking to see if another buffer is + * ready after we've called back the owner. This should + * ensure we do not wait around too long for the DMA + * engine to start the next transfer + */ + + chan->load_state = S3C2410_DMALOAD_1LOADED; + break; + + case S3C2410_DMALOAD_NONE: + printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n", + chan->number); + break; + + default: + printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n", + chan->number, chan->load_state); + break; + } + + if (buf != NULL) { + /* update the chain to make sure that if we load any more + * buffers when we call the callback function, things should + * work properly */ + + chan->curr = buf->next; + buf->next = NULL; + + if (buf->magic != BUF_MAGIC) { + printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n", + chan->number, __FUNCTION__, buf); + return IRQ_HANDLED; + } + + s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK); + + /* free resouces */ + s3c2410_dma_freebuf(buf); + } else { + } + + if (chan->next != NULL) { + unsigned long flags; + + switch (chan->load_state) { + case S3C2410_DMALOAD_1RUNNING: + /* don't need to do anything for this state */ + break; + + case S3C2410_DMALOAD_NONE: + /* can load buffer immediately */ + break; + + case S3C2410_DMALOAD_1LOADED: + if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { + /* flag error? */ + printk(KERN_ERR "dma%d: timeout waiting for load\n", + chan->number); + return IRQ_HANDLED; + } + + break; + + case S3C2410_DMALOAD_1LOADED_1RUNNING: + goto no_load; + + default: + printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n", + chan->number, chan->load_state); + return IRQ_HANDLED; + } + + local_irq_save(flags); + s3c2410_dma_loadbuffer(chan, chan->next); + local_irq_restore(flags); + } else { + s3c2410_dma_lastxfer(chan); + + /* see if we can stop this channel.. */ + if (chan->load_state == S3C2410_DMALOAD_NONE) { + pr_debug("dma%d: end of transfer, stopping channel (%ld)\n", + chan->number, jiffies); + s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP); + } + } + + no_load: + return IRQ_HANDLED; +} + + + +/* s3c2410_request_dma + * + * get control of an dma channel +*/ + +int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client, + void *dev) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + unsigned long flags; + int err; + + pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", + channel, client->name, dev); + + check_channel(channel); + + local_irq_save(flags); + + dbg_showchan(chan); + + if (chan->in_use) { + if (client != chan->client) { + printk(KERN_ERR "dma%d: already in use\n", channel); + local_irq_restore(flags); + return -EBUSY; + } else { + printk(KERN_ERR "dma%d: client already has channel\n", channel); + } + } + + chan->client = client; + chan->in_use = 1; + + if (!chan->irq_claimed) { + pr_debug("dma%d: %s : requesting irq %d\n", + channel, __FUNCTION__, chan->irq); + + err = request_irq(chan->irq, s3c2410_dma_irq, SA_INTERRUPT, + client->name, (void *)chan); + + if (err) { + chan->in_use = 0; + local_irq_restore(flags); + + printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n", + client->name, chan->irq, chan->number); + return err; + } + + chan->irq_claimed = 1; + chan->irq_enabled = 1; + } + + local_irq_restore(flags); + + /* need to setup */ + + pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan); + + return 0; +} + +EXPORT_SYMBOL(s3c2410_dma_request); + +/* s3c2410_dma_free + * + * release the given channel back to the system, will stop and flush + * any outstanding transfers, and ensure the channel is ready for the + * next claimant. + * + * Note, although a warning is currently printed if the freeing client + * info is not the same as the registrant's client info, the free is still + * allowed to go through. +*/ + +int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + unsigned long flags; + + check_channel(channel); + + local_irq_save(flags); + + + if (chan->client != client) { + printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n", + channel, chan->client, client); + } + + /* sort out stopping and freeing the channel */ + + if (chan->state != S3C2410_DMA_IDLE) { + pr_debug("%s: need to stop dma channel %p\n", + __FUNCTION__, chan); + + /* possibly flush the channel */ + s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP); + } + + chan->client = NULL; + chan->in_use = 0; + + local_irq_restore(flags); + + return 0; +} + +EXPORT_SYMBOL(s3c2410_dma_free); + +static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan) +{ + unsigned long tmp; + unsigned long flags; + + pr_debug("%s:\n", __FUNCTION__); + + dbg_showchan(chan); + + local_irq_save(flags); + + s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP); + + tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); + tmp |= S3C2410_DMASKTRIG_STOP; + dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); + +#if 0 + /* should also clear interrupts, according to WinCE BSP */ + tmp = dma_rdreg(chan, S3C2410_DMA_DCON); + tmp |= S3C2410_DCON_NORELOAD; + dma_wrreg(chan, S3C2410_DMA_DCON, tmp); +#endif + + chan->state = S3C2410_DMA_IDLE; + chan->load_state = S3C2410_DMALOAD_NONE; + + local_irq_restore(flags); + + return 0; +} + +/* s3c2410_dma_flush + * + * stop the channel, and remove all current and pending transfers +*/ + +static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan) +{ + s3c2410_dma_buf_t *buf, *next; + unsigned long flags; + + pr_debug("%s:\n", __FUNCTION__); + + local_irq_save(flags); + + if (chan->state != S3C2410_DMA_IDLE) { + pr_debug("%s: stopping channel...\n", __FUNCTION__ ); + s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP); + } + + buf = chan->curr; + if (buf == NULL) + buf = chan->next; + + chan->curr = chan->next = chan->end = NULL; + + if (buf != NULL) { + for ( ; buf != NULL; buf = next) { + next = buf->next; + + pr_debug("%s: free buffer %p, next %p\n", + __FUNCTION__, buf, buf->next); + + s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT); + s3c2410_dma_freebuf(buf); + } + } + + local_irq_restore(flags); + + return 0; +} + + +int +s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + + check_channel(channel); + + switch (op) { + case S3C2410_DMAOP_START: + return s3c2410_dma_start(chan); + + case S3C2410_DMAOP_STOP: + return s3c2410_dma_dostop(chan); + + case S3C2410_DMAOP_PAUSE: + return -ENOENT; + + case S3C2410_DMAOP_RESUME: + return -ENOENT; + + case S3C2410_DMAOP_FLUSH: + return s3c2410_dma_flush(chan); + + case S3C2410_DMAOP_TIMEOUT: + return 0; + + } + + return -ENOENT; /* unknown, don't bother */ +} + +EXPORT_SYMBOL(s3c2410_dma_ctrl); + +/* DMA configuration for each channel + * + * DISRCC -> source of the DMA (AHB,APB) + * DISRC -> source address of the DMA + * DIDSTC -> destination of the DMA (AHB,APD) + * DIDST -> destination address of the DMA +*/ + +/* s3c2410_dma_config + * + * xfersize: size of unit in bytes (1,2,4) + * dcon: base value of the DCONx register +*/ + +int s3c2410_dma_config(dmach_t channel, + int xferunit, + int dcon) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + + pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", + __FUNCTION__, channel, xferunit, dcon); + + check_channel(channel); + + switch (xferunit) { + case 1: + dcon |= S3C2410_DCON_BYTE; + break; + + case 2: + dcon |= S3C2410_DCON_HALFWORD; + break; + + case 4: + dcon |= S3C2410_DCON_WORD; + break; + + default: + pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit); + return -EINVAL; + } + + dcon |= S3C2410_DCON_HWTRIG; + dcon |= S3C2410_DCON_INTREQ; + + pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon); + + chan->dcon = dcon; + chan->xfer_unit = xferunit; + + return 0; +} + +EXPORT_SYMBOL(s3c2410_dma_config); + +int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + + check_channel(channel); + + pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags); + + chan->flags = flags; + + return 0; +} + +EXPORT_SYMBOL(s3c2410_dma_setflags); + + +/* do we need to protect the settings of the fields from + * irq? +*/ + +int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + + check_channel(channel); + + pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn); + + chan->op_fn = rtn; + + return 0; +} + +EXPORT_SYMBOL(s3c2410_dma_set_opfn); + +int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + + check_channel(channel); + + pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn); + + chan->callback_fn = rtn; + + return 0; +} + +EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); + +/* s3c2410_dma_devconfig + * + * configure the dma source/destination hardware type and address + * + * source: S3C2410_DMASRC_HW: source is hardware + * S3C2410_DMASRC_MEM: source is memory + * + * hwcfg: the value for xxxSTCn register, + * bit 0: 0=increment pointer, 1=leave pointer + * bit 1: 0=soucre is AHB, 1=soucre is APB + * + * devaddr: physical address of the source +*/ + +int s3c2410_dma_devconfig(int channel, + s3c2410_dmasrc_t source, + int hwcfg, + unsigned long devaddr) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + + check_channel(channel); + + pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", + __FUNCTION__, (int)source, hwcfg, devaddr); + + chan->source = source; + chan->dev_addr = devaddr; + + switch (source) { + case S3C2410_DMASRC_HW: + /* source is hardware */ + pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n", + __FUNCTION__, devaddr, hwcfg); + dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3); + dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr); + dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0)); + + chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST); + return 0; + + case S3C2410_DMASRC_MEM: + /* source is memory */ + pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n", + __FUNCTION__, devaddr, hwcfg); + dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0)); + dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr); + dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3); + + chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC); + return 0; + } + + printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source); + return -EINVAL; +} + +EXPORT_SYMBOL(s3c2410_dma_devconfig); + +/* s3c2410_dma_getposition + * + * returns the current transfer points for the dma source and destination +*/ + +int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) +{ + s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; + + check_channel(channel); + + if (src != NULL) + *src = dma_rdreg(chan, S3C2410_DMA_DCSRC); + + if (dst != NULL) + *dst = dma_rdreg(chan, S3C2410_DMA_DCDST); + + return 0; +} + +EXPORT_SYMBOL(s3c2410_dma_getposition); + + +/* system device class */ + +#ifdef CONFIG_PM + +static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) +{ + s3c2410_dma_chan_t *cp = container_of(dev, s3c2410_dma_chan_t, dev); + + printk(KERN_DEBUG "suspending dma channel %d\n", cp->number); + + if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) { + /* the dma channel is still working, which is probably + * a bad thing to do over suspend/resume. We stop the + * channel and assume that the client is either going to + * retry after resume, or that it is broken. + */ + + printk(KERN_INFO "dma: stopping channel %d due to suspend\n", + cp->number); + + s3c2410_dma_dostop(cp); + } + + return 0; +} + +static int s3c2410_dma_resume(struct sys_device *dev) +{ + return 0; +} + +#else +#define s3c2410_dma_suspend NULL +#define s3c2410_dma_resume NULL +#endif /* CONFIG_PM */ + +static struct sysdev_class dma_sysclass = { + set_kset_name("s3c24xx-dma"), + .suspend = s3c2410_dma_suspend, + .resume = s3c2410_dma_resume, +}; + +/* kmem cache implementation */ + +static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f) +{ + memset(p, 0, sizeof(s3c2410_dma_buf_t)); +} + + +/* initialisation code */ + +static int __init s3c2410_init_dma(void) +{ + s3c2410_dma_chan_t *cp; + int channel; + int ret; + + printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n"); + + dma_base = ioremap(S3C2410_PA_DMA, 0x200); + if (dma_base == NULL) { + printk(KERN_ERR "dma failed to remap register block\n"); + return -ENOMEM; + } + + ret = sysdev_class_register(&dma_sysclass); + if (ret != 0) { + printk(KERN_ERR "dma sysclass registration failed\n"); + goto err; + } + + dma_kmem = kmem_cache_create("dma_desc", sizeof(s3c2410_dma_buf_t), 0, + SLAB_HWCACHE_ALIGN, + s3c2410_dma_cache_ctor, NULL); + + if (dma_kmem == NULL) { + printk(KERN_ERR "dma failed to make kmem cache\n"); + ret = -ENOMEM; + goto err; + } + + for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) { + cp = &s3c2410_chans[channel]; + + memset(cp, 0, sizeof(s3c2410_dma_chan_t)); + + /* dma channel irqs are in order.. */ + cp->number = channel; + cp->irq = channel + IRQ_DMA0; + cp->regs = dma_base + (channel*0x40); + + /* point current stats somewhere */ + cp->stats = &cp->stats_store; + cp->stats_store.timeout_shortest = LONG_MAX; + + /* basic channel configuration */ + + cp->load_timeout = 1<<18; + + /* register system device */ + + cp->dev.cls = &dma_sysclass; + cp->dev.id = channel; + ret = sysdev_register(&cp->dev); + + printk("DMA channel %d at %p, irq %d\n", + cp->number, cp->regs, cp->irq); + } + + return 0; + + err: + kmem_cache_destroy(dma_kmem); + iounmap(dma_base); + dma_base = NULL; + return ret; +} + +__initcall(s3c2410_init_dma); diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c new file mode 100644 index 0000000..94f1776 --- /dev/null +++ b/arch/arm/mach-s3c2410/gpio.c @@ -0,0 +1,213 @@ +/* linux/arch/arm/mach-s3c2410/gpio.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 GPIO support + * + * 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 + * + * Changelog + * 13-Sep-2004 BJD Implemented change of MISCCR + * 14-Sep-2004 BJD Added getpin call + * 14-Sep-2004 BJD Fixed bug in setpin() call + * 30-Sep-2004 BJD Fixed cfgpin() mask bug + * 01-Oct-2004 BJD Added getcfg() to get pin configuration + * 01-Oct-2004 BJD Fixed mask bug in pullup() call + * 01-Oct-2004 BJD Added getirq() to turn pin into irqno + * 04-Oct-2004 BJD Added irq filter controls for GPIO + * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code + * 13-Mar-2005 BJD Updates for __iomem + */ + + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/arch/regs-gpio.h> + +void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) +{ + void __iomem *base = S3C2410_GPIO_BASE(pin); + unsigned long mask; + unsigned long con; + unsigned long flags; + + if (pin < S3C2410_GPIO_BANKB) { + mask = 1 << S3C2410_GPIO_OFFSET(pin); + } else { + mask = 3 << S3C2410_GPIO_OFFSET(pin)*2; + } + + local_irq_save(flags); + + con = __raw_readl(base + 0x00); + con &= ~mask; + con |= function; + + __raw_writel(con, base + 0x00); + + local_irq_restore(flags); +} + +EXPORT_SYMBOL(s3c2410_gpio_cfgpin); + +unsigned int s3c2410_gpio_getcfg(unsigned int pin) +{ + void __iomem *base = S3C2410_GPIO_BASE(pin); + unsigned long mask; + + if (pin < S3C2410_GPIO_BANKB) { + mask = 1 << S3C2410_GPIO_OFFSET(pin); + } else { + mask = 3 << S3C2410_GPIO_OFFSET(pin)*2; + } + + return __raw_readl(base) & mask; +} + +EXPORT_SYMBOL(s3c2410_gpio_getcfg); + +void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) +{ + void __iomem *base = S3C2410_GPIO_BASE(pin); + unsigned long offs = S3C2410_GPIO_OFFSET(pin); + unsigned long flags; + unsigned long up; + + if (pin < S3C2410_GPIO_BANKB) + return; + + local_irq_save(flags); + + up = __raw_readl(base + 0x08); + up &= ~(1L << offs); + up |= to << offs; + __raw_writel(up, base + 0x08); + + local_irq_restore(flags); +} + +EXPORT_SYMBOL(s3c2410_gpio_pullup); + +void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) +{ + void __iomem *base = S3C2410_GPIO_BASE(pin); + unsigned long offs = S3C2410_GPIO_OFFSET(pin); + unsigned long flags; + unsigned long dat; + + local_irq_save(flags); + + dat = __raw_readl(base + 0x04); + dat &= ~(1 << offs); + dat |= to << offs; + __raw_writel(dat, base + 0x04); + + local_irq_restore(flags); +} + +EXPORT_SYMBOL(s3c2410_gpio_setpin); + +unsigned int s3c2410_gpio_getpin(unsigned int pin) +{ + void __iomem *base = S3C2410_GPIO_BASE(pin); + unsigned long offs = S3C2410_GPIO_OFFSET(pin); + + return __raw_readl(base + 0x04) & (1<< offs); +} + +EXPORT_SYMBOL(s3c2410_gpio_getpin); + +unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) +{ + unsigned long flags; + unsigned long misccr; + + local_irq_save(flags); + misccr = __raw_readl(S3C2410_MISCCR); + misccr &= ~clear; + misccr ^= change; + __raw_writel(misccr, S3C2410_MISCCR); + local_irq_restore(flags); + + return misccr; +} + +EXPORT_SYMBOL(s3c2410_modify_misccr); + +int s3c2410_gpio_getirq(unsigned int pin) +{ + if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23) + return -1; /* not valid interrupts */ + + if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) + return -1; /* not valid pin */ + + if (pin < S3C2410_GPF4) + return (pin - S3C2410_GPF0) + IRQ_EINT0; + + if (pin < S3C2410_GPG0) + return (pin - S3C2410_GPF4) + IRQ_EINT4; + + return (pin - S3C2410_GPG0) + IRQ_EINT8; +} + +EXPORT_SYMBOL(s3c2410_gpio_getirq); + +int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, + unsigned int config) +{ + void __iomem *reg = S3C2410_EINFLT0; + unsigned long flags; + unsigned long val; + + if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15) + return -1; + + config &= 0xff; + + pin -= S3C2410_GPG8_EINT16; + reg += pin & ~3; + + local_irq_save(flags); + + /* update filter width and clock source */ + + val = __raw_readl(reg); + val &= ~(0xff << ((pin & 3) * 8)); + val |= config << ((pin & 3) * 8); + __raw_writel(val, reg); + + /* update filter enable */ + + val = __raw_readl(S3C2410_EXTINT2); + val &= ~(1 << ((pin * 4) + 3)); + val |= on << ((pin * 4) + 3); + __raw_writel(val, S3C2410_EXTINT2); + + local_irq_restore(flags); + + return 0; +} + +EXPORT_SYMBOL(s3c2410_gpio_irqfilter); diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c new file mode 100644 index 0000000..b668c48 --- /dev/null +++ b/arch/arm/mach-s3c2410/irq.c @@ -0,0 +1,966 @@ +/* linux/arch/arm/mach-s3c2410/irq.c + * + * Copyright (c) 2003,2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * 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 + * + * Changelog: + * + * 22-Jul-2004 Ben Dooks <ben@simtec.co.uk> + * Fixed compile warnings + * + * 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn> + * Fixed s3c_extirq_type + * + * 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org> + * Addition of ADC/TC demux + * + * 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de> + * Fix for set_irq_type() on low EINT numbers + * + * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk> + * Tidy up KF's patch and sort out new release + * + * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk> + * Add support for power management controls + * + * 04-Nov-2004 Ben Dooks + * Fix standard IRQ wake for EINT0..4 and RTC + * + * 22-Feb-2004 Ben Dooks + * Fixed edge-triggering on ADC IRQ +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/ptrace.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/irq.h> + +#include <asm/arch/regs-irq.h> +#include <asm/arch/regs-gpio.h> + +#include "cpu.h" +#include "pm.h" + +#define irqdbf(x...) +#define irqdbf2(x...) + +#define EXTINT_OFF (IRQ_EINT4 - 4) + +/* wakeup irq control */ + +#ifdef CONFIG_PM + +/* state for IRQs over sleep */ + +/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources + * + * set bit to 1 in allow bitfield to enable the wakeup settings on it +*/ + +unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL; +unsigned long s3c_irqwake_intmask = 0xffffffffL; +unsigned long s3c_irqwake_eintallow = 0x0000fff0L; +unsigned long s3c_irqwake_eintmask = 0xffffffffL; + +static int +s3c_irq_wake(unsigned int irqno, unsigned int state) +{ + unsigned long irqbit = 1 << (irqno - IRQ_EINT0); + + if (!(s3c_irqwake_intallow & irqbit)) + return -ENOENT; + + printk(KERN_INFO "wake %s for irq %d\n", + state ? "enabled" : "disabled", irqno); + + if (!state) + s3c_irqwake_intmask |= irqbit; + else + s3c_irqwake_intmask &= ~irqbit; + + return 0; +} + +static int +s3c_irqext_wake(unsigned int irqno, unsigned int state) +{ + unsigned long bit = 1L << (irqno - EXTINT_OFF); + + if (!(s3c_irqwake_eintallow & bit)) + return -ENOENT; + + printk(KERN_INFO "wake %s for irq %d\n", + state ? "enabled" : "disabled", irqno); + + if (!state) + s3c_irqwake_eintmask |= bit; + else + s3c_irqwake_eintmask &= ~bit; + + return 0; +} + +#else +#define s3c_irqext_wake NULL +#define s3c_irq_wake NULL +#endif + + +static void +s3c_irq_mask(unsigned int irqno) +{ + unsigned long mask; + + irqno -= IRQ_EINT0; + + mask = __raw_readl(S3C2410_INTMSK); + mask |= 1UL << irqno; + __raw_writel(mask, S3C2410_INTMSK); +} + +static inline void +s3c_irq_ack(unsigned int irqno) +{ + unsigned long bitval = 1UL << (irqno - IRQ_EINT0); + + __raw_writel(bitval, S3C2410_SRCPND); + __raw_writel(bitval, S3C2410_INTPND); +} + +static inline void +s3c_irq_maskack(unsigned int irqno) +{ + unsigned long bitval = 1UL << (irqno - IRQ_EINT0); + unsigned long mask; + + mask = __raw_readl(S3C2410_INTMSK); + __raw_writel(mask|bitval, S3C2410_INTMSK); + + __raw_writel(bitval, S3C2410_SRCPND); + __raw_writel(bitval, S3C2410_INTPND); +} + + +static void +s3c_irq_unmask(unsigned int irqno) +{ + unsigned long mask; + + if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23) + irqdbf2("s3c_irq_unmask %d\n", irqno); + + irqno -= IRQ_EINT0; + + mask = __raw_readl(S3C2410_INTMSK); + mask &= ~(1UL << irqno); + __raw_writel(mask, S3C2410_INTMSK); +} + +static struct irqchip s3c_irq_level_chip = { + .ack = s3c_irq_maskack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .wake = s3c_irq_wake +}; + +static struct irqchip s3c_irq_chip = { + .ack = s3c_irq_ack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .wake = s3c_irq_wake +}; + +/* S3C2410_EINTMASK + * S3C2410_EINTPEND + */ + +static void +s3c_irqext_mask(unsigned int irqno) +{ + unsigned long mask; + + irqno -= EXTINT_OFF; + + mask = __raw_readl(S3C2410_EINTMASK); + mask |= ( 1UL << irqno); + __raw_writel(mask, S3C2410_EINTMASK); + + if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) { + /* check to see if all need masking */ + + if ((mask & (0xf << 4)) == (0xf << 4)) { + /* all masked, mask the parent */ + s3c_irq_mask(IRQ_EINT4t7); + } + } else { + /* todo: the same check as above for the rest of the irq regs...*/ + + } +} + +static void +s3c_irqext_ack(unsigned int irqno) +{ + unsigned long req; + unsigned long bit; + unsigned long mask; + + bit = 1UL << (irqno - EXTINT_OFF); + + + mask = __raw_readl(S3C2410_EINTMASK); + + __raw_writel(bit, S3C2410_EINTPEND); + + req = __raw_readl(S3C2410_EINTPEND); + req &= ~mask; + + /* not sure if we should be acking the parent irq... */ + + if (irqno <= IRQ_EINT7 ) { + if ((req & 0xf0) == 0) + s3c_irq_ack(IRQ_EINT4t7); + } else { + if ((req >> 8) == 0) + s3c_irq_ack(IRQ_EINT8t23); + } +} + +static void +s3c_irqext_unmask(unsigned int irqno) +{ + unsigned long mask; + + irqno -= EXTINT_OFF; + + mask = __raw_readl(S3C2410_EINTMASK); + mask &= ~( 1UL << irqno); + __raw_writel(mask, S3C2410_EINTMASK); + + s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); +} + +static int +s3c_irqext_type(unsigned int irq, unsigned int type) +{ + void __iomem *extint_reg; + void __iomem *gpcon_reg; + unsigned long gpcon_offset, extint_offset; + unsigned long newvalue = 0, value; + + if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3)) + { + gpcon_reg = S3C2410_GPFCON; + extint_reg = S3C2410_EXTINT0; + gpcon_offset = (irq - IRQ_EINT0) * 2; + extint_offset = (irq - IRQ_EINT0) * 4; + } + else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7)) + { + gpcon_reg = S3C2410_GPFCON; + extint_reg = S3C2410_EXTINT0; + gpcon_offset = (irq - (EXTINT_OFF)) * 2; + extint_offset = (irq - (EXTINT_OFF)) * 4; + } + else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15)) + { + gpcon_reg = S3C2410_GPGCON; + extint_reg = S3C2410_EXTINT1; + gpcon_offset = (irq - IRQ_EINT8) * 2; + extint_offset = (irq - IRQ_EINT8) * 4; + } + else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23)) + { + gpcon_reg = S3C2410_GPGCON; + extint_reg = S3C2410_EXTINT2; + gpcon_offset = (irq - IRQ_EINT8) * 2; + extint_offset = (irq - IRQ_EINT16) * 4; + } else + return -1; + + /* Set the GPIO to external interrupt mode */ + value = __raw_readl(gpcon_reg); + value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset); + __raw_writel(value, gpcon_reg); + + /* Set the external interrupt to pointed trigger type */ + switch (type) + { + case IRQT_NOEDGE: + printk(KERN_WARNING "No edge setting!\n"); + break; + + case IRQT_RISING: + newvalue = S3C2410_EXTINT_RISEEDGE; + break; + + case IRQT_FALLING: + newvalue = S3C2410_EXTINT_FALLEDGE; + break; + + case IRQT_BOTHEDGE: + newvalue = S3C2410_EXTINT_BOTHEDGE; + break; + + case IRQT_LOW: + newvalue = S3C2410_EXTINT_LOWLEV; + break; + + case IRQT_HIGH: + newvalue = S3C2410_EXTINT_HILEV; + break; + + default: + printk(KERN_ERR "No such irq type %d", type); + return -1; + } + + value = __raw_readl(extint_reg); + value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset); + __raw_writel(value, extint_reg); + + return 0; +} + +static struct irqchip s3c_irqext_chip = { + .mask = s3c_irqext_mask, + .unmask = s3c_irqext_unmask, + .ack = s3c_irqext_ack, + .type = s3c_irqext_type, + .wake = s3c_irqext_wake +}; + +static struct irqchip s3c_irq_eint0t4 = { + .ack = s3c_irq_ack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .wake = s3c_irq_wake, + .type = s3c_irqext_type, +}; + +/* mask values for the parent registers for each of the interrupt types */ + +#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0)) +#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) +#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) +#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) +#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) + +static inline void +s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, + int subcheck) +{ + unsigned long mask; + unsigned long submask; + + submask = __raw_readl(S3C2410_INTSUBMSK); + mask = __raw_readl(S3C2410_INTMSK); + + submask |= (1UL << (irqno - IRQ_S3CUART_RX0)); + + /* check to see if we need to mask the parent IRQ */ + + if ((submask & subcheck) == subcheck) { + __raw_writel(mask | parentbit, S3C2410_INTMSK); + } + + /* write back masks */ + __raw_writel(submask, S3C2410_INTSUBMSK); + +} + +static inline void +s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit) +{ + unsigned long mask; + unsigned long submask; + + submask = __raw_readl(S3C2410_INTSUBMSK); + mask = __raw_readl(S3C2410_INTMSK); + + submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0)); + mask &= ~parentbit; + + /* write back masks */ + __raw_writel(submask, S3C2410_INTSUBMSK); + __raw_writel(mask, S3C2410_INTMSK); +} + + +static inline void +s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group) +{ + unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); + + s3c_irqsub_mask(irqno, parentmask, group); + + __raw_writel(bit, S3C2410_SUBSRCPND); + + /* only ack parent if we've got all the irqs (seems we must + * ack, all and hope that the irq system retriggers ok when + * the interrupt goes off again) + */ + + if (1) { + __raw_writel(parentmask, S3C2410_SRCPND); + __raw_writel(parentmask, S3C2410_INTPND); + } +} + +static inline void +s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group) +{ + unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0); + + __raw_writel(bit, S3C2410_SUBSRCPND); + + /* only ack parent if we've got all the irqs (seems we must + * ack, all and hope that the irq system retriggers ok when + * the interrupt goes off again) + */ + + if (1) { + __raw_writel(parentmask, S3C2410_SRCPND); + __raw_writel(parentmask, S3C2410_INTPND); + } +} + +/* UART0 */ + +static void +s3c_irq_uart0_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_UART0, 7); +} + +static void +s3c_irq_uart0_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_UART0); +} + +static void +s3c_irq_uart0_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_UART0, 7); +} + +static struct irqchip s3c_irq_uart0 = { + .mask = s3c_irq_uart0_mask, + .unmask = s3c_irq_uart0_unmask, + .ack = s3c_irq_uart0_ack, +}; + +/* UART1 */ + +static void +s3c_irq_uart1_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3); +} + +static void +s3c_irq_uart1_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_UART1); +} + +static void +s3c_irq_uart1_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3); +} + +static struct irqchip s3c_irq_uart1 = { + .mask = s3c_irq_uart1_mask, + .unmask = s3c_irq_uart1_unmask, + .ack = s3c_irq_uart1_ack, +}; + +/* UART2 */ + +static void +s3c_irq_uart2_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6); +} + +static void +s3c_irq_uart2_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_UART2); +} + +static void +s3c_irq_uart2_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6); +} + +static struct irqchip s3c_irq_uart2 = { + .mask = s3c_irq_uart2_mask, + .unmask = s3c_irq_uart2_unmask, + .ack = s3c_irq_uart2_ack, +}; + +/* ADC and Touchscreen */ + +static void +s3c_irq_adc_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9); +} + +static void +s3c_irq_adc_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT); +} + +static void +s3c_irq_adc_ack(unsigned int irqno) +{ + s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9); +} + +static struct irqchip s3c_irq_adc = { + .mask = s3c_irq_adc_mask, + .unmask = s3c_irq_adc_unmask, + .ack = s3c_irq_adc_ack, +}; + +/* irq demux for adc */ +static void s3c_irq_demux_adc(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int subsrc, submsk; + unsigned int offset = 9; + struct irqdesc *mydesc; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + subsrc >>= offset; + subsrc &= 3; + + if (subsrc != 0) { + if (subsrc & 1) { + mydesc = irq_desc + IRQ_TC; + mydesc->handle( IRQ_TC, mydesc, regs); + } + if (subsrc & 2) { + mydesc = irq_desc + IRQ_ADC; + mydesc->handle(IRQ_ADC, mydesc, regs); + } + } +} + +static void s3c_irq_demux_uart(unsigned int start, + struct pt_regs *regs) +{ + unsigned int subsrc, submsk; + unsigned int offset = start - IRQ_S3CUART_RX0; + struct irqdesc *desc; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n", + start, offset, subsrc, submsk); + + subsrc &= ~submsk; + subsrc >>= offset; + subsrc &= 7; + + if (subsrc != 0) { + desc = irq_desc + start; + + if (subsrc & 1) + desc->handle(start, desc, regs); + + desc++; + + if (subsrc & 2) + desc->handle(start+1, desc, regs); + + desc++; + + if (subsrc & 4) + desc->handle(start+2, desc, regs); + } +} + +/* uart demux entry points */ + +static void +s3c_irq_demux_uart0(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + irq = irq; + s3c_irq_demux_uart(IRQ_S3CUART_RX0, regs); +} + +static void +s3c_irq_demux_uart1(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + irq = irq; + s3c_irq_demux_uart(IRQ_S3CUART_RX1, regs); +} + +static void +s3c_irq_demux_uart2(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + irq = irq; + s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs); +} + + +/* s3c24xx_init_irq + * + * Initialise S3C2410 IRQ system +*/ + +void __init s3c24xx_init_irq(void) +{ + unsigned long pend; + unsigned long last; + int irqno; + int i; + + irqdbf("s3c2410_init_irq: clearing interrupt status flags\n"); + + /* first, clear all interrupts pending... */ + + last = 0; + for (i = 0; i < 4; i++) { + pend = __raw_readl(S3C2410_EINTPEND); + + if (pend == 0 || pend == last) + break; + + __raw_writel(pend, S3C2410_EINTPEND); + printk("irq: clearing pending ext status %08x\n", (int)pend); + last = pend; + } + + last = 0; + for (i = 0; i < 4; i++) { + pend = __raw_readl(S3C2410_INTPND); + + if (pend == 0 || pend == last) + break; + + __raw_writel(pend, S3C2410_SRCPND); + __raw_writel(pend, S3C2410_INTPND); + printk("irq: clearing pending status %08x\n", (int)pend); + last = pend; + } + + last = 0; + for (i = 0; i < 4; i++) { + pend = __raw_readl(S3C2410_SUBSRCPND); + + if (pend == 0 || pend == last) + break; + + printk("irq: clearing subpending status %08x\n", (int)pend); + __raw_writel(pend, S3C2410_SUBSRCPND); + last = pend; + } + + /* register the main interrupts */ + + irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n"); + + for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) { + /* set all the s3c2410 internal irqs */ + + switch (irqno) { + /* deal with the special IRQs (cascaded) */ + + case IRQ_UART0: + case IRQ_UART1: + case IRQ_UART2: + case IRQ_LCD: + case IRQ_ADCPARENT: + set_irq_chip(irqno, &s3c_irq_level_chip); + set_irq_handler(irqno, do_level_IRQ); + break; + + case IRQ_RESERVED6: + case IRQ_RESERVED24: + /* no IRQ here */ + break; + + default: + //irqdbf("registering irq %d (s3c irq)\n", irqno); + set_irq_chip(irqno, &s3c_irq_chip); + set_irq_handler(irqno, do_edge_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + } + + /* setup the cascade irq handlers */ + + set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); + set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); + set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); + set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); + + + /* external interrupts */ + + for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { + irqdbf("registering irq %d (ext int)\n", irqno); + set_irq_chip(irqno, &s3c_irq_eint0t4); + set_irq_handler(irqno, do_edge_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) { + irqdbf("registering irq %d (extended s3c irq)\n", irqno); + set_irq_chip(irqno, &s3c_irqext_chip); + set_irq_handler(irqno, do_edge_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + /* register the uart interrupts */ + + irqdbf("s3c2410: registering external interrupts\n"); + + for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) { + irqdbf("registering irq %d (s3c uart0 irq)\n", irqno); + set_irq_chip(irqno, &s3c_irq_uart0); + set_irq_handler(irqno, do_level_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) { + irqdbf("registering irq %d (s3c uart1 irq)\n", irqno); + set_irq_chip(irqno, &s3c_irq_uart1); + set_irq_handler(irqno, do_level_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) { + irqdbf("registering irq %d (s3c uart2 irq)\n", irqno); + set_irq_chip(irqno, &s3c_irq_uart2); + set_irq_handler(irqno, do_level_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) { + irqdbf("registering irq %d (s3c adc irq)\n", irqno); + set_irq_chip(irqno, &s3c_irq_adc); + set_irq_handler(irqno, do_edge_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + irqdbf("s3c2410: registered interrupt handlers\n"); +} + +/* s3c2440 irq code +*/ + +#ifdef CONFIG_CPU_S3C2440 + +/* WDT/AC97 */ + +static void s3c_irq_demux_wdtac97(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int subsrc, submsk; + struct irqdesc *mydesc; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + subsrc >>= 13; + subsrc &= 3; + + if (subsrc != 0) { + if (subsrc & 1) { + mydesc = irq_desc + IRQ_S3C2440_WDT; + mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); + } + if (subsrc & 2) { + mydesc = irq_desc + IRQ_S3C2440_AC97; + mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); + } + } +} + + +#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0)) + +static void +s3c_irq_wdtac97_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13); +} + +static void +s3c_irq_wdtac97_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_WDT); +} + +static void +s3c_irq_wdtac97_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13); +} + +static struct irqchip s3c_irq_wdtac97 = { + .mask = s3c_irq_wdtac97_mask, + .unmask = s3c_irq_wdtac97_unmask, + .ack = s3c_irq_wdtac97_ack, +}; + +/* camera irq */ + +static void s3c_irq_demux_cam(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int subsrc, submsk; + struct irqdesc *mydesc; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + subsrc >>= 11; + subsrc &= 3; + + if (subsrc != 0) { + if (subsrc & 1) { + mydesc = irq_desc + IRQ_S3C2440_CAM_C; + mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); + } + if (subsrc & 2) { + mydesc = irq_desc + IRQ_S3C2440_CAM_P; + mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); + } + } +} + +#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) + +static void +s3c_irq_cam_mask(unsigned int irqno) +{ + s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11); +} + +static void +s3c_irq_cam_unmask(unsigned int irqno) +{ + s3c_irqsub_unmask(irqno, INTMSK_CAM); +} + +static void +s3c_irq_cam_ack(unsigned int irqno) +{ + s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11); +} + +static struct irqchip s3c_irq_cam = { + .mask = s3c_irq_cam_mask, + .unmask = s3c_irq_cam_unmask, + .ack = s3c_irq_cam_ack, +}; + +static int s3c2440_irq_add(struct sys_device *sysdev) +{ + unsigned int irqno; + + printk("S3C2440: IRQ Support\n"); + + set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip); + set_irq_handler(IRQ_NFCON, do_level_IRQ); + set_irq_flags(IRQ_NFCON, IRQF_VALID); + + /* add new chained handler for wdt, ac7 */ + + set_irq_chip(IRQ_WDT, &s3c_irq_level_chip); + set_irq_handler(IRQ_WDT, do_level_IRQ); + set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); + + for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) { + set_irq_chip(irqno, &s3c_irq_wdtac97); + set_irq_handler(irqno, do_level_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + /* add chained handler for camera */ + + set_irq_chip(IRQ_CAM, &s3c_irq_level_chip); + set_irq_handler(IRQ_CAM, do_level_IRQ); + set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam); + + for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { + set_irq_chip(irqno, &s3c_irq_cam); + set_irq_handler(irqno, do_level_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } + + return 0; +} + +static struct sysdev_driver s3c2440_irq_driver = { + .add = s3c2440_irq_add, +}; + +static int s3c24xx_irq_driver(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver); +} + +arch_initcall(s3c24xx_irq_driver); + +#endif /* CONFIG_CPU_S3C2440 */ + diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c new file mode 100644 index 0000000..3bb97eb --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -0,0 +1,409 @@ +/* linux/arch/arm/mach-s3c2410/mach-bast.c + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * 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. + * + * Modifications: + * 14-Sep-2004 BJD USB power control + * 20-Aug-2004 BJD Added s3c2410_board struct + * 18-Aug-2004 BJD Added platform devices from default set + * 16-May-2003 BJD Created initial version + * 16-Aug-2003 BJD Fixed header files and copyright, added URL + * 05-Sep-2003 BJD Moved to v2.6 kernel + * 06-Jan-2003 BJD Updates for <arch/map.h> + * 18-Jan-2003 BJD Added serial port configuration + * 05-Oct-2004 BJD Power management code + * 04-Nov-2004 BJD Updated serial port clocks + * 04-Jan-2005 BJD New uart init call + * 10-Jan-2005 BJD Removed include of s3c2410.h + * 14-Jan-2005 BJD Add support for muitlple NAND devices + * 03-Mar-2005 BJD Ensured that bast-cpld.h is included + * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA + * 14-Mar-2006 BJD Updated for __iomem changes +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/arch/bast-map.h> +#include <asm/arch/bast-irq.h> +#include <asm/arch/bast-cpld.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +//#include <asm/debug-ll.h> +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-mem.h> +#include <asm/arch/nand.h> + +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/nand_ecc.h> +#include <linux/mtd/partitions.h> + +#include "clock.h" +#include "devs.h" +#include "cpu.h" +#include "usb-simtec.h" +#include "pm.h" + +#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics" + +/* macros for virtual address mods for the io space entries */ +#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5) +#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4) +#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3) +#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2) + +/* macros to modify the physical addresses for io space */ + +#define PA_CS2(item) ((item) + S3C2410_CS2) +#define PA_CS3(item) ((item) + S3C2410_CS3) +#define PA_CS4(item) ((item) + S3C2410_CS4) +#define PA_CS5(item) ((item) + S3C2410_CS5) + +static struct map_desc bast_iodesc[] __initdata = { + /* ISA IO areas */ + + { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + + /* we could possibly compress the next set down into a set of smaller tables + * pagetables, but that would mean using an L2 section, and it still means + * we cannot actually feed the same register to an LDR due to 16K spacing + */ + + /* bast CPLD control registers, and external interrupt controls */ + { (u32)BAST_VA_CTRL1, BAST_PA_CTRL1, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_CTRL2, BAST_PA_CTRL2, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_CTRL3, BAST_PA_CTRL3, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_CTRL4, BAST_PA_CTRL4, SZ_1M, MT_DEVICE }, + + /* PC104 IRQ mux */ + { (u32)BAST_VA_PC104_IRQREQ, BAST_PA_PC104_IRQREQ, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_PC104_IRQRAW, BAST_PA_PC104_IRQRAW, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_PC104_IRQMASK, BAST_PA_PC104_IRQMASK, SZ_1M, MT_DEVICE }, + + /* peripheral space... one for each of fast/slow/byte/16bit */ + /* note, ide is only decoded in word space, even though some registers + * are only 8bit */ + + /* slow, byte */ + { VA_C2(BAST_VA_ISAIO), PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, + { VA_C2(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, + { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, + { VA_C2(BAST_VA_DM9000), PA_CS2(BAST_PA_DM9000), SZ_1M, MT_DEVICE }, + { VA_C2(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, + { VA_C2(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, + { VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, + { VA_C2(BAST_VA_IDESECAUX), PA_CS3(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE }, + + /* slow, word */ + { VA_C3(BAST_VA_ISAIO), PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, + { VA_C3(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, + { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, + { VA_C3(BAST_VA_DM9000), PA_CS3(BAST_PA_DM9000), SZ_1M, MT_DEVICE }, + { VA_C3(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, + { VA_C3(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, + { VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, + { VA_C3(BAST_VA_IDESECAUX), PA_CS3(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE }, + + /* fast, byte */ + { VA_C4(BAST_VA_ISAIO), PA_CS4(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, + { VA_C4(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, + { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, + { VA_C4(BAST_VA_DM9000), PA_CS4(BAST_PA_DM9000), SZ_1M, MT_DEVICE }, + { VA_C4(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, + { VA_C4(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, + { VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, + { VA_C4(BAST_VA_IDESECAUX), PA_CS5(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE }, + + /* fast, word */ + { VA_C5(BAST_VA_ISAIO), PA_CS5(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, + { VA_C5(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, + { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, + { VA_C5(BAST_VA_DM9000), PA_CS5(BAST_PA_DM9000), SZ_1M, MT_DEVICE }, + { VA_C5(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, + { VA_C5(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, + { VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, + { VA_C5(BAST_VA_IDESECAUX), PA_CS5(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE }, +}; + +#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c24xx_uart_clksrc bast_serial_clocks[] = { + [0] = { + .name = "uclk", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, + [1] = { + .name = "pclk", + .divisor = 1, + .min_baud = 0, + .max_baud = 0. + } +}; + + +static struct s3c2410_uartcfg bast_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = bast_serial_clocks, + .clocks_size = ARRAY_SIZE(bast_serial_clocks) + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = bast_serial_clocks, + .clocks_size = ARRAY_SIZE(bast_serial_clocks) + }, + /* port 2 is not actually used */ + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = bast_serial_clocks, + .clocks_size = ARRAY_SIZE(bast_serial_clocks) + } +}; + +/* NOR Flash on BAST board */ + +static struct resource bast_nor_resource[] = { + [0] = { + .start = S3C2410_CS1 + 0x4000000, + .end = S3C2410_CS1 + 0x4000000 + (32*1024*1024) - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device bast_device_nor = { + .name = "bast-nor", + .id = -1, + .num_resources = ARRAY_SIZE(bast_nor_resource), + .resource = bast_nor_resource, +}; + +/* NAND Flash on BAST board */ + + +static int smartmedia_map[] = { 0 }; +static int chip0_map[] = { 1 }; +static int chip1_map[] = { 2 }; +static int chip2_map[] = { 3 }; + +struct mtd_partition bast_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_16K, + .offset = 0 + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_16K, + .offset = SZ_16K, + }, + [2] = { + .name = "user", + .offset = SZ_4M, + .size = MTDPART_SIZ_FULL, + } +}; + +/* the bast has 4 selectable slots for nand-flash, the three + * on-board chip areas, as well as the external SmartMedia + * slot. + * + * Note, there is no current hot-plug support for the SmartMedia + * socket. +*/ + +static struct s3c2410_nand_set bast_nand_sets[] = { + [0] = { + .name = "SmartMedia", + .nr_chips = 1, + .nr_map = smartmedia_map, + .nr_partitions = ARRAY_SIZE(bast_default_nand_part), + .partitions = bast_default_nand_part + }, + [1] = { + .name = "chip0", + .nr_chips = 1, + .nr_map = chip0_map, + .nr_partitions = ARRAY_SIZE(bast_default_nand_part), + .partitions = bast_default_nand_part + }, + [2] = { + .name = "chip1", + .nr_chips = 1, + .nr_map = chip1_map, + .nr_partitions = ARRAY_SIZE(bast_default_nand_part), + .partitions = bast_default_nand_part + }, + [3] = { + .name = "chip2", + .nr_chips = 1, + .nr_map = chip2_map, + .nr_partitions = ARRAY_SIZE(bast_default_nand_part), + .partitions = bast_default_nand_part + } +}; + +static void bast_nand_select(struct s3c2410_nand_set *set, int slot) +{ + unsigned int tmp; + + slot = set->nr_map[slot] & 3; + + pr_debug("bast_nand: selecting slot %d (set %p,%p)\n", + slot, set, set->nr_map); + + tmp = __raw_readb(BAST_VA_CTRL2); + tmp &= BAST_CPLD_CTLR2_IDERST; + tmp |= slot; + tmp |= BAST_CPLD_CTRL2_WNAND; + + pr_debug("bast_nand: ctrl2 now %02x\n", tmp); + + __raw_writeb(tmp, BAST_VA_CTRL2); +} + +static struct s3c2410_platform_nand bast_nand_info = { + .tacls = 80, + .twrph0 = 80, + .twrph1 = 80, + .nr_sets = ARRAY_SIZE(bast_nand_sets), + .sets = bast_nand_sets, + .select_chip = bast_nand_select, +}; + + +/* Standard BAST devices */ + +static struct platform_device *bast_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, + &s3c_device_rtc, + &s3c_device_nand, + &bast_device_nor +}; + +static struct clk *bast_clocks[] = { + &s3c24xx_dclk0, + &s3c24xx_dclk1, + &s3c24xx_clkout0, + &s3c24xx_clkout1, + &s3c24xx_uclk, +}; + +static struct s3c24xx_board bast_board __initdata = { + .devices = bast_devices, + .devices_count = ARRAY_SIZE(bast_devices), + .clocks = bast_clocks, + .clocks_count = ARRAY_SIZE(bast_clocks) +}; + +void __init bast_map_io(void) +{ + /* initialise the clocks */ + + s3c24xx_dclk0.parent = NULL; + s3c24xx_dclk0.rate = 12*1000*1000; + + s3c24xx_dclk1.parent = NULL; + s3c24xx_dclk1.rate = 24*1000*1000; + + s3c24xx_clkout0.parent = &s3c24xx_dclk0; + s3c24xx_clkout1.parent = &s3c24xx_dclk1; + + s3c24xx_uclk.parent = &s3c24xx_clkout1; + + s3c_device_nand.dev.platform_data = &bast_nand_info; + + s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); + s3c24xx_set_board(&bast_board); + usb_simtec_init(); +} + +void __init bast_init_irq(void) +{ + s3c24xx_init_irq(); +} + +#ifdef CONFIG_PM + +/* bast_init_machine + * + * enable the power management functions for the EB2410ITX +*/ + +static __init void bast_init_machine(void) +{ + unsigned long gstatus4; + + printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n"); + + gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; + gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; + gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); + + __raw_writel(gstatus4, S3C2410_GSTATUS4); + + s3c2410_pm_init(); +} + +#else +#define bast_init_machine NULL +#endif + + +MACHINE_START(BAST, "Simtec-BAST") + MAINTAINER("Ben Dooks <ben@simtec.co.uk>") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + MAPIO(bast_map_io) + INITIRQ(bast_init_irq) + .init_machine = bast_init_machine, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c new file mode 100644 index 0000000..2924afc --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -0,0 +1,126 @@ +/* linux/arch/arm/mach-s3c2410/mach-h1940.c + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.handhelds.org/projects/h1940.html + * + * 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. + * + * Modifications: + * 16-May-2003 BJD Created initial version + * 16-Aug-2003 BJD Fixed header files and copyright, added URL + * 05-Sep-2003 BJD Moved to v2.6 kernel + * 06-Jan-2003 BJD Updates for <arch/map.h> + * 18-Jan-2003 BJD Added serial port configuration + * 17-Feb-2003 BJD Copied to mach-ipaq.c + * 21-Aug-2004 BJD Added struct s3c2410_board + * 04-Sep-2004 BJD Changed uart init, renamed ipaq_ -> h1940_ + * 18-Oct-2004 BJD Updated new board structure name + * 04-Nov-2004 BJD Change for new serial clock + * 04-Jan-2005 BJD Updated uart init call + * 10-Jan-2005 BJD Removed include of s3c2410.h + * 14-Jan-2005 BJD Added clock init + * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/hardware/iomd.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +//#include <asm/debug-ll.h> +#include <asm/arch/regs-serial.h> + +#include <linux/serial_core.h> + +#include "clock.h" +#include "devs.h" +#include "cpu.h" + +static struct map_desc h1940_iodesc[] __initdata = { + /* nothing here yet */ +}; + +#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg h1940_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = 0x245, + .ulcon = 0x03, + .ufcon = 0x00, + }, + /* IR port */ + [2] = { + .hwport = 2, + .flags = 0, + .uart_flags = UPF_CONS_FLOW, + .ucon = 0x3c5, + .ulcon = 0x43, + .ufcon = 0x51, + } +}; + + + + +static struct platform_device *h1940_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, +}; + +static struct s3c24xx_board h1940_board __initdata = { + .devices = h1940_devices, + .devices_count = ARRAY_SIZE(h1940_devices) +}; + +void __init h1940_map_io(void) +{ + s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs)); + s3c24xx_set_board(&h1940_board); +} + +void __init h1940_init_irq(void) +{ + s3c24xx_init_irq(); + +} + +MACHINE_START(H1940, "IPAQ-H1940") + MAINTAINER("Ben Dooks <ben@fluff.org>") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + MAPIO(h1940_map_io) + INITIRQ(h1940_init_irq) + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c new file mode 100644 index 0000000..bd15998 --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -0,0 +1,155 @@ +/* linux/arch/arm/mach-s3c2410/mach-n30.c + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Copyright (c) 2005 Christer Weinigel <christer@weinigel.se> + * + * There is a wiki with more information about the n30 port at + * http://handhelds.org/moin/moin.cgi/AcerN30Documentation . + * + * 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/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/kthread.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/hardware/iomd.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/iic.h> + +#include <linux/serial_core.h> + +#include "s3c2410.h" +#include "clock.h" +#include "devs.h" +#include "cpu.h" + +static struct map_desc n30_iodesc[] __initdata = { + /* nothing here yet */ +}; + +static struct s3c2410_uartcfg n30_uartcfgs[] = { + /* Normal serial port */ + [0] = { + .hwport = 0, + .flags = 0, + .ucon = 0x2c5, + .ulcon = 0x03, + .ufcon = 0x51, + }, + /* IR port */ + [1] = { + .hwport = 1, + .flags = 0, + .uart_flags = UPF_CONS_FLOW, + .ucon = 0x2c5, + .ulcon = 0x43, + .ufcon = 0x51, + }, + /* The BlueTooth controller is connected to port 2 */ + [2] = { + .hwport = 2, + .flags = 0, + .ucon = 0x2c5, + .ulcon = 0x03, + .ufcon = 0x51, + }, +}; + +static struct platform_device *n30_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, + &s3c_device_usbgadget, +}; + +static struct s3c2410_platform_i2c n30_i2ccfg = { + .flags = 0, + .slave_addr = 0x10, + .bus_freq = 10*1000, + .max_freq = 10*1000, +}; + +static struct s3c24xx_board n30_board __initdata = { + .devices = n30_devices, + .devices_count = ARRAY_SIZE(n30_devices) +}; + +void __init n30_map_io(void) +{ + s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs)); + s3c24xx_set_board(&n30_board); +} + +void __init n30_init_irq(void) +{ + s3c24xx_init_irq(); +} + + +static int n30_usbstart_thread(void *unused) +{ + /* Turn off suspend on both USB ports, and switch the + * selectable USB port to USB device mode. */ + writel(readl(S3C2410_MISCCR) & ~0x00003008, S3C2410_MISCCR); + + /* Turn off the D+ pull up for 3 seconds so that the USB host + * at the other end will do a rescan of the USB bus. */ + s3c2410_gpio_setpin(S3C2410_GPB3, 0); + + msleep_interruptible(3*HZ); + + s3c2410_gpio_setpin(S3C2410_GPB3, 1); + + return 0; +} + + +void __init n30_init(void) +{ + s3c_device_i2c.dev.platform_data = &n30_i2ccfg; + + kthread_run(n30_usbstart_thread, NULL, "n30_usbstart"); +} + +MACHINE_START(N30, "Acer-N30") + MAINTAINER("Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org>") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + + .timer = &s3c24xx_timer, + .init_machine = n30_init, + .init_irq = n30_init_irq, + .map_io = n30_map_io, +MACHINE_END + +/* + Local variables: + compile-command: "make ARCH=arm CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux- -k -C ../../.." + c-basic-offset: 8 + End: +*/ diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c new file mode 100644 index 0000000..70487bf --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-nexcoder.c @@ -0,0 +1,156 @@ +/* linux/arch/arm/mach-s3c2410/mach-nexcoder.c + * + * Copyright (c) 2004 Nex Vision + * Guillaume GOURAT <guillaume.gourat@nexvision.tv> + * + * 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. + * + * Modifications: + * 15-10-2004 GG Created initial version + * 12-03-2005 BJD Updated for release + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/string.h> +#include <linux/device.h> + +#include <linux/mtd/map.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/setup.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +//#include <asm/debug-ll.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-serial.h> + +#include "s3c2410.h" +#include "s3c2440.h" +#include "clock.h" +#include "devs.h" +#include "cpu.h" + +static struct map_desc nexcoder_iodesc[] __initdata = { + /* nothing here yet */ +}; + +#define UCON S3C2410_UCON_DEFAULT +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg nexcoder_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + } +}; + +/* NOR Flash on NexVision NexCoder 2440 board */ + +static struct resource nexcoder_nor_resource[] = { + [0] = { + .start = S3C2410_CS0, + .end = S3C2410_CS0 + (8*1024*1024) - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct map_info nexcoder_nor_map = { + .bankwidth = 2, +}; + +static struct platform_device nexcoder_device_nor = { + .name = "mtd-flash", + .id = -1, + .num_resources = ARRAY_SIZE(nexcoder_nor_resource), + .resource = nexcoder_nor_resource, + .dev = + { + .platform_data = &nexcoder_nor_map, + } +}; + +/* Standard Nexcoder devices */ + +static struct platform_device *nexcoder_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, + &s3c_device_rtc, + &s3c_device_camif, + &s3c_device_spi0, + &s3c_device_spi1, + &nexcoder_device_nor, +}; + +static struct s3c24xx_board nexcoder_board __initdata = { + .devices = nexcoder_devices, + .devices_count = ARRAY_SIZE(nexcoder_devices), +}; + + +static void __init nexcoder_sensorboard_init(void) +{ + // Initialize SCCB bus + s3c2410_gpio_setpin(S3C2410_GPE14, 1); // IICSCL + s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_OUTP); + s3c2410_gpio_setpin(S3C2410_GPE15, 1); // IICSDA + s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_OUTP); + + // Power up the sensor board + s3c2410_gpio_setpin(S3C2410_GPF1, 1); + s3c2410_gpio_cfgpin(S3C2410_GPF1, S3C2410_GPF1_OUTP); // CAM_GPIO7 => nLDO_PWRDN + s3c2410_gpio_setpin(S3C2410_GPF2, 0); + s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); // CAM_GPIO6 => CAM_PWRDN +} + +void __init nexcoder_map_io(void) +{ + s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs)); + s3c24xx_set_board(&nexcoder_board); + nexcoder_sensorboard_init(); +} + + +MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") + MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + .map_io = nexcoder_map_io, + .init_irq = s3c24xx_init_irq, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c new file mode 100644 index 0000000..67d8ce8 --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-otom.c @@ -0,0 +1,124 @@ +/* linux/arch/arm/mach-s3c2410/mach-otom.c + * + * Copyright (c) 2004 Nex Vision + * Guillaume GOURAT <guillaume.gourat@nexvision.fr> + * + * 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/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/arch/otom-map.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> + +#include "s3c2410.h" +#include "clock.h" +#include "devs.h" +#include "cpu.h" + +static struct map_desc otom11_iodesc[] __initdata = { + /* Device area */ + { (u32)OTOM_VA_CS8900A_BASE, OTOM_PA_CS8900A_BASE, SZ_16M, MT_DEVICE }, +}; + +#define UCON S3C2410_UCON_DEFAULT +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg otom11_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + /* port 2 is not actually used */ + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + } +}; + +/* NOR Flash on NexVision OTOM board */ + +static struct resource otom_nor_resource[] = { + [0] = { + .start = S3C2410_CS0, + .end = S3C2410_CS0 + (4*1024*1024) - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device otom_device_nor = { + .name = "mtd-flash", + .id = -1, + .num_resources = ARRAY_SIZE(otom_nor_resource), + .resource = otom_nor_resource, +}; + +/* Standard OTOM devices */ + +static struct platform_device *otom11_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, + &s3c_device_rtc, + &otom_device_nor, +}; + +static struct s3c24xx_board otom11_board __initdata = { + .devices = otom11_devices, + .devices_count = ARRAY_SIZE(otom11_devices) +}; + + +void __init otom11_map_io(void) +{ + s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs)); + s3c24xx_set_board(&otom11_board); +} + + +MACHINE_START(OTOM, "Nex Vision - Otom 1.1") + MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + .map_io = otom11_map_io, + .init_irq = s3c24xx_init_irq, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c new file mode 100644 index 0000000..f8d3a97 --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-rx3715.c @@ -0,0 +1,141 @@ +/* linux/arch/arm/mach-s3c2410/mach-rx3715.c + * + * Copyright (c) 2003,2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.handhelds.org/projects/rx3715.html + * + * 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. + * + * Modifications: + * 16-Sep-2004 BJD Copied from mach-h1940.c + * 25-Oct-2004 BJD Updates for 2.6.10-rc1 + * 10-Jan-2005 BJD Removed include of s3c2410.h s3c2440.h + * 14-Jan-2005 BJD Added new clock init + * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA + * 14-Mar-2005 BJD Fixed __iomem warnings +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/tty.h> +#include <linux/console.h> +#include <linux/serial_core.h> +#include <linux/serial.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/hardware/iomd.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> + +#include "clock.h" +#include "devs.h" +#include "cpu.h" +#include "pm.h" + +static struct map_desc rx3715_iodesc[] __initdata = { + /* dump ISA space somewhere unused */ + + { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE }, +}; + + +static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = { + [0] = { + .name = "fclk", + .divisor = 0, + .min_baud = 0, + .max_baud = 0, + } +}; + +static struct s3c2410_uartcfg rx3715_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + .clocks = rx3715_serial_clocks, + .clocks_size = ARRAY_SIZE(rx3715_serial_clocks), + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x00, + .clocks = rx3715_serial_clocks, + .clocks_size = ARRAY_SIZE(rx3715_serial_clocks), + }, + /* IR port */ + [2] = { + .hwport = 2, + .uart_flags = UPF_CONS_FLOW, + .ucon = 0x3c5, + .ulcon = 0x43, + .ufcon = 0x51, + .clocks = rx3715_serial_clocks, + .clocks_size = ARRAY_SIZE(rx3715_serial_clocks), + } +}; + +static struct platform_device *rx3715_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, +}; + +static struct s3c24xx_board rx3715_board __initdata = { + .devices = rx3715_devices, + .devices_count = ARRAY_SIZE(rx3715_devices) +}; + +void __init rx3715_map_io(void) +{ + s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); + s3c24xx_init_clocks(16934000); + s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); + s3c24xx_set_board(&rx3715_board); +} + +void __init rx3715_init_irq(void) +{ + s3c24xx_init_irq(); +} + +#ifdef CONFIG_PM +static void __init rx3715_init_machine(void) +{ + s3c2410_pm_init(); +} +#else +#define rx3715_init_machine NULL +#endif + +MACHINE_START(RX3715, "IPAQ-RX3715") + MAINTAINER("Ben Dooks <ben@fluff.org>") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + MAPIO(rx3715_map_io) + INITIRQ(rx3715_init_irq) + INIT_MACHINE(rx3715_init_machine) + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c new file mode 100644 index 0000000..c1a4a14 --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -0,0 +1,123 @@ +/*********************************************************************** + * + * linux/arch/arm/mach-s3c2410/mach-smdk2410.c + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH + * All rights reserved. + * + * $Id: mach-smdk2410.c,v 1.1 2004/05/11 14:15:38 mpietrek Exp $ + * @Author: Jonas Dietsche + * + * 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 + * + * @History: + * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by + * Ben Dooks <ben@simtec.co.uk> + * + * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA + * + ***********************************************************************/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <asm/arch/regs-serial.h> + +#include "devs.h" +#include "cpu.h" + +static struct map_desc smdk2410_iodesc[] __initdata = { + /* nothing here yet */ +}; + +#define UCON S3C2410_UCON_DEFAULT +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg smdk2410_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + } +}; + +static struct platform_device *smdk2410_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, +}; + +static struct s3c24xx_board smdk2410_board __initdata = { + .devices = smdk2410_devices, + .devices_count = ARRAY_SIZE(smdk2410_devices) +}; + +void __init smdk2410_map_io(void) +{ + s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); + s3c24xx_set_board(&smdk2410_board); +} + +void __init smdk2410_init_irq(void) +{ + s3c24xx_init_irq(); +} + +MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch + * to SMDK2410 */ + MAINTAINER("Jonas Dietsche") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + MAPIO(smdk2410_map_io) + INITIRQ(smdk2410_init_irq) + .timer = &s3c24xx_timer, +MACHINE_END + + diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c new file mode 100644 index 0000000..7857176 --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -0,0 +1,135 @@ +/* linux/arch/arm/mach-s3c2410/mach-smdk2440.c + * + * Copyright (c) 2004,2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.fluff.org/ben/smdk2440/ + * + * Thanks to Dimity Andric and TomTom for the loan of an SMDK2440. + * + * 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. + * + * Modifications: + * 01-Nov-2004 BJD Initial version + * 12-Nov-2004 BJD Updated for release + * 04-Jan-2005 BJD Fixes for pre-release + * 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa + * 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA + * 14-Mar-2005 BJD void __iomem fixes +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/hardware/iomd.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +//#include <asm/debug-ll.h> +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/idle.h> + +#include "s3c2410.h" +#include "s3c2440.h" +#include "clock.h" +#include "devs.h" +#include "cpu.h" +#include "pm.h" + +static struct map_desc smdk2440_iodesc[] __initdata = { + /* ISA IO Space map (memory space selected by A24) */ + + { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE }, +}; + +#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg smdk2440_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + }, + /* IR port */ + [2] = { + .hwport = 2, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x43, + .ufcon = 0x51, + } +}; + +static struct platform_device *smdk2440_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, +}; + +static struct s3c24xx_board smdk2440_board __initdata = { + .devices = smdk2440_devices, + .devices_count = ARRAY_SIZE(smdk2440_devices) +}; + +void __init smdk2440_map_io(void) +{ + s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); + s3c24xx_init_clocks(16934400); + s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); + s3c24xx_set_board(&smdk2440_board); +} + +void __init smdk2440_machine_init(void) +{ + /* Configure the LEDs (even if we have no LED support)*/ + + s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP); + s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP); + s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP); + s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP); + + s3c2410_gpio_setpin(S3C2410_GPF4, 0); + s3c2410_gpio_setpin(S3C2410_GPF5, 0); + s3c2410_gpio_setpin(S3C2410_GPF6, 0); + s3c2410_gpio_setpin(S3C2410_GPF7, 0); + + s3c2410_pm_init(); +} + +MACHINE_START(S3C2440, "SMDK2440") + MAINTAINER("Ben Dooks <ben@fluff.org>") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + + .init_irq = s3c24xx_init_irq, + .map_io = smdk2440_map_io, + .init_machine = smdk2440_machine_init, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c new file mode 100644 index 0000000..5512146 --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -0,0 +1,317 @@ +/* linux/arch/arm/mach-s3c2410/mach-vr1000.c + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Machine support for Thorcom VR1000 board. Designed for Thorcom by + * Simtec Electronics, http://www.simtec.co.uk/ + * + * 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. + * + * Modifications: + * 14-Sep-2004 BJD USB Power control + * 04-Sep-2004 BJD Added new uart init, and io init + * 21-Aug-2004 BJD Added struct s3c2410_board + * 06-Aug-2004 BJD Fixed call to time initialisation + * 05-Apr-2004 BJD Copied to make mach-vr1000.c + * 18-Oct-2004 BJD Updated board struct + * 04-Nov-2004 BJD Clock and serial configuration update + * + * 04-Jan-2005 BJD Updated uart init call + * 10-Jan-2005 BJD Removed include of s3c2410.h + * 14-Jan-2005 BJD Added clock init + * 15-Jan-2005 BJD Add serial port device definition + * 20-Jan-2005 BJD Use UPF_IOREMAP for ports + * 10-Feb-2005 BJD Added power-off capability + * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA + * 14-Mar-2006 BJD void __iomem fixes +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> + +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> +#include <linux/serial_reg.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/arch/bast-map.h> +#include <asm/arch/vr1000-map.h> +#include <asm/arch/vr1000-irq.h> +#include <asm/arch/vr1000-cpld.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> + +#include "clock.h" +#include "devs.h" +#include "cpu.h" +#include "usb-simtec.h" + +/* macros for virtual address mods for the io space entries */ +#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5) +#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4) +#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3) +#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2) + +/* macros to modify the physical addresses for io space */ + +#define PA_CS2(item) ((item) + S3C2410_CS2) +#define PA_CS3(item) ((item) + S3C2410_CS3) +#define PA_CS4(item) ((item) + S3C2410_CS4) +#define PA_CS5(item) ((item) + S3C2410_CS5) + +static struct map_desc vr1000_iodesc[] __initdata = { + /* ISA IO areas */ + + { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + + /* we could possibly compress the next set down into a set of smaller tables + * pagetables, but that would mean using an L2 section, and it still means + * we cannot actually feed the same register to an LDR due to 16K spacing + */ + + /* bast CPLD control registers, and external interrupt controls */ + { (u32)VR1000_VA_CTRL1, VR1000_PA_CTRL1, SZ_1M, MT_DEVICE }, + { (u32)VR1000_VA_CTRL2, VR1000_PA_CTRL2, SZ_1M, MT_DEVICE }, + { (u32)VR1000_VA_CTRL3, VR1000_PA_CTRL3, SZ_1M, MT_DEVICE }, + { (u32)VR1000_VA_CTRL4, VR1000_PA_CTRL4, SZ_1M, MT_DEVICE }, + + /* peripheral space... one for each of fast/slow/byte/16bit */ + /* note, ide is only decoded in word space, even though some registers + * are only 8bit */ + + /* slow, byte */ + { VA_C2(VR1000_VA_DM9000), PA_CS2(VR1000_PA_DM9000), SZ_1M, MT_DEVICE }, + { VA_C2(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE }, + { VA_C2(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE }, + { VA_C2(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, + { VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, + + /* slow, word */ + { VA_C3(VR1000_VA_DM9000), PA_CS3(VR1000_PA_DM9000), SZ_1M, MT_DEVICE }, + { VA_C3(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE }, + { VA_C3(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE }, + { VA_C3(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, + { VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, + + /* fast, byte */ + { VA_C4(VR1000_VA_DM9000), PA_CS4(VR1000_PA_DM9000), SZ_1M, MT_DEVICE }, + { VA_C4(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE }, + { VA_C4(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE }, + { VA_C4(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, + { VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, + + /* fast, word */ + { VA_C5(VR1000_VA_DM9000), PA_CS5(VR1000_PA_DM9000), SZ_1M, MT_DEVICE }, + { VA_C5(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE }, + { VA_C5(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE }, + { VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, + { VA_C5(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, +}; + +#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +/* uart clock source(s) */ + +static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = { + [0] = { + .name = "uclk", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, + [1] = { + .name = "pclk", + .divisor = 1, + .min_baud = 0, + .max_baud = 0. + } +}; + +static struct s3c2410_uartcfg vr1000_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = vr1000_serial_clocks, + .clocks_size = ARRAY_SIZE(vr1000_serial_clocks), + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = vr1000_serial_clocks, + .clocks_size = ARRAY_SIZE(vr1000_serial_clocks), + }, + /* port 2 is not actually used */ + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = vr1000_serial_clocks, + .clocks_size = ARRAY_SIZE(vr1000_serial_clocks), + + } +}; + +/* definitions for the vr1000 extra 16550 serial ports */ + +#define VR1000_BAUDBASE (3692307) + +#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5)) + +static struct plat_serial8250_port serial_platform_data[] = { + [0] = { + .mapbase = VR1000_SERIAL_MAPBASE(0), + .irq = IRQ_VR1000_SERIAL + 0, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = VR1000_BAUDBASE, + }, + [1] = { + .mapbase = VR1000_SERIAL_MAPBASE(1), + .irq = IRQ_VR1000_SERIAL + 1, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = VR1000_BAUDBASE, + }, + [2] = { + .mapbase = VR1000_SERIAL_MAPBASE(2), + .irq = IRQ_VR1000_SERIAL + 2, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = VR1000_BAUDBASE, + }, + [3] = { + .mapbase = VR1000_SERIAL_MAPBASE(3), + .irq = IRQ_VR1000_SERIAL + 3, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = VR1000_BAUDBASE, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +/* MTD NOR Flash */ + +static struct resource vr1000_nor_resource[] = { + [0] = { + .start = S3C2410_CS1 + 0x4000000, + .end = S3C2410_CS1 + 0x4000000 + SZ_16M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device vr1000_nor = { + .name = "bast-nor", + .id = -1, + .num_resources = ARRAY_SIZE(vr1000_nor_resource), + .resource = vr1000_nor_resource, +}; + + +static struct platform_device *vr1000_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, + &serial_device, + &vr1000_nor, +}; + +static struct clk *vr1000_clocks[] = { + &s3c24xx_dclk0, + &s3c24xx_dclk1, + &s3c24xx_clkout0, + &s3c24xx_clkout1, + &s3c24xx_uclk, +}; + +static struct s3c24xx_board vr1000_board __initdata = { + .devices = vr1000_devices, + .devices_count = ARRAY_SIZE(vr1000_devices), + .clocks = vr1000_clocks, + .clocks_count = ARRAY_SIZE(vr1000_clocks), +}; + +static void vr1000_power_off(void) +{ + s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_OUTP); + s3c2410_gpio_setpin(S3C2410_GPB9, 1); +} + +void __init vr1000_map_io(void) +{ + /* initialise clock sources */ + + s3c24xx_dclk0.parent = NULL; + s3c24xx_dclk0.rate = 12*1000*1000; + + s3c24xx_dclk1.parent = NULL; + s3c24xx_dclk1.rate = 3692307; + + s3c24xx_clkout0.parent = &s3c24xx_dclk0; + s3c24xx_clkout1.parent = &s3c24xx_dclk1; + + s3c24xx_uclk.parent = &s3c24xx_clkout1; + + pm_power_off = vr1000_power_off; + + s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs)); + s3c24xx_set_board(&vr1000_board); + usb_simtec_init(); +} + +void __init vr1000_init_irq(void) +{ + s3c24xx_init_irq(); +} + +MACHINE_START(VR1000, "Thorcom-VR1000") + MAINTAINER("Ben Dooks <ben@simtec.co.uk>") + BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) + BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + MAPIO(vr1000_map_io) + INITIRQ(vr1000_init_irq) + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c new file mode 100644 index 0000000..13a48ee --- /dev/null +++ b/arch/arm/mach-s3c2410/pm.c @@ -0,0 +1,672 @@ +/* linux/arch/arm/mach-s3c2410/pm.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 Power Manager (Suspend-To-RAM) support + * + * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information + * + * 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 + * + * Parts based on arch/arm/mach-pxa/pm.c + * + * Thanks to Dimitry Andric for debugging + * + * Modifications: + * 10-Mar-2005 LCVR Changed S3C2410_VA_UART to S3C24XX_VA_UART +*/ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/suspend.h> +#include <linux/errno.h> +#include <linux/time.h> +#include <linux/interrupt.h> +#include <linux/crc32.h> +#include <linux/ioport.h> +#include <linux/delay.h> + +#include <asm/hardware.h> +#include <asm/io.h> + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-clock.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-mem.h> +#include <asm/arch/regs-irq.h> + +#include <asm/mach/time.h> + +#include "pm.h" + +/* for external use */ + +unsigned long s3c_pm_flags; + +/* cache functions from arch/arm/mm/proc-arm920.S */ + +extern void arm920_flush_kern_cache_all(void); + +#define PFX "s3c24xx-pm: " + +static struct sleep_save core_save[] = { + SAVE_ITEM(S3C2410_LOCKTIME), + SAVE_ITEM(S3C2410_CLKCON), + + /* we restore the timings here, with the proviso that the board + * brings the system up in an slower, or equal frequency setting + * to the original system. + * + * if we cannot guarantee this, then things are going to go very + * wrong here, as we modify the refresh and both pll settings. + */ + + SAVE_ITEM(S3C2410_BWSCON), + SAVE_ITEM(S3C2410_BANKCON0), + SAVE_ITEM(S3C2410_BANKCON1), + SAVE_ITEM(S3C2410_BANKCON2), + SAVE_ITEM(S3C2410_BANKCON3), + SAVE_ITEM(S3C2410_BANKCON4), + SAVE_ITEM(S3C2410_BANKCON5), + + SAVE_ITEM(S3C2410_CLKDIVN), + SAVE_ITEM(S3C2410_MPLLCON), + SAVE_ITEM(S3C2410_UPLLCON), + SAVE_ITEM(S3C2410_CLKSLOW), + SAVE_ITEM(S3C2410_REFRESH), +}; + +/* this lot should be really saved by the IRQ code */ +static struct sleep_save irq_save[] = { + SAVE_ITEM(S3C2410_EXTINT0), + SAVE_ITEM(S3C2410_EXTINT1), + SAVE_ITEM(S3C2410_EXTINT2), + SAVE_ITEM(S3C2410_EINFLT0), + SAVE_ITEM(S3C2410_EINFLT1), + SAVE_ITEM(S3C2410_EINFLT2), + SAVE_ITEM(S3C2410_EINFLT3), + SAVE_ITEM(S3C2410_EINTMASK), + SAVE_ITEM(S3C2410_INTMSK) +}; + +static struct sleep_save gpio_save[] = { + SAVE_ITEM(S3C2410_GPACON), + SAVE_ITEM(S3C2410_GPADAT), + + SAVE_ITEM(S3C2410_GPBCON), + SAVE_ITEM(S3C2410_GPBDAT), + SAVE_ITEM(S3C2410_GPBUP), + + SAVE_ITEM(S3C2410_GPCCON), + SAVE_ITEM(S3C2410_GPCDAT), + SAVE_ITEM(S3C2410_GPCUP), + + SAVE_ITEM(S3C2410_GPDCON), + SAVE_ITEM(S3C2410_GPDDAT), + SAVE_ITEM(S3C2410_GPDUP), + + SAVE_ITEM(S3C2410_GPECON), + SAVE_ITEM(S3C2410_GPEDAT), + SAVE_ITEM(S3C2410_GPEUP), + + SAVE_ITEM(S3C2410_GPFCON), + SAVE_ITEM(S3C2410_GPFDAT), + SAVE_ITEM(S3C2410_GPFUP), + + SAVE_ITEM(S3C2410_GPGCON), + SAVE_ITEM(S3C2410_GPGDAT), + SAVE_ITEM(S3C2410_GPGUP), + + SAVE_ITEM(S3C2410_GPHCON), + SAVE_ITEM(S3C2410_GPHDAT), + SAVE_ITEM(S3C2410_GPHUP), + + SAVE_ITEM(S3C2410_DCLKCON), +}; + +#ifdef CONFIG_S3C2410_PM_DEBUG + +#define SAVE_UART(va) \ + SAVE_ITEM((va) + S3C2410_ULCON), \ + SAVE_ITEM((va) + S3C2410_UCON), \ + SAVE_ITEM((va) + S3C2410_UFCON), \ + SAVE_ITEM((va) + S3C2410_UMCON), \ + SAVE_ITEM((va) + S3C2410_UBRDIV) + +static struct sleep_save uart_save[] = { + SAVE_UART(S3C24XX_VA_UART0), + SAVE_UART(S3C24XX_VA_UART1), +#ifndef CONFIG_CPU_S3C2400 + SAVE_UART(S3C24XX_VA_UART2), +#endif +}; + +/* debug + * + * we send the debug to printascii() to allow it to be seen if the + * system never wakes up from the sleep +*/ + +extern void printascii(const char *); + +static void pm_dbg(const char *fmt, ...) +{ + va_list va; + char buff[256]; + + va_start(va, fmt); + vsprintf(buff, fmt, va); + va_end(va); + + printascii(buff); +} + +static void s3c2410_pm_debug_init(void) +{ + unsigned long tmp = __raw_readl(S3C2410_CLKCON); + + /* re-start uart clocks */ + tmp |= S3C2410_CLKCON_UART0; + tmp |= S3C2410_CLKCON_UART1; + tmp |= S3C2410_CLKCON_UART2; + + __raw_writel(tmp, S3C2410_CLKCON); + udelay(10); +} + +#define DBG(fmt...) pm_dbg(fmt) +#else +#define DBG(fmt...) printk(KERN_DEBUG fmt) + +#define s3c2410_pm_debug_init() do { } while(0) + +static struct sleep_save uart_save[] = {}; +#endif + +#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0 + +/* suspend checking code... + * + * this next area does a set of crc checks over all the installed + * memory, so the system can verify if the resume was ok. + * + * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC, + * increasing it will mean that the area corrupted will be less easy to spot, + * and reducing the size will cause the CRC save area to grow +*/ + +#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024) + +static u32 crc_size; /* size needed for the crc block */ +static u32 *crcs; /* allocated over suspend/resume */ + +typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg); + +/* s3c2410_pm_run_res + * + * go thorugh the given resource list, and look for system ram +*/ + +static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg) +{ + while (ptr != NULL) { + if (ptr->child != NULL) + s3c2410_pm_run_res(ptr->child, fn, arg); + + if ((ptr->flags & IORESOURCE_MEM) && + strcmp(ptr->name, "System RAM") == 0) { + DBG("Found system RAM at %08lx..%08lx\n", + ptr->start, ptr->end); + arg = (fn)(ptr, arg); + } + + ptr = ptr->sibling; + } +} + +static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg) +{ + s3c2410_pm_run_res(&iomem_resource, fn, arg); +} + +static u32 *s3c2410_pm_countram(struct resource *res, u32 *val) +{ + u32 size = (u32)(res->end - res->start)+1; + + size += CHECK_CHUNKSIZE-1; + size /= CHECK_CHUNKSIZE; + + DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size); + + *val += size * sizeof(u32); + return val; +} + +/* s3c2410_pm_prepare_check + * + * prepare the necessary information for creating the CRCs. This + * must be done before the final save, as it will require memory + * allocating, and thus touching bits of the kernel we do not + * know about. +*/ + +static void s3c2410_pm_check_prepare(void) +{ + crc_size = 0; + + s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size); + + DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size); + + crcs = kmalloc(crc_size+4, GFP_KERNEL); + if (crcs == NULL) + printk(KERN_ERR "Cannot allocated CRC save area\n"); +} + +static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val) +{ + unsigned long addr, left; + + for (addr = res->start; addr < res->end; + addr += CHECK_CHUNKSIZE) { + left = res->end - addr; + + if (left > CHECK_CHUNKSIZE) + left = CHECK_CHUNKSIZE; + + *val = crc32_le(~0, phys_to_virt(addr), left); + val++; + } + + return val; +} + +/* s3c2410_pm_check_store + * + * compute the CRC values for the memory blocks before the final + * sleep. +*/ + +static void s3c2410_pm_check_store(void) +{ + if (crcs != NULL) + s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs); +} + +/* in_region + * + * return TRUE if the area defined by ptr..ptr+size contatins the + * what..what+whatsz +*/ + +static inline int in_region(void *ptr, int size, void *what, size_t whatsz) +{ + if ((what+whatsz) < ptr) + return 0; + + if (what > (ptr+size)) + return 0; + + return 1; +} + +static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val) +{ + void *save_at = phys_to_virt(s3c2410_sleep_save_phys); + unsigned long addr; + unsigned long left; + void *ptr; + u32 calc; + + for (addr = res->start; addr < res->end; + addr += CHECK_CHUNKSIZE) { + left = res->end - addr; + + if (left > CHECK_CHUNKSIZE) + left = CHECK_CHUNKSIZE; + + ptr = phys_to_virt(addr); + + if (in_region(ptr, left, crcs, crc_size)) { + DBG("skipping %08lx, has crc block in\n", addr); + goto skip_check; + } + + if (in_region(ptr, left, save_at, 32*4 )) { + DBG("skipping %08lx, has save block in\n", addr); + goto skip_check; + } + + /* calculate and check the checksum */ + + calc = crc32_le(~0, ptr, left); + if (calc != *val) { + printk(KERN_ERR PFX "Restore CRC error at " + "%08lx (%08x vs %08x)\n", addr, calc, *val); + + DBG("Restore CRC error at %08lx (%08x vs %08x)\n", + addr, calc, *val); + } + + skip_check: + val++; + } + + return val; +} + +/* s3c2410_pm_check_restore + * + * check the CRCs after the restore event and free the memory used + * to hold them +*/ + +static void s3c2410_pm_check_restore(void) +{ + if (crcs != NULL) { + s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs); + kfree(crcs); + crcs = NULL; + } +} + +#else + +#define s3c2410_pm_check_prepare() do { } while(0) +#define s3c2410_pm_check_restore() do { } while(0) +#define s3c2410_pm_check_store() do { } while(0) +#endif + +/* helper functions to save and restore register state */ + +void s3c2410_pm_do_save(struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) { + ptr->val = __raw_readl(ptr->reg); + DBG("saved %p value %08lx\n", ptr->reg, ptr->val); + } +} + +/* s3c2410_pm_do_restore + * + * restore the system from the given list of saved registers + * + * Note, we do not use DBG() in here, as the system may not have + * restore the UARTs state yet +*/ + +void s3c2410_pm_do_restore(struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) { + printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n", + ptr->reg, ptr->val, __raw_readl(ptr->reg)); + + __raw_writel(ptr->val, ptr->reg); + } +} + +/* s3c2410_pm_do_restore_core + * + * similar to s3c2410_pm_do_restore_core + * + * WARNING: Do not put any debug in here that may effect memory or use + * peripherals, as things may be changing! +*/ + +static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count) +{ + for (; count > 0; count--, ptr++) { + __raw_writel(ptr->val, ptr->reg); + } +} + +/* s3c2410_pm_show_resume_irqs + * + * print any IRQs asserted at resume time (ie, we woke from) +*/ + +static void s3c2410_pm_show_resume_irqs(int start, unsigned long which, + unsigned long mask) +{ + int i; + + which &= ~mask; + + for (i = 0; i <= 31; i++) { + if ((which) & (1L<<i)) { + DBG("IRQ %d asserted at resume\n", start+i); + } + } +} + +/* s3c2410_pm_check_resume_pin + * + * check to see if the pin is configured correctly for sleep mode, and + * make any necessary adjustments if it is not +*/ + +static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) +{ + unsigned long irqstate; + unsigned long pinstate; + int irq = s3c2410_gpio_getirq(pin); + + if (irqoffs < 4) + irqstate = s3c_irqwake_intmask & (1L<<irqoffs); + else + irqstate = s3c_irqwake_eintmask & (1L<<irqoffs); + + pinstate = s3c2410_gpio_getcfg(pin); + pinstate >>= S3C2410_GPIO_OFFSET(pin)*2; + + if (!irqstate) { + if (pinstate == 0x02) + DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin); + } else { + if (pinstate == 0x02) { + DBG("Disabling IRQ %d (pin %d)\n", irq, pin); + s3c2410_gpio_cfgpin(pin, 0x00); + } + } +} + +/* s3c2410_pm_configure_extint + * + * configure all external interrupt pins +*/ + +static void s3c2410_pm_configure_extint(void) +{ + int pin; + + /* for each of the external interrupts (EINT0..EINT15) we + * need to check wether it is an external interrupt source, + * and then configure it as an input if it is not + */ + + for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) { + s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0); + } + + for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) { + s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8); + } +} + +#define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) + +/* s3c2410_pm_enter + * + * central control for sleep/resume process +*/ + +static int s3c2410_pm_enter(suspend_state_t state) +{ + unsigned long regs_save[16]; + unsigned long tmp; + + /* ensure the debug is initialised (if enabled) */ + + s3c2410_pm_debug_init(); + + DBG("s3c2410_pm_enter(%d)\n", state); + + if (state != PM_SUSPEND_MEM) { + printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n"); + return -EINVAL; + } + + /* check if we have anything to wake-up with... bad things seem + * to happen if you suspend with no wakeup (system will often + * require a full power-cycle) + */ + + if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) && + !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) { + printk(KERN_ERR PFX "No sources enabled for wake-up!\n"); + printk(KERN_ERR PFX "Aborting sleep\n"); + return -EINVAL; + } + + /* prepare check area if configured */ + + s3c2410_pm_check_prepare(); + + /* store the physical address of the register recovery block */ + + s3c2410_sleep_save_phys = virt_to_phys(regs_save); + + DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys); + + /* ensure at least GESTATUS3 has the resume address */ + + __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3); + + DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); + DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); + + /* save all necessary core registers not covered by the drivers */ + + s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); + s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); + s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); + s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); + + /* set the irq configuration for wake */ + + s3c2410_pm_configure_extint(); + + DBG("sleep: irq wakeup masks: %08lx,%08lx\n", + s3c_irqwake_intmask, s3c_irqwake_eintmask); + + __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK); + __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK); + + /* ack any outstanding external interrupts before we go to sleep */ + + __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); + + /* flush cache back to ram */ + + arm920_flush_kern_cache_all(); + + s3c2410_pm_check_store(); + + // need to make some form of time-delta + + /* send the cpu to sleep... */ + + __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ + + s3c2410_cpu_suspend(regs_save); + + /* unset the return-from-sleep flag, to ensure reset */ + + tmp = __raw_readl(S3C2410_GSTATUS2); + tmp &= S3C2410_GSTATUS2_OFFRESET; + __raw_writel(tmp, S3C2410_GSTATUS2); + + /* restore the system state */ + + s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); + s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); + s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); + s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); + + s3c2410_pm_debug_init(); + + /* check what irq (if any) restored the system */ + + DBG("post sleep: IRQs 0x%08x, 0x%08x\n", + __raw_readl(S3C2410_SRCPND), + __raw_readl(S3C2410_EINTPEND)); + + s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND), + s3c_irqwake_intmask); + + s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND), + s3c_irqwake_eintmask); + + DBG("post sleep, preparing to return\n"); + + s3c2410_pm_check_restore(); + + /* ok, let's return from sleep */ + + DBG("S3C2410 PM Resume (post-restore)\n"); + return 0; +} + +/* + * Called after processes are frozen, but before we shut down devices. + */ +static int s3c2410_pm_prepare(suspend_state_t state) +{ + return 0; +} + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +static int s3c2410_pm_finish(suspend_state_t state) +{ + return 0; +} + +/* + * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. + */ +static struct pm_ops s3c2410_pm_ops = { + .pm_disk_mode = PM_DISK_FIRMWARE, + .prepare = s3c2410_pm_prepare, + .enter = s3c2410_pm_enter, + .finish = s3c2410_pm_finish, +}; + +/* s3c2410_pm_init + * + * Attach the power management functions. This should be called + * from the board specific initialisation if the board supports + * it. +*/ + +int __init s3c2410_pm_init(void) +{ + printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n"); + + pm_set_ops(&s3c2410_pm_ops); + return 0; +} diff --git a/arch/arm/mach-s3c2410/pm.h b/arch/arm/mach-s3c2410/pm.h new file mode 100644 index 0000000..7a5e714 --- /dev/null +++ b/arch/arm/mach-s3c2410/pm.h @@ -0,0 +1,59 @@ +/* linux/arch/arm/mach-s3c2410/pm.h + * + * Copyright (c) 2004 Simtec Electronics + * Written by Ben Dooks, <ben@simtec.co.uk> + * + * 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. +*/ + +/* s3c2410_pm_init + * + * called from board at initialisation time to setup the power + * management +*/ + +#ifdef CONFIG_PM + +extern __init int s3c2410_pm_init(void); + +#else + +static inline int s3c2410_pm_init(void) +{ + return 0; +} +#endif + +/* configuration for the IRQ mask over sleep */ +extern unsigned long s3c_irqwake_intmask; +extern unsigned long s3c_irqwake_eintmask; + +/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */ +extern unsigned long s3c_irqwake_intallow; +extern unsigned long s3c_irqwake_eintallow; + +/* Flags for PM Control */ + +extern unsigned long s3c_pm_flags; + +/* from sleep.S */ + +extern void s3c2410_cpu_suspend(unsigned long *saveblk); +extern void s3c2410_cpu_resume(void); + +extern unsigned long s3c2410_sleep_save_phys; + +/* sleep save info */ + +struct sleep_save { + void __iomem *reg; + unsigned long val; +}; + +#define SAVE_ITEM(x) \ + { .reg = (x) } + +extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count); +extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count); diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c new file mode 100644 index 0000000..ff2f254 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2410.c @@ -0,0 +1,200 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410.c + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * 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. + * + * Modifications: + * 16-May-2003 BJD Created initial version + * 16-Aug-2003 BJD Fixed header files and copyright, added URL + * 05-Sep-2003 BJD Moved to kernel v2.6 + * 18-Jan-2004 BJD Added serial port configuration + * 21-Aug-2004 BJD Added new struct s3c2410_board handler + * 28-Sep-2004 BJD Updates for new serial port bits + * 04-Nov-2004 BJD Updated UART configuration process + * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> + +#include <asm/arch/regs-clock.h> +#include <asm/arch/regs-serial.h> + +#include "s3c2410.h" +#include "cpu.h" +#include "clock.h" + +/* Initial IO mappings */ + +static struct map_desc s3c2410_iodesc[] __initdata = { + IODESC_ENT(USBHOST), + IODESC_ENT(CLKPWR), + IODESC_ENT(LCD), + IODESC_ENT(UART), + IODESC_ENT(TIMER), + IODESC_ENT(ADC), + IODESC_ENT(WATCHDOG) +}; + +static struct resource s3c_uart0_resource[] = { + [0] = { + .start = S3C2410_PA_UART0, + .end = S3C2410_PA_UART0 + 0x3fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S3CUART_RX0, + .end = IRQ_S3CUART_ERR0, + .flags = IORESOURCE_IRQ, + } + +}; + +static struct resource s3c_uart1_resource[] = { + [0] = { + .start = S3C2410_PA_UART1, + .end = S3C2410_PA_UART1 + 0x3fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S3CUART_RX1, + .end = IRQ_S3CUART_ERR1, + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource s3c_uart2_resource[] = { + [0] = { + .start = S3C2410_PA_UART2, + .end = S3C2410_PA_UART2 + 0x3fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S3CUART_RX2, + .end = IRQ_S3CUART_ERR2, + .flags = IORESOURCE_IRQ, + } +}; + +/* our uart devices */ + +static struct platform_device s3c_uart0 = { + .name = "s3c2410-uart", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_uart0_resource), + .resource = s3c_uart0_resource, +}; + + +static struct platform_device s3c_uart1 = { + .name = "s3c2410-uart", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_uart1_resource), + .resource = s3c_uart1_resource, +}; + +static struct platform_device s3c_uart2 = { + .name = "s3c2410-uart", + .id = 2, + .num_resources = ARRAY_SIZE(s3c_uart2_resource), + .resource = s3c_uart2_resource, +}; + +static struct platform_device *uart_devices[] __initdata = { + &s3c_uart0, + &s3c_uart1, + &s3c_uart2 +}; + +/* store our uart devices for the serial driver console */ +struct platform_device *s3c2410_uart_devices[3]; + +static int s3c2410_uart_count = 0; + +/* uart registration process */ + +void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + struct platform_device *platdev; + int uart; + + for (uart = 0; uart < no; uart++, cfg++) { + platdev = uart_devices[cfg->hwport]; + + s3c24xx_uart_devs[uart] = platdev; + platdev->dev.platform_data = cfg; + } + + s3c2410_uart_count = uart; +} + +/* s3c2410_map_io + * + * register the standard cpu IO areas, and any passed in from the + * machine specific initialisation. +*/ + +void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size) +{ + /* register our io-tables */ + + iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc)); + iotable_init(mach_desc, mach_size); +} + +void __init s3c2410_init_clocks(int xtal) +{ + unsigned long tmp; + unsigned long fclk; + unsigned long hclk; + unsigned long pclk; + + /* now we've got our machine bits initialised, work out what + * clocks we've got */ + + fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal); + + tmp = __raw_readl(S3C2410_CLKDIVN); + + /* work out clock scalings */ + + hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1); + pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1); + + /* print brieft summary of clocks, etc */ + + printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n", + print_mhz(fclk), print_mhz(hclk), print_mhz(pclk)); + + /* initialise the clocks here, to allow other things like the + * console to use them + */ + + s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); +} + +int __init s3c2410_init(void) +{ + printk("S3C2410: Initialising architecture\n"); + + return platform_add_devices(s3c24xx_uart_devs, s3c2410_uart_count); +} diff --git a/arch/arm/mach-s3c2410/s3c2410.h b/arch/arm/mach-s3c2410/s3c2410.h new file mode 100644 index 0000000..4d5312a --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2410.h @@ -0,0 +1,37 @@ +/* arch/arm/mach-s3c2410/s3c2410.h + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Header file for s3c2410 machine directory + * + * 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. + * + * Modifications: + * 18-Aug-2004 BJD Created initial version + * 20-Aug-2004 BJD Added s3c2410_board struct + * 04-Sep-2004 BJD Added s3c2410_init_uarts() call + * 17-Oct-2004 BJD Moved board out to cpu + * 04-Jan-2005 BJD Changed uart init + * 10-Jan-2005 BJD Removed timer to cpu.h, moved 2410 specific bits here + * 14-Jan-2005 BJD Added s3c2410_init_clocks call +*/ + +#ifdef CONFIG_CPU_S3C2410 + +extern int s3c2410_init(void); + +extern void s3c2410_map_io(struct map_desc *mach_desc, int size); + +extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no); + +extern void s3c2410_init_clocks(int xtal); + +#else +#define s3c2410_init_clocks NULL +#define s3c2410_init_uarts NULL +#define s3c2410_map_io NULL +#define s3c2410_init NULL +#endif diff --git a/arch/arm/mach-s3c2410/s3c2440-dsc.c b/arch/arm/mach-s3c2410/s3c2440-dsc.c new file mode 100644 index 0000000..16fa2a3 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2440-dsc.c @@ -0,0 +1,59 @@ +/* linux/arch/arm/mach-s3c2410/s3c2440-dsc.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Samsung S3C2440 Drive Strength Control support + * + * 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. + * + * Modifications: + * 29-Aug-2004 BJD Start of drive-strength control + * 09-Nov-2004 BJD Added symbol export + * 11-Jan-2005 BJD Include fix +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/module.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> + +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-dsc.h> + +#include "cpu.h" +#include "s3c2440.h" + +int s3c2440_set_dsc(unsigned int pin, unsigned int value) +{ + void __iomem *base; + unsigned long val; + unsigned long flags; + unsigned long mask; + + base = (pin & S3C2440_SELECT_DSC1) ? S3C2440_DSC1 : S3C2440_DSC0; + mask = 3 << S3C2440_DSC_GETSHIFT(pin); + + local_irq_save(flags); + + val = __raw_readl(base); + val &= ~mask; + val |= value & mask; + __raw_writel(val, base); + + local_irq_restore(flags); + return 0; +} + +EXPORT_SYMBOL(s3c2440_set_dsc); diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c new file mode 100644 index 0000000..9a8cc5a --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2440.c @@ -0,0 +1,281 @@ +/* linux/arch/arm/mach-s3c2410/s3c2440.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Samsung S3C2440 Mobile CPU support + * + * 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. + * + * Modifications: + * 24-Aug-2004 BJD Start of s3c2440 support + * 12-Oct-2004 BJD Moved clock info out to clock.c + * 01-Nov-2004 BJD Fixed clock build code + * 09-Nov-2004 BJD Added sysdev for power management + * 04-Nov-2004 BJD New serial registration + * 15-Nov-2004 BJD Rename the i2c device for the s3c2440 + * 14-Jan-2005 BJD Moved clock init code into seperate function + * 14-Jan-2005 BJD Removed un-used clock bits +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/sysdev.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/hardware/clock.h> + +#include <asm/arch/regs-clock.h> +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-gpioj.h> +#include <asm/arch/regs-dsc.h> + +#include "s3c2440.h" +#include "clock.h" +#include "devs.h" +#include "cpu.h" +#include "pm.h" + + +static struct map_desc s3c2440_iodesc[] __initdata = { + IODESC_ENT(USBHOST), + IODESC_ENT(CLKPWR), + IODESC_ENT(LCD), + IODESC_ENT(TIMER), + IODESC_ENT(ADC), + IODESC_ENT(WATCHDOG), +}; + +static struct resource s3c_uart0_resource[] = { + [0] = { + .start = S3C2410_PA_UART0, + .end = S3C2410_PA_UART0 + 0x3fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S3CUART_RX0, + .end = IRQ_S3CUART_ERR0, + .flags = IORESOURCE_IRQ, + } + +}; + +static struct resource s3c_uart1_resource[] = { + [0] = { + .start = S3C2410_PA_UART1, + .end = S3C2410_PA_UART1 + 0x3fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S3CUART_RX1, + .end = IRQ_S3CUART_ERR1, + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource s3c_uart2_resource[] = { + [0] = { + .start = S3C2410_PA_UART2, + .end = S3C2410_PA_UART2 + 0x3fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S3CUART_RX2, + .end = IRQ_S3CUART_ERR2, + .flags = IORESOURCE_IRQ, + } +}; + +/* our uart devices */ + +static struct platform_device s3c_uart0 = { + .name = "s3c2440-uart", + .id = 0, + .num_resources = ARRAY_SIZE(s3c_uart0_resource), + .resource = s3c_uart0_resource, +}; + +static struct platform_device s3c_uart1 = { + .name = "s3c2440-uart", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_uart1_resource), + .resource = s3c_uart1_resource, +}; + +static struct platform_device s3c_uart2 = { + .name = "s3c2440-uart", + .id = 2, + .num_resources = ARRAY_SIZE(s3c_uart2_resource), + .resource = s3c_uart2_resource, +}; + +static struct platform_device *uart_devices[] __initdata = { + &s3c_uart0, + &s3c_uart1, + &s3c_uart2 +}; + +/* uart initialisation */ + +static int __initdata s3c2440_uart_count; + +void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + struct platform_device *platdev; + int uart; + + for (uart = 0; uart < no; uart++, cfg++) { + platdev = uart_devices[cfg->hwport]; + + s3c24xx_uart_devs[uart] = platdev; + platdev->dev.platform_data = cfg; + } + + s3c2440_uart_count = uart; +} + + +#ifdef CONFIG_PM + +struct sleep_save s3c2440_sleep[] = { + SAVE_ITEM(S3C2440_DSC0), + SAVE_ITEM(S3C2440_DSC1), + SAVE_ITEM(S3C2440_GPJDAT), + SAVE_ITEM(S3C2440_GPJCON), + SAVE_ITEM(S3C2440_GPJUP) +}; + +static int s3c2440_suspend(struct sys_device *dev, pm_message_t state) +{ + s3c2410_pm_do_save(s3c2440_sleep, ARRAY_SIZE(s3c2440_sleep)); + return 0; +} + +static int s3c2440_resume(struct sys_device *dev) +{ + s3c2410_pm_do_restore(s3c2440_sleep, ARRAY_SIZE(s3c2440_sleep)); + return 0; +} + +#else +#define s3c2440_suspend NULL +#define s3c2440_resume NULL +#endif + +struct sysdev_class s3c2440_sysclass = { + set_kset_name("s3c2440-core"), + .suspend = s3c2440_suspend, + .resume = s3c2440_resume +}; + +static struct sys_device s3c2440_sysdev = { + .cls = &s3c2440_sysclass, +}; + +void __init s3c2440_map_io(struct map_desc *mach_desc, int size) +{ + /* register our io-tables */ + + iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc)); + iotable_init(mach_desc, size); + /* rename any peripherals used differing from the s3c2410 */ + + s3c_device_i2c.name = "s3c2440-i2c"; + + /* change irq for watchdog */ + + s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; + s3c_device_wdt.resource[1].end = IRQ_S3C2440_WDT; +} + +void __init s3c2440_init_clocks(int xtal) +{ + unsigned long clkdiv; + unsigned long camdiv; + unsigned long hclk, fclk, pclk; + int hdiv = 1; + + /* now we've got our machine bits initialised, work out what + * clocks we've got */ + + fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2; + + clkdiv = __raw_readl(S3C2410_CLKDIVN); + camdiv = __raw_readl(S3C2440_CAMDIVN); + + /* work out clock scalings */ + + switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) { + case S3C2440_CLKDIVN_HDIVN_1: + hdiv = 1; + break; + + case S3C2440_CLKDIVN_HDIVN_2: + hdiv = 1; + break; + + case S3C2440_CLKDIVN_HDIVN_4_8: + hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4; + break; + + case S3C2440_CLKDIVN_HDIVN_3_6: + hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3; + break; + } + + hclk = fclk / hdiv; + pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1); + + /* print brief summary of clocks, etc */ + + printk("S3C2440: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n", + print_mhz(fclk), print_mhz(hclk), print_mhz(pclk)); + + /* initialise the clocks here, to allow other things like the + * console to use them, and to add new ones after the initialisation + */ + + s3c24xx_setup_clocks(xtal, fclk, hclk, pclk); +} + +/* need to register class before we actually register the device, and + * we also need to ensure that it has been initialised before any of the + * drivers even try to use it (even if not on an s3c2440 based system) + * as a driver which may support both 2410 and 2440 may try and use it. +*/ + +int __init s3c2440_core_init(void) +{ + return sysdev_class_register(&s3c2440_sysclass); +} + +core_initcall(s3c2440_core_init); + +int __init s3c2440_init(void) +{ + int ret; + + printk("S3C2440: Initialising architecture\n"); + + ret = sysdev_register(&s3c2440_sysdev); + if (ret != 0) + printk(KERN_ERR "failed to register sysdev for s3c2440\n"); + else + ret = platform_add_devices(s3c24xx_uart_devs, s3c2440_uart_count); + + return ret; +} diff --git a/arch/arm/mach-s3c2410/s3c2440.h b/arch/arm/mach-s3c2410/s3c2440.h new file mode 100644 index 0000000..29cb6df --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2440.h @@ -0,0 +1,35 @@ +/* arch/arm/mach-s3c2410/s3c2440.h + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Header file for s3c2440 cpu support + * + * 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. + * + * Modifications: + * 24-Aug-2004 BJD Start of S3C2440 CPU support + * 04-Nov-2004 BJD Added s3c2440_init_uarts() + * 04-Jan-2005 BJD Moved uart init to cpu code + * 10-Jan-2005 BJD Moved 2440 specific init here + * 14-Jan-2005 BJD Split the clock initialisation code +*/ + +#ifdef CONFIG_CPU_S3C2440 + +extern int s3c2440_init(void); + +extern void s3c2440_map_io(struct map_desc *mach_desc, int size); + +extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no); + +extern void s3c2440_init_clocks(int xtal); + +#else +#define s3c2440_init_clocks NULL +#define s3c2440_init_uarts NULL +#define s3c2440_map_io NULL +#define s3c2440_init NULL +#endif diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S new file mode 100644 index 0000000..61768dac --- /dev/null +++ b/arch/arm/mach-s3c2410/sleep.S @@ -0,0 +1,180 @@ +/* linux/arch/arm/mach-s3c2410/sleep.S + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 Power Manager (Suspend-To-RAM) support + * + * Based on PXA/SA1100 sleep code by: + * Nicolas Pitre, (c) 2002 Monta Vista Software Inc + * Cliff Brake, (c) 2001 + * + * 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/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> +#include <asm/arch/map.h> + +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-clock.h> +#include <asm/arch/regs-mem.h> +#include <asm/arch/regs-serial.h> + +/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not + * reset the UART configuration, only enable if you really need this! +*/ +//#define CONFIG_DEBUG_RESUME + + .text + + /* s3c2410_cpu_suspend + * + * put the cpu into sleep mode + * + * entry: + * r0 = sleep save block + */ + +ENTRY(s3c2410_cpu_suspend) + stmfd sp!, { r4 - r12, lr } + + @@ store co-processor registers + + mrc p15, 0, r4, c15, c1, 0 @ CP access register + mrc p15, 0, r5, c13, c0, 0 @ PID + mrc p15, 0, r6, c3, c0, 0 @ Domain ID + mrc p15, 0, r7, c2, c0, 0 @ translation table base address + mrc p15, 0, r8, c2, c0, 0 @ auxiliary control register + mrc p15, 0, r9, c1, c0, 0 @ control register + + stmia r0, { r4 - r13 } + + @@ flush the caches to ensure everything is back out to + @@ SDRAM before the core powers down + + bl arm920_flush_kern_cache_all + + @@ prepare cpu to sleep + + ldr r4, =S3C2410_REFRESH + ldr r5, =S3C2410_MISCCR + ldr r6, =S3C2410_CLKCON + ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) + ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) + ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB) + + orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command + orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals + orr r9, r9, #S3C2410_CLKCON_POWER @ power down command + + teq pc, #0 @ first as a trial-run to load cache + bl s3c2410_do_sleep + teq r0, r0 @ now do it for real + b s3c2410_do_sleep @ + + @@ align next bit of code to cache line + .align 8 +s3c2410_do_sleep: + streq r7, [ r4 ] @ SDRAM sleep command + streq r8, [ r5 ] @ SDRAM power-down config + streq r9, [ r6 ] @ CPU sleep +1: beq 1b + mov pc, r14 + + @@ return to the caller, after having the MMU + @@ turned on, this restores the last bits from the + @@ stack +resume_with_mmu: + ldmfd sp!, { r4 - r12, pc } + + .ltorg + + @@ the next bits sit in the .data segment, even though they + @@ happen to be code... the s3c2410_sleep_save_phys needs to be + @@ accessed by the resume code before it can restore the MMU. + @@ This means that the variable has to be close enough for the + @@ code to read it... since the .text segment needs to be RO, + @@ the data segment can be the only place to put this code. + + .data + + .global s3c2410_sleep_save_phys +s3c2410_sleep_save_phys: + .word 0 + + /* s3c2410_cpu_resume + * + * resume code entry for bootloader to call + * + * we must put this code here in the data segment as we have no + * other way of restoring the stack pointer after sleep, and we + * must not write to the code segment (code is read-only) + */ + +ENTRY(s3c2410_cpu_resume) + mov r0, #PSR_I_BIT | PSR_F_BIT | MODE_SVC + msr cpsr_c, r0 + + @@ load UART to allow us to print the two characters for + @@ resume debug + + mov r2, #S3C2410_PA_UART & 0xff000000 + orr r2, r2, #S3C2410_PA_UART & 0xff000 + +#if 0 + /* SMDK2440 LED set */ + mov r14, #S3C2410_PA_GPIO + ldr r12, [ r14, #0x54 ] + bic r12, r12, #3<<4 + orr r12, r12, #1<<7 + str r12, [ r14, #0x54 ] +#endif + +#ifdef CONFIG_DEBUG_RESUME + mov r3, #'L' + strb r3, [ r2, #S3C2410_UTXH ] +1001: + ldrb r14, [ r3, #S3C2410_UTRSTAT ] + tst r14, #S3C2410_UTRSTAT_TXE + beq 1001b +#endif /* CONFIG_DEBUG_RESUME */ + + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs + mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches + + ldr r0, s3c2410_sleep_save_phys @ address of restore block + ldmia r0, { r4 - r13 } + + mcr p15, 0, r4, c15, c1, 0 @ CP access register + mcr p15, 0, r5, c13, c0, 0 @ PID + mcr p15, 0, r6, c3, c0, 0 @ Domain ID + mcr p15, 0, r7, c2, c0, 0 @ translation table base + mcr p15, 0, r8, c1, c1, 0 @ auxilliary control + +#ifdef CONFIG_DEBUG_RESUME + mov r3, #'R' + strb r3, [ r2, #S3C2410_UTXH ] +#endif + + ldr r2, =resume_with_mmu + mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc + nop @ second-to-last before mmu + mov pc, r2 @ go back to virtual address + + .ltorg diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c new file mode 100644 index 0000000..179f0e0 --- /dev/null +++ b/arch/arm/mach-s3c2410/time.c @@ -0,0 +1,256 @@ +/* linux/arch/arm/mach-s3c2410/time.c + * + * Copyright (C) 2003-2005 Simtec Electronics + * Ben Dooks, <ben@simtec.co.uk> + * + * 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/kernel.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/err.h> + +#include <asm/system.h> +#include <asm/leds.h> +#include <asm/mach-types.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/arch/map.h> +#include <asm/arch/regs-timer.h> +#include <asm/arch/regs-irq.h> +#include <asm/mach/time.h> +#include <asm/hardware/clock.h> + +#include "clock.h" + +static unsigned long timer_startval; +static unsigned long timer_usec_ticks; + +#define TIMER_USEC_SHIFT 16 + +/* we use the shifted arithmetic to work out the ratio of timer ticks + * to usecs, as often the peripheral clock is not a nice even multiple + * of 1MHz. + * + * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok + * for the current HZ value of 200 without producing overflows. + * + * Original patch by Dimitry Andric, updated by Ben Dooks +*/ + + +/* timer_mask_usec_ticks + * + * given a clock and divisor, make the value to pass into timer_ticks_to_usec + * to scale the ticks into usecs +*/ + +static inline unsigned long +timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk) +{ + unsigned long den = pclk / 1000; + + return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den; +} + +/* timer_ticks_to_usec + * + * convert timer ticks to usec. +*/ + +static inline unsigned long timer_ticks_to_usec(unsigned long ticks) +{ + unsigned long res; + + res = ticks * timer_usec_ticks; + res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */ + + return res >> TIMER_USEC_SHIFT; +} + +/*** + * Returns microsecond since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + * IRQs are disabled before entering here from do_gettimeofday() + */ + +#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0)) + +static unsigned long s3c2410_gettimeoffset (void) +{ + unsigned long tdone; + unsigned long irqpend; + unsigned long tval; + + /* work out how many ticks have gone since last timer interrupt */ + + tval = __raw_readl(S3C2410_TCNTO(4)); + tdone = timer_startval - tval; + + /* check to see if there is an interrupt pending */ + + irqpend = __raw_readl(S3C2410_SRCPND); + if (irqpend & SRCPND_TIMER4) { + /* re-read the timer, and try and fix up for the missed + * interrupt. Note, the interrupt may go off before the + * timer has re-loaded from wrapping. + */ + + tval = __raw_readl(S3C2410_TCNTO(4)); + tdone = timer_startval - tval; + + if (tval != 0) + tdone += timer_startval; + } + + return timer_ticks_to_usec(tdone); +} + + +/* + * IRQ handler for the timer + */ +static irqreturn_t +s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + timer_tick(regs); + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +static struct irqaction s3c2410_timer_irq = { + .name = "S3C2410 Timer Tick", + .flags = SA_INTERRUPT, + .handler = s3c2410_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + * + * Currently we only use timer4, as it is the only timer which has no + * other function that can be exploited externally + */ +static void s3c2410_timer_setup (void) +{ + unsigned long tcon; + unsigned long tcnt; + unsigned long tcfg1; + unsigned long tcfg0; + + tcnt = 0xffff; /* default value for tcnt */ + + /* read the current timer configuration bits */ + + tcon = __raw_readl(S3C2410_TCON); + tcfg1 = __raw_readl(S3C2410_TCFG1); + tcfg0 = __raw_readl(S3C2410_TCFG0); + + /* configure the system for whichever machine is in use */ + + if (machine_is_bast() || machine_is_vr1000()) { + /* timer is at 12MHz, scaler is 1 */ + timer_usec_ticks = timer_mask_usec_ticks(1, 12000000); + tcnt = 12000000 / HZ; + + tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; + tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1; + } else { + unsigned long pclk; + struct clk *clk; + + /* for the h1940 (and others), we use the pclk from the core + * to generate the timer values. since values around 50 to + * 70MHz are not values we can directly generate the timer + * value from, we need to pre-scale and divide before using it. + * + * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz + * (8.45 ticks per usec) + */ + + /* this is used as default if no other timer can be found */ + + clk = clk_get(NULL, "timers"); + if (IS_ERR(clk)) + panic("failed to get clock for system timer"); + + clk_use(clk); + clk_enable(clk); + + pclk = clk_get_rate(clk); + + /* configure clock tick */ + + timer_usec_ticks = timer_mask_usec_ticks(6, pclk); + + tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; + tcfg1 |= S3C2410_TCFG1_MUX4_DIV2; + + tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; + tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT; + + tcnt = (pclk / 6) / HZ; + } + + /* timers reload after counting zero, so reduce the count by 1 */ + + tcnt--; + + printk("timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n", + tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks); + + /* check to see if timer is within 16bit range... */ + if (tcnt > 0xffff) { + panic("setup_timer: HZ is too small, cannot configure timer!"); + return; + } + + __raw_writel(tcfg1, S3C2410_TCFG1); + __raw_writel(tcfg0, S3C2410_TCFG0); + + timer_startval = tcnt; + __raw_writel(tcnt, S3C2410_TCNTB(4)); + + /* ensure timer is stopped... */ + + tcon &= ~(7<<20); + tcon |= S3C2410_TCON_T4RELOAD; + tcon |= S3C2410_TCON_T4MANUALUPD; + + __raw_writel(tcon, S3C2410_TCON); + __raw_writel(tcnt, S3C2410_TCNTB(4)); + __raw_writel(tcnt, S3C2410_TCMPB(4)); + + /* start the timer running */ + tcon |= S3C2410_TCON_T4START; + tcon &= ~S3C2410_TCON_T4MANUALUPD; + __raw_writel(tcon, S3C2410_TCON); +} + +static void __init s3c2410_timer_init (void) +{ + s3c2410_timer_setup(); + setup_irq(IRQ_TIMER4, &s3c2410_timer_irq); +} + +struct sys_timer s3c24xx_timer = { + .init = s3c2410_timer_init, + .offset = s3c2410_gettimeoffset, + .resume = s3c2410_timer_setup +}; diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c new file mode 100644 index 0000000..7f2b613 --- /dev/null +++ b/arch/arm/mach-s3c2410/usb-simtec.c @@ -0,0 +1,113 @@ +/* linux/arch/arm/mach-s3c2410/usb-simtec.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * Simtec BAST and Thorcom VR1000 USB port support functions + * + * 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. + * + * Modifications: + * 14-Sep-2004 BJD Created + * 18-Oct-2004 BJD Cleanups, and added code to report OC cleared +*/ + +#define DEBUG + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/arch/bast-map.h> +#include <asm/arch/bast-irq.h> +#include <asm/arch/usb-control.h> +#include <asm/arch/regs-gpio.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include "devs.h" +#include "usb-simtec.h" + +/* control power and monitor over-current events on various Simtec + * designed boards. +*/ + +static void +usb_simtec_powercontrol(int port, int to) +{ + pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to); + + if (port == 1) + s3c2410_gpio_setpin(S3C2410_GPB4, to ? 0:1); +} + +static irqreturn_t +usb_simtec_ocirq(int irq, void *pw, struct pt_regs *regs) +{ + struct s3c2410_hcd_info *info = (struct s3c2410_hcd_info *)pw; + + if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) { + pr_debug("usb_simtec: over-current irq (oc detected)\n"); + s3c2410_report_oc(info, 3); + } else { + pr_debug("usb_simtec: over-current irq (oc cleared)\n"); + s3c2410_report_oc(info, 0); + } + + return IRQ_HANDLED; +} + +static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on) +{ + int ret; + + if (on) { + ret = request_irq(IRQ_USBOC, usb_simtec_ocirq, SA_INTERRUPT, + "USB Over-current", info); + if (ret != 0) { + printk(KERN_ERR "failed to request usb oc irq\n"); + } + + set_irq_type(IRQ_USBOC, IRQT_BOTHEDGE); + } else { + free_irq(IRQ_USBOC, info); + } +} + +static struct s3c2410_hcd_info usb_simtec_info = { + .port[0] = { + .flags = S3C_HCDFLG_USED + }, + .port[1] = { + .flags = S3C_HCDFLG_USED + }, + + .power_control = usb_simtec_powercontrol, + .enable_oc = usb_simtec_enableoc, +}; + + +int usb_simtec_init(void) +{ + printk("USB Power Control, (c) 2004 Simtec Electronics\n"); + s3c_device_usb.dev.platform_data = &usb_simtec_info; + + s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP); + s3c2410_gpio_setpin(S3C2410_GPB4, 1); + return 0; +} diff --git a/arch/arm/mach-s3c2410/usb-simtec.h b/arch/arm/mach-s3c2410/usb-simtec.h new file mode 100644 index 0000000..92c0cc83 --- /dev/null +++ b/arch/arm/mach-s3c2410/usb-simtec.h @@ -0,0 +1,19 @@ +/* linux/arch/arm/mach-s3c2410/usb-simtec.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * Simtec BAST and Thorcom VR1000 USB port support functions + * + * 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. + * + * Modifications: + * 20-Aug-2004 BJD Created +*/ + +extern int usb_simtec_init(void); + diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig new file mode 100644 index 0000000..50cde57 --- /dev/null +++ b/arch/arm/mach-sa1100/Kconfig @@ -0,0 +1,162 @@ +if ARCH_SA1100 + +menu "SA11x0 Implementations" + +config SA1100_ASSABET + bool "Assabet" + help + Say Y here if you are using the Intel(R) StrongARM(R) SA-1110 + Microprocessor Development Board (also known as the Assabet). + +config ASSABET_NEPONSET + bool "Include support for Neponset" + depends on SA1100_ASSABET + select SA1111 + help + Say Y here if you are using the Intel(R) StrongARM(R) SA-1110 + Microprocessor Development Board (Assabet) with the SA-1111 + Development Board (Nepon). + +config SA1100_CERF + bool "CerfBoard" + help + The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued). + More information is available at: + <http://www.intrinsyc.com/products/cerfboard/>. + + Say Y if configuring for an Intrinsyc CerfBoard. + Say N otherwise. + +choice + prompt "Cerf Flash available" + depends on SA1100_CERF + default SA1100_CERF_FLASH_8MB + +config SA1100_CERF_FLASH_8MB + bool "8MB" + +config SA1100_CERF_FLASH_16MB + bool "16MB" + +config SA1100_CERF_FLASH_32MB + bool "32MB" + +endchoice + +config SA1100_COLLIE + bool "Sharp Zaurus SL5500" + select SHARP_LOCOMO + select SHARP_SCOOP + select SHARP_PARAM + help + Say Y here to support the Sharp Zaurus SL5500 PDAs. + +config SA1100_H3100 + bool "Compaq iPAQ H3100" + help + Say Y here if you intend to run this kernel on the Compaq iPAQ + H3100 handheld computer. Information about this machine and the + Linux port to this machine can be found at: + + <http://www.handhelds.org/Compaq/index.html#iPAQ_H3100> + <http://www.compaq.com/products/handhelds/pocketpc/> + +config SA1100_H3600 + bool "Compaq iPAQ H3600/H3700" + help + Say Y here if you intend to run this kernel on the Compaq iPAQ + H3600 handheld computer. Information about this machine and the + Linux port to this machine can be found at: + + <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600> + <http://www.compaq.com/products/handhelds/pocketpc/> + +config SA1100_H3800 + bool "Compaq iPAQ H3800" + help + Say Y here if you intend to run this kernel on the Compaq iPAQ H3800 + series handheld computer. Information about this machine and the + Linux port to this machine can be found at: + + <http://www.handhelds.org/Compaq/index.html#iPAQ_H3800> + <http://www.compaq.com/products/handhelds/pocketpc/> + +config SA1100_H3XXX + bool + depends on SA1100_H3100 || SA1100_H3600 || SA1100_H3800 + default y + +config SA1100_BADGE4 + bool "HP Labs BadgePAD 4" + select SA1111 + help + Say Y here if you want to build a kernel for the HP Laboratories + BadgePAD 4. + +config SA1100_JORNADA720 + bool "HP Jornada 720" + select SA1111 + help + Say Y here if you want to build a kernel for the HP Jornada 720 + handheld computer. See <http://www.hp.com/jornada/products/720> + for details. + +config SA1100_HACKKIT + bool "HackKit Core CPU Board" + help + Say Y here to support the HackKit Core CPU Board + <http://hackkit.eletztrick.de>; + +config SA1100_LART + bool "LART" + help + Say Y here if you are using the Linux Advanced Radio Terminal + (also known as the LART). See <http://www.lart.tudelft.nl/> for + information on the LART. + +config SA1100_PLEB + bool "PLEB" + help + Say Y here if you are using version 1 of the Portable Linux + Embedded Board (also known as PLEB). + See <http://www.disy.cse.unsw.edu.au/Hardware/PLEB/> + for more information. + +config SA1100_SHANNON + bool "Shannon" + help + The Shannon (also known as a Tuxscreen, and also as a IS2630) was a + limited edition webphone produced by Philips. The Shannon is a SA1100 + platform with a 640x480 LCD, touchscreen, CIR keyboard, PCMCIA slots, + and a telco interface. + +config SA1100_SIMPAD + bool "Simpad" + help + The SIEMENS webpad SIMpad is based on the StrongARM 1110. There + are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB + FLASH. The SL4 version got 64 MB RAM and 32 MB FLASH and a + PCMCIA-Slot. The version for the Germany Telecom (DTAG) is the same + like CL4 in additional it has a PCMCIA-Slot. For more information + visit <http://www.my-siemens.com/> or <http://www.siemens.ch/>. + +config SA1100_SSP + tristate "Generic PIO SSP" + help + Say Y here to enable support for the generic PIO SSP driver. + This isn't for audio support, but for attached sensors and + other devices, eg for BadgePAD 4 sensor support, or Jornada + 720 touchscreen support. + +config H3600_SLEEVE + tristate "Compaq iPAQ Handheld sleeve support" + depends on SA1100_H3600 + help + Choose this option to enable support for extension packs (sleeves) + for the Compaq iPAQ H3XXX series of handheld computers. This option + is required for the CF, PCMCIA, Bluetooth and GSM/GPRS extension + packs. + +endmenu + +endif diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile new file mode 100644 index 0000000..e4a4a3e --- /dev/null +++ b/arch/arm/mach-sa1100/Makefile @@ -0,0 +1,53 @@ +# +# Makefile for the linux kernel. +# + +# Common support +obj-y := generic.o irq.o dma.o time.o +obj-m := +obj-n := +obj- := +led-y := leds.o + +obj-$(CONFIG_CPU_FREQ_SA1100) += cpu-sa1100.o +obj-$(CONFIG_CPU_FREQ_SA1110) += cpu-sa1110.o + +# Specific board support +obj-$(CONFIG_SA1100_ASSABET) += assabet.o +led-$(CONFIG_SA1100_ASSABET) += leds-assabet.o +obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o + +obj-$(CONFIG_SA1100_BADGE4) += badge4.o +led-$(CONFIG_SA1100_BADGE4) += leds-badge4.o + +obj-$(CONFIG_SA1100_CERF) += cerf.o +led-$(CONFIG_SA1100_CERF) += leds-cerf.o + +obj-$(CONFIG_SA1100_COLLIE) += collie.o + +obj-$(CONFIG_SA1100_H3600) += h3600.o + +obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o +led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o + +obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o + +obj-$(CONFIG_SA1100_LART) += lart.o +led-$(CONFIG_SA1100_LART) += leds-lart.o + +obj-$(CONFIG_SA1100_PLEB) += pleb.o + +obj-$(CONFIG_SA1100_SHANNON) += shannon.o + +obj-$(CONFIG_SA1100_SIMPAD) += simpad.o +led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o + +# LEDs support +obj-$(CONFIG_LEDS) += $(led-y) + +# SA1110 USB client support +#obj-$(CONFIG_SA1100_USB) += usb/ + +# Miscelaneous functions +obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_SA1100_SSP) += ssp.o diff --git a/arch/arm/mach-sa1100/Makefile.boot b/arch/arm/mach-sa1100/Makefile.boot new file mode 100644 index 0000000..a56ad04 --- /dev/null +++ b/arch/arm/mach-sa1100/Makefile.boot @@ -0,0 +1,7 @@ + zreladdr-y := 0xc0008000 +ifeq ($(CONFIG_ARCH_SA1100),y) + zreladdr-$(CONFIG_SA1111) := 0xc0208000 +endif +params_phys-y := 0xc0000100 +initrd_phys-y := 0xc0800000 + diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c new file mode 100644 index 0000000..bedf88f --- /dev/null +++ b/arch/arm/mach-sa1100/assabet.c @@ -0,0 +1,441 @@ +/* + * linux/arch/arm/mach-sa1100/assabet.c + * + * Author: Nicolas Pitre + * + * This file contains all Assabet-specific tweaks. + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/ioport.h> +#include <linux/serial_core.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/delay.h> +#include <linux/mm.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/irda.h> +#include <asm/mach/map.h> +#include <asm/mach/serial_sa1100.h> +#include <asm/arch/assabet.h> + +#include "generic.h" + +#define ASSABET_BCR_DB1110 \ + (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ + ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ + ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ + ASSABET_BCR_IRDA_MD0) + +#define ASSABET_BCR_DB1111 \ + (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ + ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ + ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ + ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \ + ASSABET_BCR_IRDA_MD0 | ASSABET_BCR_CF_RST) + +unsigned long SCR_value = ASSABET_SCR_INIT; +EXPORT_SYMBOL(SCR_value); + +static unsigned long BCR_value = ASSABET_BCR_DB1110; + +void ASSABET_BCR_frob(unsigned int mask, unsigned int val) +{ + unsigned long flags; + + local_irq_save(flags); + BCR_value = (BCR_value & ~mask) | val; + ASSABET_BCR = BCR_value; + local_irq_restore(flags); +} + +EXPORT_SYMBOL(ASSABET_BCR_frob); + +static void assabet_backlight_power(int on) +{ +#ifndef ASSABET_PAL_VIDEO + if (on) + ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON); + else +#endif + ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); +} + +/* + * Turn on/off the backlight. When turning the backlight on, + * we wait 500us after turning it on so we don't cause the + * supplies to droop when we enable the LCD controller (and + * cause a hard reset.) + */ +static void assabet_lcd_power(int on) +{ +#ifndef ASSABET_PAL_VIDEO + if (on) { + ASSABET_BCR_set(ASSABET_BCR_LCD_ON); + udelay(500); + } else +#endif + ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); +} + + +/* + * Assabet flash support code. + */ + +#ifdef ASSABET_REV_4 +/* + * Phase 4 Assabet has two 28F160B3 flash parts in bank 0: + */ +static struct mtd_partition assabet_partitions[] = { + { + .name = "bootloader", + .size = 0x00020000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "bootloader params", + .size = 0x00020000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "jffs", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; +#else +/* + * Phase 5 Assabet has two 28F128J3A flash parts in bank 0: + */ +static struct mtd_partition assabet_partitions[] = { + { + .name = "bootloader", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "bootloader params", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "jffs", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; +#endif + +static struct flash_platform_data assabet_flash_data = { + .map_name = "cfi_probe", + .parts = assabet_partitions, + .nr_parts = ARRAY_SIZE(assabet_partitions), +}; + +static struct resource assabet_flash_resources[] = { + { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = SA1100_CS1_PHYS, + .end = SA1100_CS1_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + } +}; + + +/* + * Assabet IrDA support code. + */ + +static int assabet_irda_set_power(struct device *dev, unsigned int state) +{ + static unsigned int bcr_state[4] = { + ASSABET_BCR_IRDA_MD0, + ASSABET_BCR_IRDA_MD1|ASSABET_BCR_IRDA_MD0, + ASSABET_BCR_IRDA_MD1, + 0 + }; + + if (state < 4) { + state = bcr_state[state]; + ASSABET_BCR_clear(state ^ (ASSABET_BCR_IRDA_MD1| + ASSABET_BCR_IRDA_MD0)); + ASSABET_BCR_set(state); + } + return 0; +} + +static void assabet_irda_set_speed(struct device *dev, unsigned int speed) +{ + if (speed < 4000000) + ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL); + else + ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL); +} + +static struct irda_platform_data assabet_irda_data = { + .set_power = assabet_irda_set_power, + .set_speed = assabet_irda_set_speed, +}; + +static void __init assabet_init(void) +{ + /* + * Ensure that the power supply is in "high power" mode. + */ + GPDR |= GPIO_GPIO16; + GPSR = GPIO_GPIO16; + + /* + * Ensure that these pins are set as outputs and are driving + * logic 0. This ensures that we won't inadvertently toggle + * the WS latch in the CPLD, and we don't float causing + * excessive power drain. --rmk + */ + GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; + GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; + + /* + * Set up registers for sleep mode. + */ + PWER = PWER_GPIO0; + PGSR = 0; + PCFR = 0; + PSDR = 0; + PPDR |= PPC_TXD3 | PPC_TXD1; + PPSR |= PPC_TXD3 | PPC_TXD1; + + sa1100fb_lcd_power = assabet_lcd_power; + sa1100fb_backlight_power = assabet_backlight_power; + + if (machine_has_neponset()) { + /* + * Angel sets this, but other bootloaders may not. + * + * This must precede any driver calls to BCR_set() + * or BCR_clear(). + */ + ASSABET_BCR = BCR_value = ASSABET_BCR_DB1111; + +#ifndef CONFIG_ASSABET_NEPONSET + printk( "Warning: Neponset detected but full support " + "hasn't been configured in the kernel\n" ); +#endif + } + + sa11x0_set_flash_data(&assabet_flash_data, assabet_flash_resources, + ARRAY_SIZE(assabet_flash_resources)); + sa11x0_set_irda_data(&assabet_irda_data); +} + +/* + * On Assabet, we must probe for the Neponset board _before_ + * paging_init() 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. + */ +static void __init map_sa1100_gpio_regs( void ) +{ + unsigned long phys = __PREG(GPLR) & PMD_MASK; + unsigned long virt = io_p2v(phys); + int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO); + pmd_t *pmd; + + pmd = pmd_offset(pgd_offset_k(virt), virt); + *pmd = __pmd(phys | prot); + flush_pmd_entry(pmd); +} + +/* + * Read System Configuration "Register" + * (taken from "Intel StrongARM SA-1110 Microprocessor Development Board + * User's Guide", section 4.4.1) + * + * This same scan is performed in arch/arm/boot/compressed/head-sa1100.S + * to set up the serial port for decompression status messages. We + * repeat it here because the kernel may not be loaded as a zImage, and + * also because it's a hassle to communicate the SCR value to the kernel + * from the decompressor. + * + * Note that IRQs are guaranteed to be disabled. + */ +static void __init get_assabet_scr(void) +{ + unsigned long scr, i; + + GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */ + GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */ + GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */ + for(i = 100; i--; scr = GPLR); /* Read GPIO 9:2 */ + GPDR |= 0x3fc; /* restore correct pin direction */ + scr &= 0x3fc; /* save as system configuration byte. */ + SCR_value = scr; +} + +static void __init +fixup_assabet(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + /* This must be done before any call to machine_has_neponset() */ + map_sa1100_gpio_regs(); + get_assabet_scr(); + + if (machine_has_neponset()) + printk("Neponset expansion board detected\n"); +} + + +static void assabet_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + if (port->mapbase == _Ser1UTCR0) { + if (state) + ASSABET_BCR_clear(ASSABET_BCR_RS232EN | + ASSABET_BCR_COM_RTS | + ASSABET_BCR_COM_DTR); + else + ASSABET_BCR_set(ASSABET_BCR_RS232EN | + ASSABET_BCR_COM_RTS | + ASSABET_BCR_COM_DTR); + } +} + +/* + * Assabet uses COM_RTS and COM_DTR for both UART1 (com port) + * and UART3 (radio module). We only handle them for UART1 here. + */ +static void assabet_set_mctrl(struct uart_port *port, u_int mctrl) +{ + if (port->mapbase == _Ser1UTCR0) { + u_int set = 0, clear = 0; + + if (mctrl & TIOCM_RTS) + clear |= ASSABET_BCR_COM_RTS; + else + set |= ASSABET_BCR_COM_RTS; + + if (mctrl & TIOCM_DTR) + clear |= ASSABET_BCR_COM_DTR; + else + set |= ASSABET_BCR_COM_DTR; + + ASSABET_BCR_clear(clear); + ASSABET_BCR_set(set); + } +} + +static u_int assabet_get_mctrl(struct uart_port *port) +{ + u_int ret = 0; + u_int bsr = ASSABET_BSR; + + /* need 2 reads to read current value */ + bsr = ASSABET_BSR; + + if (port->mapbase == _Ser1UTCR0) { + if (bsr & ASSABET_BSR_COM_DCD) + ret |= TIOCM_CD; + if (bsr & ASSABET_BSR_COM_CTS) + ret |= TIOCM_CTS; + if (bsr & ASSABET_BSR_COM_DSR) + ret |= TIOCM_DSR; + } else if (port->mapbase == _Ser3UTCR0) { + if (bsr & ASSABET_BSR_RAD_DCD) + ret |= TIOCM_CD; + if (bsr & ASSABET_BSR_RAD_CTS) + ret |= TIOCM_CTS; + if (bsr & ASSABET_BSR_RAD_DSR) + ret |= TIOCM_DSR; + if (bsr & ASSABET_BSR_RAD_RI) + ret |= TIOCM_RI; + } else { + ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; + } + + return ret; +} + +static struct sa1100_port_fns assabet_port_fns __initdata = { + .set_mctrl = assabet_set_mctrl, + .get_mctrl = assabet_get_mctrl, + .pm = assabet_uart_pm, +}; + +static struct map_desc assabet_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xf1000000, 0x12000000, 0x00100000, MT_DEVICE }, /* Board Control Register */ + { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE } /* MQ200 */ +}; + +static void __init assabet_map_io(void) +{ + sa1100_map_io(); + iotable_init(assabet_io_desc, ARRAY_SIZE(assabet_io_desc)); + + /* + * Set SUS bit in SDCR0 so serial port 1 functions. + * Its called GPCLKR0 in my SA1110 manual. + */ + Ser1SDCR0 |= SDCR0_SUS; + + if (machine_has_neponset()) { +#ifdef CONFIG_ASSABET_NEPONSET + extern void neponset_map_io(void); + + /* + * We map Neponset registers even if it isn't present since + * many drivers will try to probe their stuff (and fail). + * This is still more friendly than a kernel paging request + * crash. + */ + neponset_map_io(); +#endif + } else { + sa1100_register_uart_fns(&assabet_port_fns); + } + + /* + * When Neponset is attached, the first UART should be + * UART3. That's what Angel is doing and many documents + * are stating this. + * + * We do the Neponset mapping even if Neponset support + * isn't compiled in so the user will still get something on + * the expected physical serial port. + * + * We no longer do this; not all boot loaders support it, + * and UART3 appears to be somewhat unreliable with blob. + */ + sa1100_register_uart(0, 1); + sa1100_register_uart(2, 3); +} + + +MACHINE_START(ASSABET, "Intel-Assabet") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_assabet) + MAPIO(assabet_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, + .init_machine = assabet_init, +MACHINE_END diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c new file mode 100644 index 0000000..6a60b49 --- /dev/null +++ b/arch/arm/mach-sa1100/badge4.c @@ -0,0 +1,293 @@ +/* + * linux/arch/arm/mach-sa1100/badge4.c + * + * BadgePAD 4 specific initialization + * + * Tim Connors <connors@hpl.hp.com> + * Christopher Hoover <ch@hpl.hp.com> + * + * Copyright (C) 2002 Hewlett-Packard Company + * + * 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/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/delay.h> +#include <linux/tty.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/errno.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/setup.h> +#include <asm/arch/irqs.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> +#include <asm/hardware/sa1111.h> +#include <asm/mach/serial_sa1100.h> + +#include <asm/arch/badge4.h> + +#include "generic.h" + +static struct resource sa1111_resources[] = { + [0] = { + .start = BADGE4_SA1111_BASE, + .end = BADGE4_SA1111_BASE + 0x00001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = BADGE4_IRQ_GPIO_SA1111, + .end = BADGE4_IRQ_GPIO_SA1111, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .dma_mask = &sa1111_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + +static int __init badge4_sa1111_init(void) +{ + /* + * Ensure that the memory bus request/grant signals are setup, + * and the grant is held in its inactive state + */ + sa1110_mb_disable(); + + /* + * Probe for SA1111. + */ + return platform_add_devices(devices, ARRAY_SIZE(devices)); +} + + +/* + * 1 x Intel 28F320C3 Advanced+ Boot Block Flash (32 Mi bit) + * Eight 4 KiW Parameter Bottom Blocks (64 KiB) + * Sixty-three 32 KiW Main Blocks (4032 Ki b) + * + * <or> + * + * 1 x Intel 28F640C3 Advanced+ Boot Block Flash (64 Mi bit) + * Eight 4 KiW Parameter Bottom Blocks (64 KiB) + * One-hundred-twenty-seven 32 KiW Main Blocks (8128 Ki b) + */ +static struct mtd_partition badge4_partitions[] = { + { + .name = "BLOB boot loader", + .offset = 0, + .size = 0x0000A000 + }, { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = 0x00006000 + }, { + .name = "root", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + } +}; + +static struct flash_platform_data badge4_flash_data = { + .map_name = "cfi_probe", + .parts = badge4_partitions, + .nr_parts = ARRAY_SIZE(badge4_partitions), +}; + +static struct resource badge4_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; + +static int five_v_on __initdata = 0; + +static int __init five_v_on_setup(char *ignore) +{ + five_v_on = 1; + return 1; +} +__setup("five_v_on", five_v_on_setup); + + +static int __init badge4_init(void) +{ + int ret; + + if (!machine_is_badge4()) + return -ENODEV; + + /* LCD */ + GPCR = (BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 | + BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 | + BADGE4_GPIO_LGP6 | BADGE4_GPIO_LGP7 | + BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 | + BADGE4_GPIO_GPA_VID | BADGE4_GPIO_GPB_VID | + BADGE4_GPIO_GPC_VID); + GPDR &= ~BADGE4_GPIO_INT_VID; + GPDR |= (BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 | + BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 | + BADGE4_GPIO_LGP6 | BADGE4_GPIO_LGP7 | + BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 | + BADGE4_GPIO_GPA_VID | BADGE4_GPIO_GPB_VID | + BADGE4_GPIO_GPC_VID); + + /* SDRAM SPD i2c */ + GPCR = (BADGE4_GPIO_SDSDA | BADGE4_GPIO_SDSCL); + GPDR |= (BADGE4_GPIO_SDSDA | BADGE4_GPIO_SDSCL); + + /* uart */ + GPCR = (BADGE4_GPIO_UART_HS1 | BADGE4_GPIO_UART_HS2); + GPDR |= (BADGE4_GPIO_UART_HS1 | BADGE4_GPIO_UART_HS2); + + /* CPLD muxsel0 input for mux/adc chip select */ + GPCR = BADGE4_GPIO_MUXSEL0; + GPDR |= BADGE4_GPIO_MUXSEL0; + + /* test points: J5, J6 as inputs, J7 outputs */ + GPDR &= ~(BADGE4_GPIO_TESTPT_J5 | BADGE4_GPIO_TESTPT_J6); + GPCR = BADGE4_GPIO_TESTPT_J7; + GPDR |= BADGE4_GPIO_TESTPT_J7; + + /* 5V supply rail. */ + GPCR = BADGE4_GPIO_PCMEN5V; /* initially off */ + GPDR |= BADGE4_GPIO_PCMEN5V; + + /* CPLD sdram type inputs; set up by blob */ + //GPDR |= (BADGE4_GPIO_SDTYP1 | BADGE4_GPIO_SDTYP0); + printk(KERN_DEBUG __FILE__ ": SDRAM CPLD typ1=%d typ0=%d\n", + !!(GPLR & BADGE4_GPIO_SDTYP1), + !!(GPLR & BADGE4_GPIO_SDTYP0)); + + /* SA1111 reset pin; set up by blob */ + //GPSR = BADGE4_GPIO_SA1111_NRST; + //GPDR |= BADGE4_GPIO_SA1111_NRST; + + + /* power management cruft */ + PGSR = 0; + PWER = 0; + PCFR = 0; + PSDR = 0; + + PWER |= PWER_GPIO26; /* wake up on an edge from TESTPT_J5 */ + PWER |= PWER_RTC; /* wake up if rtc fires */ + + /* drive sa1111_nrst during sleep */ + PGSR |= BADGE4_GPIO_SA1111_NRST; + /* drive CPLD as is during sleep */ + PGSR |= (GPLR & (BADGE4_GPIO_SDTYP0|BADGE4_GPIO_SDTYP1)); + + + /* Now bring up the SA-1111. */ + ret = badge4_sa1111_init(); + if (ret < 0) + printk(KERN_ERR + "%s: SA-1111 initialization failed (%d)\n", + __FUNCTION__, ret); + + + /* maybe turn on 5v0 from the start */ + badge4_set_5V(BADGE4_5V_INITIALLY, five_v_on); + + sa11x0_set_flash_data(&badge4_flash_data, &badge4_flash_resource, 1); + + return 0; +} + +arch_initcall(badge4_init); + + +static unsigned badge4_5V_bitmap = 0; + +void badge4_set_5V(unsigned subsystem, int on) +{ + unsigned long flags; + unsigned old_5V_bitmap; + + local_irq_save(flags); + + old_5V_bitmap = badge4_5V_bitmap; + + if (on) { + badge4_5V_bitmap |= subsystem; + } else { + badge4_5V_bitmap &= ~subsystem; + } + + /* detect on->off and off->on transitions */ + if ((!old_5V_bitmap) && (badge4_5V_bitmap)) { + /* was off, now on */ + printk(KERN_INFO "%s: enabling 5V supply rail\n", __FUNCTION__); + GPSR = BADGE4_GPIO_PCMEN5V; + } else if ((old_5V_bitmap) && (!badge4_5V_bitmap)) { + /* was on, now off */ + printk(KERN_INFO "%s: disabling 5V supply rail\n", __FUNCTION__); + GPCR = BADGE4_GPIO_PCMEN5V; + } + + local_irq_restore(flags); +} +EXPORT_SYMBOL(badge4_set_5V); + + +static struct map_desc badge4_io_desc[] __initdata = { + /* virtual physical length type */ + {0xf1000000, 0x08000000, 0x00100000, MT_DEVICE },/* SRAM bank 1 */ + {0xf2000000, 0x10000000, 0x00100000, MT_DEVICE },/* SRAM bank 2 */ + {0xf4000000, 0x48000000, 0x00100000, MT_DEVICE } /* SA-1111 */ +}; + +static void +badge4_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + if (!state) { + Ser1SDCR0 |= SDCR0_UART; + } +} + +static struct sa1100_port_fns badge4_port_fns __initdata = { + //.get_mctrl = badge4_get_mctrl, + //.set_mctrl = badge4_set_mctrl, + .pm = badge4_uart_pm, +}; + +static void __init badge4_map_io(void) +{ + sa1100_map_io(); + iotable_init(badge4_io_desc, ARRAY_SIZE(badge4_io_desc)); + + sa1100_register_uart_fns(&badge4_port_fns); + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); +} + +MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(badge4_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, +MACHINE_END diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c new file mode 100644 index 0000000..f8edde5 --- /dev/null +++ b/arch/arm/mach-sa1100/cerf.c @@ -0,0 +1,132 @@ +/* + * linux/arch/arm/mach-sa1100/cerf.c + * + * 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. + * + * Apr-2003 : Removed some old PDA crud [FB] + * Oct-2003 : Added uart2 resource [FB] + * Jan-2004 : Removed io map for flash [FB] + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/tty.h> +#include <linux/device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/setup.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> +#include <asm/mach/serial_sa1100.h> + +#include <asm/arch/cerf.h> +#include "generic.h" + +static struct resource cerfuart2_resources[] = { + [0] = { + .start = 0x80030000, + .end = 0x8003ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device cerfuart2_device = { + .name = "sa11x0-uart", + .id = 2, + .num_resources = ARRAY_SIZE(cerfuart2_resources), + .resource = cerfuart2_resources, +}; + +static struct platform_device *cerf_devices[] __initdata = { + &cerfuart2_device, +}; + +#ifdef CONFIG_SA1100_CERF_FLASH_32MB +# define CERF_FLASH_SIZE 0x02000000 +#elif defined CONFIG_SA1100_CERF_FLASH_16MB +# define CERF_FLASH_SIZE 0x01000000 +#elif defined CONFIG_SA1100_CERF_FLASH_8MB +# define CERF_FLASH_SIZE 0x00800000 +#else +# error "Undefined flash size for CERF" +#endif + +static struct mtd_partition cerf_partitions[] = { + { + .name = "Bootloader", + .size = 0x00020000, + .offset = 0x00000000, + }, { + .name = "Params", + .size = 0x00040000, + .offset = 0x00020000, + }, { + .name = "Kernel", + .size = 0x00100000, + .offset = 0x00060000, + }, { + .name = "Filesystem", + .size = CERF_FLASH_SIZE-0x00160000, + .offset = 0x00160000, + } +}; + +static struct flash_platform_data cerf_flash_data = { + .map_name = "cfi_probe", + .parts = cerf_partitions, + .nr_parts = ARRAY_SIZE(cerf_partitions), +}; + +static struct resource cerf_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static void __init cerf_init_irq(void) +{ + sa1100_init_irq(); + set_irq_type(CERF_ETH_IRQ, IRQT_RISING); +} + +static struct map_desc cerf_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xf0000000, 0x08000000, 0x00100000, MT_DEVICE } /* Crystal Ethernet Chip */ +}; + +static void __init cerf_map_io(void) +{ + sa1100_map_io(); + iotable_init(cerf_io_desc, ARRAY_SIZE(cerf_io_desc)); + + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 2); /* disable this and the uart2 device for sa1100_fir */ + sa1100_register_uart(2, 1); + + /* set some GPDR bits here while it's safe */ + GPDR |= CERF_GPIO_CF_RESET; +} + +static void __init cerf_init(void) +{ + platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices)); + sa11x0_set_flash_data(&cerf_flash_data, &cerf_flash_resource, 1); +} + +MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube") + MAINTAINER("support@intrinsyc.com") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + MAPIO(cerf_map_io) + INITIRQ(cerf_init_irq) + .timer = &sa1100_timer, + .init_machine = cerf_init, +MACHINE_END diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c new file mode 100644 index 0000000..9928789 --- /dev/null +++ b/arch/arm/mach-sa1100/collie.c @@ -0,0 +1,192 @@ +/* + * linux/arch/arm/mach-sa1100/collie.c + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains all Collie-specific tweaks. + * + * 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. + * + * ChangeLog: + * 03-06-2004 John Lenz <jelenz@wisc.edu> + * 06-04-2002 Chris Larson <kergoth@digitalnemesis.net> + * 04-16-2001 Lineo Japan,Inc. ... + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/tty.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/timer.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/arch/collie.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> +#include <asm/mach/serial_sa1100.h> + +#include <asm/hardware/scoop.h> +#include <asm/mach/sharpsl_param.h> +#include <asm/hardware/locomo.h> + +#include "generic.h" + +static struct resource collie_scoop_resources[] = { + [0] = { + .start = 0x40800000, + .end = 0x40800fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct scoop_config collie_scoop_setup = { + .io_dir = COLLIE_SCOOP_IO_DIR, + .io_out = COLLIE_SCOOP_IO_OUT, +}; + +struct platform_device colliescoop_device = { + .name = "sharp-scoop", + .id = -1, + .dev = { + .platform_data = &collie_scoop_setup, + }, + .num_resources = ARRAY_SIZE(collie_scoop_resources), + .resource = collie_scoop_resources, +}; + + +static struct resource locomo_resources[] = { + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO25, + .end = IRQ_GPIO25, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device locomo_device = { + .name = "locomo", + .id = 0, + .num_resources = ARRAY_SIZE(locomo_resources), + .resource = locomo_resources, +}; + +static struct platform_device *devices[] __initdata = { + &locomo_device, + &colliescoop_device, +}; + +static struct mtd_partition collie_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 0x000C0000, + .mask_flags = MTD_WRITEABLE + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 0x00100000, + }, { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 0x00e20000, + } +}; + +static void collie_set_vpp(int vpp) +{ + write_scoop_reg(SCOOP_GPCR, read_scoop_reg(SCOOP_GPCR) | COLLIE_SCP_VPEN); + if (vpp) { + write_scoop_reg(SCOOP_GPWR, read_scoop_reg(SCOOP_GPWR) | COLLIE_SCP_VPEN); + } else { + write_scoop_reg(SCOOP_GPWR, read_scoop_reg(SCOOP_GPWR) & ~COLLIE_SCP_VPEN); + } +} + +static struct flash_platform_data collie_flash_data = { + .map_name = "cfi_probe", + .set_vpp = collie_set_vpp, + .parts = collie_partitions, + .nr_parts = ARRAY_SIZE(collie_partitions), +}; + +static struct resource collie_flash_resources[] = { + { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static void __init collie_init(void) +{ + int ret = 0; + + /* cpu initialize */ + GAFR = ( GPIO_SSP_TXD | \ + GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK | GPIO_TIC_ACK | \ + GPIO_32_768kHz ); + + GPDR = ( GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 | \ + GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD | \ + GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK | \ + GPIO_SDLC_AAF | GPIO_UART_SCLK1 | GPIO_32_768kHz ); + GPLR = GPIO_GPIO18; + + // PPC pin setting + PPDR = ( PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 | \ + PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS | \ + PPC_TXD1 | PPC_TXD2 | PPC_RXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM ); + + PSDR = ( PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4 ); + + GAFR |= GPIO_32_768kHz; + GPDR |= GPIO_32_768kHz; + TUCR = TUCR_32_768kHz; + + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + if (ret) { + printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); + } + + sa11x0_set_flash_data(&collie_flash_data, collie_flash_resources, + ARRAY_SIZE(collie_flash_resources)); + + sharpsl_save_param(); +} + +static struct map_desc collie_io_desc[] __initdata = { + /* virtual physical length type */ + {0xe8000000, 0x00000000, 0x02000000, MT_DEVICE}, /* 32M main flash (cs0) */ + {0xea000000, 0x08000000, 0x02000000, MT_DEVICE}, /* 32M boot flash (cs1) */ +}; + +static void __init collie_map_io(void) +{ + sa1100_map_io(); + iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc)); +} + +MACHINE_START(COLLIE, "Sharp-Collie") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + MAPIO(collie_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, + .init_machine = collie_init, +MACHINE_END diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c new file mode 100644 index 0000000..6435b2e --- /dev/null +++ b/arch/arm/mach-sa1100/cpu-sa1100.c @@ -0,0 +1,249 @@ +/* + * cpu-sa1100.c: clock scaling for the SA1100 + * + * Copyright (C) 2000 2001, The Delft University of Technology + * + * Authors: + * - Johan Pouwelse (J.A.Pouwelse@its.tudelft.nl): initial version + * - Erik Mouw (J.A.K.Mouw@its.tudelft.nl): + * - major rewrite for linux-2.3.99 + * - rewritten for the more generic power management scheme in + * linux-2.4.5-rmk1 + * + * This software has been developed while working on the LART + * computing board (http://www.lart.tudelft.nl/), which is + * sponsored by the Mobile Multi-media Communications + * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications + * (http://www.ubicom.tudelft.nl/) projects. + * + * The authors can be reached at: + * + * Erik Mouw + * Information and Communication Theory Group + * Faculty of Information Technology and Systems + * Delft University of Technology + * P.O. Box 5031 + * 2600 GA Delft + * The Netherlands + * + * + * 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 + * + * + * Theory of operations + * ==================== + * + * Clock scaling can be used to lower the power consumption of the CPU + * core. This will give you a somewhat longer running time. + * + * The SA-1100 has a single register to change the core clock speed: + * + * PPCR 0x90020014 PLL config + * + * However, the DRAM timings are closely related to the core clock + * speed, so we need to change these, too. The used registers are: + * + * MDCNFG 0xA0000000 DRAM config + * MDCAS0 0xA0000004 Access waveform + * MDCAS1 0xA0000008 Access waveform + * MDCAS2 0xA000000C Access waveform + * + * Care must be taken to change the DRAM parameters the correct way, + * because otherwise the DRAM becomes unusable and the kernel will + * crash. + * + * The simple solution to avoid a kernel crash is to put the actual + * clock change in ROM and jump to that code from the kernel. The main + * disadvantage is that the ROM has to be modified, which is not + * possible on all SA-1100 platforms. Another disadvantage is that + * jumping to ROM makes clock switching unecessary complicated. + * + * The idea behind this driver is that the memory configuration can be + * changed while running from DRAM (even with interrupts turned on!) + * as long as all re-configuration steps yield a valid DRAM + * configuration. The advantages are clear: it will run on all SA-1100 + * platforms, and the code is very simple. + * + * If you really want to understand what is going on in + * sa1100_update_dram_timings(), you'll have to read sections 8.2, + * 9.5.7.3, and 10.2 from the "Intel StrongARM SA-1100 Microprocessor + * Developers Manual" (available for free from Intel). + * + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/cpufreq.h> + +#include <asm/hardware.h> + +#include "generic.h" + +typedef struct { + int speed; + u32 mdcnfg; + u32 mdcas0; + u32 mdcas1; + u32 mdcas2; +} sa1100_dram_regs_t; + + +static struct cpufreq_driver sa1100_driver; + +static sa1100_dram_regs_t sa1100_dram_settings[] = +{ + /* speed, mdcnfg, mdcas0, mdcas1, mdcas2 clock frequency */ + { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 59.0 MHz */ + { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 73.7 MHz */ + { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 88.5 MHz */ + { 103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 103.2 MHz */ + { 118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 118.0 MHz */ + { 132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 132.7 MHz */ + { 147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff }, /* 147.5 MHz */ + { 162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff }, /* 162.2 MHz */ + { 176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff }, /* 176.9 MHz */ + { 191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff }, /* 191.7 MHz */ + { 206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 206.4 MHz */ + { 221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 221.2 MHz */ + { 235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1 }, /* 235.9 MHz */ + { 250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 250.7 MHz */ + { 265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 265.4 MHz */ + { 280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87 }, /* 280.2 MHz */ + { 0, 0, 0, 0, 0 } /* last entry */ +}; + +static void sa1100_update_dram_timings(int current_speed, int new_speed) +{ + sa1100_dram_regs_t *settings = sa1100_dram_settings; + + /* find speed */ + while (settings->speed != 0) { + if(new_speed == settings->speed) + break; + + settings++; + } + + if (settings->speed == 0) { + panic("%s: couldn't find dram setting for speed %d\n", + __FUNCTION__, new_speed); + } + + /* No risk, no fun: run with interrupts on! */ + if (new_speed > current_speed) { + /* We're going FASTER, so first relax the memory + * timings before changing the core frequency + */ + + /* Half the memory access clock */ + MDCNFG |= MDCNFG_CDB2; + + /* The order of these statements IS important, keep 8 + * pulses!! + */ + MDCAS2 = settings->mdcas2; + MDCAS1 = settings->mdcas1; + MDCAS0 = settings->mdcas0; + MDCNFG = settings->mdcnfg; + } else { + /* We're going SLOWER: first decrease the core + * frequency and then tighten the memory settings. + */ + + /* Half the memory access clock */ + MDCNFG |= MDCNFG_CDB2; + + /* The order of these statements IS important, keep 8 + * pulses!! + */ + MDCAS0 = settings->mdcas0; + MDCAS1 = settings->mdcas1; + MDCAS2 = settings->mdcas2; + MDCNFG = settings->mdcnfg; + } +} + +static int sa1100_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int cur = sa11x0_getspeed(0); + unsigned int new_ppcr; + + struct cpufreq_freqs freqs; + switch(relation){ + case CPUFREQ_RELATION_L: + new_ppcr = sa11x0_freq_to_ppcr(target_freq); + if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max) + new_ppcr--; + break; + case CPUFREQ_RELATION_H: + new_ppcr = sa11x0_freq_to_ppcr(target_freq); + if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) && + (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min)) + new_ppcr--; + break; + } + + freqs.old = cur; + freqs.new = sa11x0_ppcr_to_freq(new_ppcr); + freqs.cpu = 0; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + if (freqs.new > cur) + sa1100_update_dram_timings(cur, freqs.new); + + PPCR = new_ppcr; + + if (freqs.new < cur) + sa1100_update_dram_timings(cur, freqs.new); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return 0; +} + +static int __init sa1100_cpu_init(struct cpufreq_policy *policy) +{ + if (policy->cpu != 0) + return -EINVAL; + policy->cur = policy->min = policy->max = sa11x0_getspeed(0); + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.min_freq = 59000; + policy->cpuinfo.max_freq = 287000; + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + return 0; +} + +static struct cpufreq_driver sa1100_driver = { + .flags = CPUFREQ_STICKY, + .verify = sa11x0_verify_speed, + .target = sa1100_target, + .get = sa11x0_getspeed, + .init = sa1100_cpu_init, + .name = "sa1100", +}; + +static int __init sa1100_dram_init(void) +{ + if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) + return cpufreq_register_driver(&sa1100_driver); + else + return -ENODEV; +} + +arch_initcall(sa1100_dram_init); diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c new file mode 100644 index 0000000..8d2a89a --- /dev/null +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -0,0 +1,367 @@ +/* + * linux/arch/arm/mach-sa1100/cpu-sa1110.c + * + * Copyright (C) 2001 Russell King + * + * $Id: cpu-sa1110.c,v 1.9 2002/07/06 16:53:18 rmk Exp $ + * + * 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. + * + * Note: there are two erratas that apply to the SA1110 here: + * 7 - SDRAM auto-power-up failure (rev A0) + * 13 - Corruption of internal register reads/writes following + * SDRAM reads (rev A0, B0, B1) + * + * We ignore rev. A0 and B0 devices; I don't think they're worth supporting. + */ +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/cpufreq.h> +#include <linux/delay.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/io.h> +#include <asm/system.h> + +#include "generic.h" + +#undef DEBUG + +static struct cpufreq_driver sa1110_driver; + +struct sdram_params { + u_char rows; /* bits */ + u_char cas_latency; /* cycles */ + u_char tck; /* clock cycle time (ns) */ + u_char trcd; /* activate to r/w (ns) */ + u_char trp; /* precharge to activate (ns) */ + u_char twr; /* write recovery time (ns) */ + u_short refresh; /* refresh time for array (us) */ +}; + +struct sdram_info { + u_int mdcnfg; + u_int mdrefr; + u_int mdcas[3]; +}; + +static struct sdram_params tc59sm716_cl2_params __initdata = { + .rows = 12, + .tck = 10, + .trcd = 20, + .trp = 20, + .twr = 10, + .refresh = 64000, + .cas_latency = 2, +}; + +static struct sdram_params tc59sm716_cl3_params __initdata = { + .rows = 12, + .tck = 8, + .trcd = 20, + .trp = 20, + .twr = 8, + .refresh = 64000, + .cas_latency = 3, +}; + +static struct sdram_params samsung_k4s641632d_tc75 __initdata = { + .rows = 14, + .tck = 9, + .trcd = 27, + .trp = 20, + .twr = 9, + .refresh = 64000, + .cas_latency = 3, +}; + +static struct sdram_params samsung_km416s4030ct __initdata = { + .rows = 13, + .tck = 8, + .trcd = 24, /* 3 CLKs */ + .trp = 24, /* 3 CLKs */ + .twr = 16, /* Trdl: 2 CLKs */ + .refresh = 64000, + .cas_latency = 3, +}; + +static struct sdram_params wbond_w982516ah75l_cl3_params __initdata = { + .rows = 16, + .tck = 8, + .trcd = 20, + .trp = 20, + .twr = 8, + .refresh = 64000, + .cas_latency = 3, +}; + +static struct sdram_params sdram_params; + +/* + * Given a period in ns and frequency in khz, calculate the number of + * cycles of frequency in period. Note that we round up to the next + * cycle, even if we are only slightly over. + */ +static inline u_int ns_to_cycles(u_int ns, u_int khz) +{ + return (ns * khz + 999999) / 1000000; +} + +/* + * Create the MDCAS register bit pattern. + */ +static inline void set_mdcas(u_int *mdcas, int delayed, u_int rcd) +{ + u_int shift; + + rcd = 2 * rcd - 1; + shift = delayed + 1 + rcd; + + mdcas[0] = (1 << rcd) - 1; + mdcas[0] |= 0x55555555 << shift; + mdcas[1] = mdcas[2] = 0x55555555 << (shift & 1); +} + +static void +sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz, + struct sdram_params *sdram) +{ + u_int mem_khz, sd_khz, trp, twr; + + mem_khz = cpu_khz / 2; + sd_khz = mem_khz; + + /* + * If SDCLK would invalidate the SDRAM timings, + * run SDCLK at half speed. + * + * CPU steppings prior to B2 must either run the memory at + * half speed or use delayed read latching (errata 13). + */ + if ((ns_to_cycles(sdram->tck, sd_khz) > 1) || + (CPU_REVISION < CPU_SA1110_B2 && sd_khz < 62000)) + sd_khz /= 2; + + sd->mdcnfg = MDCNFG & 0x007f007f; + + twr = ns_to_cycles(sdram->twr, mem_khz); + + /* trp should always be >1 */ + trp = ns_to_cycles(sdram->trp, mem_khz) - 1; + if (trp < 1) + trp = 1; + + sd->mdcnfg |= trp << 8; + sd->mdcnfg |= trp << 24; + sd->mdcnfg |= sdram->cas_latency << 12; + sd->mdcnfg |= sdram->cas_latency << 28; + sd->mdcnfg |= twr << 14; + sd->mdcnfg |= twr << 30; + + sd->mdrefr = MDREFR & 0xffbffff0; + sd->mdrefr |= 7; + + if (sd_khz != mem_khz) + sd->mdrefr |= MDREFR_K1DB2; + + /* initial number of '1's in MDCAS + 1 */ + set_mdcas(sd->mdcas, sd_khz >= 62000, ns_to_cycles(sdram->trcd, mem_khz)); + +#ifdef DEBUG + printk("MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n", + sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1], sd->mdcas[2]); +#endif +} + +/* + * Set the SDRAM refresh rate. + */ +static inline void sdram_set_refresh(u_int dri) +{ + MDREFR = (MDREFR & 0xffff000f) | (dri << 4); + (void) MDREFR; +} + +/* + * Update the refresh period. We do this such that we always refresh + * the SDRAMs within their permissible period. The refresh period is + * always a multiple of the memory clock (fixed at cpu_clock / 2). + * + * FIXME: we don't currently take account of burst accesses here, + * but neither do Intels DM nor Angel. + */ +static void +sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) +{ + u_int ns_row = (sdram->refresh * 1000) >> sdram->rows; + u_int dri = ns_to_cycles(ns_row, cpu_khz / 2) / 32; + +#ifdef DEBUG + mdelay(250); + printk("new dri value = %d\n", dri); +#endif + + sdram_set_refresh(dri); +} + +/* + * Ok, set the CPU frequency. + */ +static int sa1110_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + struct sdram_params *sdram = &sdram_params; + struct cpufreq_freqs freqs; + struct sdram_info sd; + unsigned long flags; + unsigned int ppcr, unused; + + switch(relation){ + case CPUFREQ_RELATION_L: + ppcr = sa11x0_freq_to_ppcr(target_freq); + if (sa11x0_ppcr_to_freq(ppcr) > policy->max) + ppcr--; + break; + case CPUFREQ_RELATION_H: + ppcr = sa11x0_freq_to_ppcr(target_freq); + if (ppcr && (sa11x0_ppcr_to_freq(ppcr) > target_freq) && + (sa11x0_ppcr_to_freq(ppcr-1) >= policy->min)) + ppcr--; + break; + default: + return -EINVAL; + } + + freqs.old = sa11x0_getspeed(0); + freqs.new = sa11x0_ppcr_to_freq(ppcr); + freqs.cpu = 0; + + sdram_calculate_timing(&sd, freqs.new, sdram); + +#if 0 + /* + * These values are wrong according to the SA1110 documentation + * and errata, but they seem to work. Need to get a storage + * scope on to the SDRAM signals to work out why. + */ + if (policy->max < 147500) { + sd.mdrefr |= MDREFR_K1DB2; + sd.mdcas[0] = 0xaaaaaa7f; + } else { + sd.mdrefr &= ~MDREFR_K1DB2; + sd.mdcas[0] = 0xaaaaaa9f; + } + sd.mdcas[1] = 0xaaaaaaaa; + sd.mdcas[2] = 0xaaaaaaaa; +#endif + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + /* + * The clock could be going away for some time. Set the SDRAMs + * to refresh rapidly (every 64 memory clock cycles). To get + * through the whole array, we need to wait 262144 mclk cycles. + * We wait 20ms to be safe. + */ + sdram_set_refresh(2); + if (!irqs_disabled()) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(20 * HZ / 1000); + } else { + mdelay(20); + } + + /* + * Reprogram the DRAM timings with interrupts disabled, and + * ensure that we are doing this within a complete cache line. + * This means that we won't access SDRAM for the duration of + * the programming. + */ + local_irq_save(flags); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); + udelay(10); + __asm__ __volatile__(" \n\ + b 2f \n\ + .align 5 \n\ +1: str %3, [%1, #0] @ MDCNFG \n\ + str %4, [%1, #28] @ MDREFR \n\ + str %5, [%1, #4] @ MDCAS0 \n\ + str %6, [%1, #8] @ MDCAS1 \n\ + str %7, [%1, #12] @ MDCAS2 \n\ + str %8, [%2, #0] @ PPCR \n\ + ldr %0, [%1, #0] \n\ + b 3f \n\ +2: b 1b \n\ +3: nop \n\ + nop" + : "=&r" (unused) + : "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg), + "r" (sd.mdrefr), "r" (sd.mdcas[0]), + "r" (sd.mdcas[1]), "r" (sd.mdcas[2]), "r" (ppcr)); + local_irq_restore(flags); + + /* + * Now, return the SDRAM refresh back to normal. + */ + sdram_update_refresh(freqs.new, sdram); + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return 0; +} + +static int __init sa1110_cpu_init(struct cpufreq_policy *policy) +{ + if (policy->cpu != 0) + return -EINVAL; + policy->cur = policy->min = policy->max = sa11x0_getspeed(0); + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.min_freq = 59000; + policy->cpuinfo.max_freq = 287000; + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + return 0; +} + +static struct cpufreq_driver sa1110_driver = { + .flags = CPUFREQ_STICKY, + .verify = sa11x0_verify_speed, + .target = sa1110_target, + .get = sa11x0_getspeed, + .init = sa1110_cpu_init, + .name = "sa1110", +}; + +static int __init sa1110_clk_init(void) +{ + struct sdram_params *sdram = NULL; + + if (machine_is_assabet()) + sdram = &tc59sm716_cl3_params; + + if (machine_is_pt_system3()) + sdram = &samsung_k4s641632d_tc75; + + if (machine_is_h3100()) + sdram = &samsung_km416s4030ct; + + if (sdram) { + printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d" + " twr: %d refresh: %d cas_latency: %d\n", + sdram->tck, sdram->trcd, sdram->trp, + sdram->twr, sdram->refresh, sdram->cas_latency); + + memcpy(&sdram_params, sdram, sizeof(sdram_params)); + + return cpufreq_register_driver(&sa1110_driver); + } + + return 0; +} + +arch_initcall(sa1110_clk_init); diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c new file mode 100644 index 0000000..be0e442 --- /dev/null +++ b/arch/arm/mach-sa1100/dma.c @@ -0,0 +1,348 @@ +/* + * arch/arm/kernel/dma-sa1100.c + * + * Support functions for the SA11x0 internal DMA channels. + * + * Copyright (C) 2000, 2001 by Nicolas Pitre + * + * 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/module.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/errno.h> + +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/dma.h> + + +#undef DEBUG +#ifdef DEBUG +#define DPRINTK( s, arg... ) printk( "dma<%p>: " s, regs , ##arg ) +#else +#define DPRINTK( x... ) +#endif + + +typedef struct { + const char *device_id; /* device name */ + u_long device; /* this channel device, 0 if unused*/ + dma_callback_t callback; /* to call when DMA completes */ + void *data; /* ... with private data ptr */ +} sa1100_dma_t; + +static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS]; + +static spinlock_t dma_list_lock; + + +static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + dma_regs_t *dma_regs = dev_id; + sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7); + int status = dma_regs->RdDCSR; + + if (status & (DCSR_ERROR)) { + printk(KERN_CRIT "DMA on \"%s\" caused an error\n", dma->device_id); + dma_regs->ClrDCSR = DCSR_ERROR; + } + + dma_regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB); + if (dma->callback) { + if (status & DCSR_DONEA) + dma->callback(dma->data); + if (status & DCSR_DONEB) + dma->callback(dma->data); + } + return IRQ_HANDLED; +} + + +/** + * sa1100_request_dma - allocate one of the SA11x0's DMA chanels + * @device: The SA11x0 peripheral targeted by this request + * @device_id: An ascii name for the claiming device + * @callback: Function to be called when the DMA completes + * @data: A cookie passed back to the callback function + * @dma_regs: Pointer to the location of the allocated channel's identifier + * + * This function will search for a free DMA channel and returns the + * address of the hardware registers for that channel as the channel + * identifier. This identifier is written to the location pointed by + * @dma_regs. The list of possible values for @device are listed into + * linux/include/asm-arm/arch-sa1100/dma.h as a dma_device_t enum. + * + * Note that reading from a port and writing to the same port are + * actually considered as two different streams requiring separate + * DMA registrations. + * + * The @callback function is called from interrupt context when one + * of the two possible DMA buffers in flight has terminated. That + * function has to be small and efficient while posponing more complex + * processing to a lower priority execution context. + * + * If no channels are available, or if the desired @device is already in + * use by another DMA channel, then an error code is returned. This + * function must be called before any other DMA calls. + **/ + +int sa1100_request_dma (dma_device_t device, const char *device_id, + dma_callback_t callback, void *data, + dma_regs_t **dma_regs) +{ + sa1100_dma_t *dma = NULL; + dma_regs_t *regs; + int i, err; + + *dma_regs = NULL; + + err = 0; + spin_lock(&dma_list_lock); + for (i = 0; i < SA1100_DMA_CHANNELS; i++) { + if (dma_chan[i].device == device) { + err = -EBUSY; + break; + } else if (!dma_chan[i].device && !dma) { + dma = &dma_chan[i]; + } + } + if (!err) { + if (dma) + dma->device = device; + else + err = -ENOSR; + } + spin_unlock(&dma_list_lock); + if (err) + return err; + + i = dma - dma_chan; + regs = (dma_regs_t *)&DDAR(i); + err = request_irq(IRQ_DMA0 + i, dma_irq_handler, SA_INTERRUPT, + device_id, regs); + if (err) { + printk(KERN_ERR + "%s: unable to request IRQ %d for %s\n", + __FUNCTION__, IRQ_DMA0 + i, device_id); + dma->device = 0; + return err; + } + + *dma_regs = regs; + dma->device_id = device_id; + dma->callback = callback; + dma->data = data; + + regs->ClrDCSR = + (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | + DCSR_IE | DCSR_ERROR | DCSR_RUN); + regs->DDAR = device; + + return 0; +} + + +/** + * sa1100_free_dma - free a SA11x0 DMA channel + * @regs: identifier for the channel to free + * + * This clears all activities on a given DMA channel and releases it + * for future requests. The @regs identifier is provided by a + * successful call to sa1100_request_dma(). + **/ + +void sa1100_free_dma(dma_regs_t *regs) +{ + int i; + + for (i = 0; i < SA1100_DMA_CHANNELS; i++) + if (regs == (dma_regs_t *)&DDAR(i)) + break; + if (i >= SA1100_DMA_CHANNELS) { + printk(KERN_ERR "%s: bad DMA identifier\n", __FUNCTION__); + return; + } + + if (!dma_chan[i].device) { + printk(KERN_ERR "%s: Trying to free free DMA\n", __FUNCTION__); + return; + } + + regs->ClrDCSR = + (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | + DCSR_IE | DCSR_ERROR | DCSR_RUN); + free_irq(IRQ_DMA0 + i, regs); + dma_chan[i].device = 0; +} + + +/** + * sa1100_start_dma - submit a data buffer for DMA + * @regs: identifier for the channel to use + * @dma_ptr: buffer physical (or bus) start address + * @size: buffer size + * + * This function hands the given data buffer to the hardware for DMA + * access. If another buffer is already in flight then this buffer + * will be queued so the DMA engine will switch to it automatically + * when the previous one is done. The DMA engine is actually toggling + * between two buffers so at most 2 successful calls can be made before + * one of them terminates and the callback function is called. + * + * The @regs identifier is provided by a successful call to + * sa1100_request_dma(). + * + * The @size must not be larger than %MAX_DMA_SIZE. If a given buffer + * is larger than that then it's the caller's responsibility to split + * it into smaller chunks and submit them separately. If this is the + * case then a @size of %CUT_DMA_SIZE is recommended to avoid ending + * up with too small chunks. The callback function can be used to chain + * submissions of buffer chunks. + * + * Error return values: + * %-EOVERFLOW: Given buffer size is too big. + * %-EBUSY: Both DMA buffers are already in use. + * %-EAGAIN: Both buffers were busy but one of them just completed + * but the interrupt handler has to execute first. + * + * This function returs 0 on success. + **/ + +int sa1100_start_dma(dma_regs_t *regs, dma_addr_t dma_ptr, u_int size) +{ + unsigned long flags; + u_long status; + int ret; + + if (dma_ptr & 3) + printk(KERN_WARNING "DMA: unaligned start address (0x%08lx)\n", + (unsigned long)dma_ptr); + + if (size > MAX_DMA_SIZE) + return -EOVERFLOW; + + local_irq_save(flags); + status = regs->RdDCSR; + + /* If both DMA buffers are started, there's nothing else we can do. */ + if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) { + DPRINTK("start: st %#x busy\n", status); + ret = -EBUSY; + goto out; + } + + if (((status & DCSR_BIU) && (status & DCSR_STRTB)) || + (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) { + if (status & DCSR_DONEA) { + /* give a chance for the interrupt to be processed */ + ret = -EAGAIN; + goto out; + } + regs->DBSA = dma_ptr; + regs->DBTA = size; + regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN; + DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size); + } else { + if (status & DCSR_DONEB) { + /* give a chance for the interrupt to be processed */ + ret = -EAGAIN; + goto out; + } + regs->DBSB = dma_ptr; + regs->DBTB = size; + regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN; + DPRINTK("start a=%#x s=%d on B\n", dma_ptr, size); + } + ret = 0; + +out: + local_irq_restore(flags); + return ret; +} + + +/** + * sa1100_get_dma_pos - return current DMA position + * @regs: identifier for the channel to use + * + * This function returns the current physical (or bus) address for the + * given DMA channel. If the channel is running i.e. not in a stopped + * state then the caller must disable interrupts prior calling this + * function and process the returned value before re-enabling them to + * prevent races with the completion interrupt handler and the callback + * function. The validation of the returned value is the caller's + * responsibility as well -- the hardware seems to return out of range + * values when the DMA engine completes a buffer. + * + * The @regs identifier is provided by a successful call to + * sa1100_request_dma(). + **/ + +dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs) +{ + int status; + + /* + * We must determine whether buffer A or B is active. + * Two possibilities: either we are in the middle of + * a buffer, or the DMA controller just switched to the + * next toggle but the interrupt hasn't been serviced yet. + * The former case is straight forward. In the later case, + * we'll do like if DMA is just at the end of the previous + * toggle since all registers haven't been reset yet. + * This goes around the edge case and since we're always + * a little behind anyways it shouldn't make a big difference. + * If DMA has been stopped prior calling this then the + * position is exact. + */ + status = regs->RdDCSR; + if ((!(status & DCSR_BIU) && (status & DCSR_STRTA)) || + ( (status & DCSR_BIU) && !(status & DCSR_STRTB))) + return regs->DBSA; + else + return regs->DBSB; +} + + +/** + * sa1100_reset_dma - reset a DMA channel + * @regs: identifier for the channel to use + * + * This function resets and reconfigure the given DMA channel. This is + * particularly useful after a sleep/wakeup event. + * + * The @regs identifier is provided by a successful call to + * sa1100_request_dma(). + **/ + +void sa1100_reset_dma(dma_regs_t *regs) +{ + int i; + + for (i = 0; i < SA1100_DMA_CHANNELS; i++) + if (regs == (dma_regs_t *)&DDAR(i)) + break; + if (i >= SA1100_DMA_CHANNELS) { + printk(KERN_ERR "%s: bad DMA identifier\n", __FUNCTION__); + return; + } + + regs->ClrDCSR = + (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB | + DCSR_IE | DCSR_ERROR | DCSR_RUN); + regs->DDAR = dma_chan[i].device; +} + + +EXPORT_SYMBOL(sa1100_request_dma); +EXPORT_SYMBOL(sa1100_free_dma); +EXPORT_SYMBOL(sa1100_start_dma); +EXPORT_SYMBOL(sa1100_get_dma_pos); +EXPORT_SYMBOL(sa1100_reset_dma); + diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c new file mode 100644 index 0000000..95ae217 --- /dev/null +++ b/arch/arm/mach-sa1100/generic.c @@ -0,0 +1,419 @@ +/* + * linux/arch/arm/mach-sa1100/generic.c + * + * Author: Nicolas Pitre + * + * Code common to all SA11x0 machines. + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/cpufreq.h> +#include <linux/ioport.h> + +#include <asm/div64.h> +#include <asm/hardware.h> +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/mach/map.h> +#include <asm/irq.h> + +#include "generic.h" + +#define NR_FREQS 16 + +/* + * This table is setup for a 3.6864MHz Crystal. + */ +static const unsigned short cclk_frequency_100khz[NR_FREQS] = { + 590, /* 59.0 MHz */ + 737, /* 73.7 MHz */ + 885, /* 88.5 MHz */ + 1032, /* 103.2 MHz */ + 1180, /* 118.0 MHz */ + 1327, /* 132.7 MHz */ + 1475, /* 147.5 MHz */ + 1622, /* 162.2 MHz */ + 1769, /* 176.9 MHz */ + 1917, /* 191.7 MHz */ + 2064, /* 206.4 MHz */ + 2212, /* 221.2 MHz */ + 2359, /* 235.9 MHz */ + 2507, /* 250.7 MHz */ + 2654, /* 265.4 MHz */ + 2802 /* 280.2 MHz */ +}; + +#if defined(CONFIG_CPU_FREQ_SA1100) || defined(CONFIG_CPU_FREQ_SA1110) +/* rounds up(!) */ +unsigned int sa11x0_freq_to_ppcr(unsigned int khz) +{ + int i; + + khz /= 100; + + for (i = 0; i < NR_FREQS; i++) + if (cclk_frequency_100khz[i] >= khz) + break; + + return i; +} + +unsigned int sa11x0_ppcr_to_freq(unsigned int idx) +{ + unsigned int freq = 0; + if (idx < NR_FREQS) + freq = cclk_frequency_100khz[idx] * 100; + return freq; +} + + +/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on + * this platform, anyway. + */ +int sa11x0_verify_speed(struct cpufreq_policy *policy) +{ + unsigned int tmp; + if (policy->cpu) + return -EINVAL; + + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); + + /* make sure that at least one frequency is within the policy */ + tmp = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->min)] * 100; + if (tmp > policy->max) + policy->max = tmp; + + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); + + return 0; +} + +unsigned int sa11x0_getspeed(unsigned int cpu) +{ + if (cpu) + return 0; + return cclk_frequency_100khz[PPCR & 0xf] * 100; +} + +#else +/* + * We still need to provide this so building without cpufreq works. + */ +unsigned int cpufreq_get(unsigned int cpu) +{ + return cclk_frequency_100khz[PPCR & 0xf] * 100; +} +EXPORT_SYMBOL(cpufreq_get); +#endif + +/* + * This is the SA11x0 sched_clock implementation. This has + * a resolution of 271ns, and a maximum value of 1165s. + * ( * 1E9 / 3686400 => * 78125 / 288) + */ +unsigned long long sched_clock(void) +{ + unsigned long long v; + + v = (unsigned long long)OSCR * 78125; + do_div(v, 288); + + return v; +} + +/* + * Default power-off for SA1100 + */ +static void sa1100_power_off(void) +{ + mdelay(100); + local_irq_disable(); + /* disable internal oscillator, float CS lines */ + PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); + /* enable wake-up on GPIO0 (Assabet...) */ + PWER = GFER = GRER = 1; + /* + * set scratchpad to zero, just in case it is used as a + * restart address by the bootloader. + */ + PSPR = 0; + /* enter sleep mode */ + PMCR = PMCR_SF; +} + +static struct resource sa11x0udc_resources[] = { + [0] = { + .start = 0x80000000, + .end = 0x8000ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static u64 sa11x0udc_dma_mask = 0xffffffffUL; + +static struct platform_device sa11x0udc_device = { + .name = "sa11x0-udc", + .id = -1, + .dev = { + .dma_mask = &sa11x0udc_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(sa11x0udc_resources), + .resource = sa11x0udc_resources, +}; + +static struct resource sa11x0uart1_resources[] = { + [0] = { + .start = 0x80010000, + .end = 0x8001ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device sa11x0uart1_device = { + .name = "sa11x0-uart", + .id = 1, + .num_resources = ARRAY_SIZE(sa11x0uart1_resources), + .resource = sa11x0uart1_resources, +}; + +static struct resource sa11x0uart3_resources[] = { + [0] = { + .start = 0x80050000, + .end = 0x8005ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device sa11x0uart3_device = { + .name = "sa11x0-uart", + .id = 3, + .num_resources = ARRAY_SIZE(sa11x0uart3_resources), + .resource = sa11x0uart3_resources, +}; + +static struct resource sa11x0mcp_resources[] = { + [0] = { + .start = 0x80060000, + .end = 0x8006ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static u64 sa11x0mcp_dma_mask = 0xffffffffUL; + +static struct platform_device sa11x0mcp_device = { + .name = "sa11x0-mcp", + .id = -1, + .dev = { + .dma_mask = &sa11x0mcp_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(sa11x0mcp_resources), + .resource = sa11x0mcp_resources, +}; + +static struct resource sa11x0ssp_resources[] = { + [0] = { + .start = 0x80070000, + .end = 0x8007ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static u64 sa11x0ssp_dma_mask = 0xffffffffUL; + +static struct platform_device sa11x0ssp_device = { + .name = "sa11x0-ssp", + .id = -1, + .dev = { + .dma_mask = &sa11x0ssp_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(sa11x0ssp_resources), + .resource = sa11x0ssp_resources, +}; + +static struct resource sa11x0fb_resources[] = { + [0] = { + .start = 0xb0100000, + .end = 0xb010ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sa11x0fb_device = { + .name = "sa11x0-fb", + .id = -1, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(sa11x0fb_resources), + .resource = sa11x0fb_resources, +}; + +static struct platform_device sa11x0pcmcia_device = { + .name = "sa11x0-pcmcia", + .id = -1, +}; + +static struct platform_device sa11x0mtd_device = { + .name = "flash", + .id = -1, +}; + +void sa11x0_set_flash_data(struct flash_platform_data *flash, + struct resource *res, int nr) +{ + sa11x0mtd_device.dev.platform_data = flash; + sa11x0mtd_device.resource = res; + sa11x0mtd_device.num_resources = nr; +} + +static struct resource sa11x0ir_resources[] = { + { + .start = __PREG(Ser2UTCR0), + .end = __PREG(Ser2UTCR0) + 0x24 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = __PREG(Ser2HSCR0), + .end = __PREG(Ser2HSCR0) + 0x1c - 1, + .flags = IORESOURCE_MEM, + }, { + .start = __PREG(Ser2HSCR2), + .end = __PREG(Ser2HSCR2) + 0x04 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_Ser2ICP, + .end = IRQ_Ser2ICP, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device sa11x0ir_device = { + .name = "sa11x0-ir", + .id = -1, + .num_resources = ARRAY_SIZE(sa11x0ir_resources), + .resource = sa11x0ir_resources, +}; + +void sa11x0_set_irda_data(struct irda_platform_data *irda) +{ + sa11x0ir_device.dev.platform_data = irda; +} + +static struct platform_device *sa11x0_devices[] __initdata = { + &sa11x0udc_device, + &sa11x0uart1_device, + &sa11x0uart3_device, + &sa11x0mcp_device, + &sa11x0ssp_device, + &sa11x0pcmcia_device, + &sa11x0fb_device, + &sa11x0mtd_device, +}; + +static int __init sa1100_init(void) +{ + pm_power_off = sa1100_power_off; + + if (sa11x0ir_device.dev.platform_data) + platform_device_register(&sa11x0ir_device); + + return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices)); +} + +arch_initcall(sa1100_init); + +void (*sa1100fb_backlight_power)(int on); +void (*sa1100fb_lcd_power)(int on); + +EXPORT_SYMBOL(sa1100fb_backlight_power); +EXPORT_SYMBOL(sa1100fb_lcd_power); + + +/* + * Common I/O mapping: + * + * Typically, static virtual address mappings are as follow: + * + * 0xf0000000-0xf3ffffff: miscellaneous stuff (CPLDs, etc.) + * 0xf4000000-0xf4ffffff: SA-1111 + * 0xf5000000-0xf5ffffff: reserved (used by cache flushing area) + * 0xf6000000-0xfffeffff: reserved (internal SA1100 IO defined above) + * 0xffff0000-0xffff0fff: SA1100 exception vectors + * 0xffff2000-0xffff2fff: Minicache copy_user_page area + * + * Below 0xe8000000 is reserved for vm allocation. + * + * The machine specific code must provide the extra mapping beside the + * default mapping provided here. + */ + +static struct map_desc standard_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xf8000000, 0x80000000, 0x00100000, MT_DEVICE }, /* PCM */ + { 0xfa000000, 0x90000000, 0x00100000, MT_DEVICE }, /* SCM */ + { 0xfc000000, 0xa0000000, 0x00100000, MT_DEVICE }, /* MER */ + { 0xfe000000, 0xb0000000, 0x00200000, MT_DEVICE } /* LCD + DMA */ +}; + +void __init sa1100_map_io(void) +{ + iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); +} + +/* + * Disable the memory bus request/grant signals on the SA1110 to + * ensure that we don't receive spurious memory requests. We set + * the MBGNT signal false to ensure the SA1111 doesn't own the + * SDRAM bus. + */ +void __init sa1110_mb_disable(void) +{ + unsigned long flags; + + local_irq_save(flags); + + PGSR &= ~GPIO_MBGNT; + GPCR = GPIO_MBGNT; + GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT; + + GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ); + + local_irq_restore(flags); +} + +/* + * If the system is going to use the SA-1111 DMA engines, set up + * the memory bus request/grant pins. + */ +void __init sa1110_mb_enable(void) +{ + unsigned long flags; + + local_irq_save(flags); + + PGSR &= ~GPIO_MBGNT; + GPCR = GPIO_MBGNT; + GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT; + + GAFR |= (GPIO_MBGNT | GPIO_MBREQ); + TUCR |= TUCR_MR; + + local_irq_restore(flags); +} + diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h new file mode 100644 index 0000000..bfe41da --- /dev/null +++ b/arch/arm/mach-sa1100/generic.h @@ -0,0 +1,38 @@ +/* + * linux/arch/arm/mach-sa1100/generic.h + * + * Author: Nicolas Pitre + */ + +struct sys_timer; + +extern struct sys_timer sa1100_timer; +extern void __init sa1100_map_io(void); +extern void __init sa1100_init_irq(void); + +#define SET_BANK(__nr,__start,__size) \ + mi->bank[__nr].start = (__start), \ + mi->bank[__nr].size = (__size), \ + mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) + +extern void (*sa1100fb_backlight_power)(int on); +extern void (*sa1100fb_lcd_power)(int on); + +extern void sa1110_mb_enable(void); +extern void sa1110_mb_disable(void); + +struct cpufreq_policy; + +extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); +extern int sa11x0_verify_speed(struct cpufreq_policy *policy); +extern unsigned int sa11x0_getspeed(unsigned int cpu); +extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx); + +struct flash_platform_data; +struct resource; + +extern void sa11x0_set_flash_data(struct flash_platform_data *flash, + struct resource *res, int nr); + +struct irda_platform_data; +void sa11x0_set_irda_data(struct irda_platform_data *irda); diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c new file mode 100644 index 0000000..9788d3a --- /dev/null +++ b/arch/arm/mach-sa1100/h3600.c @@ -0,0 +1,892 @@ +/* + * Hardware definitions for Compaq iPAQ H3xxx Handheld Computers + * + * Copyright 2000,1 Compaq Computer Corporation. + * + * Use consistent with the GNU GPL is permitted, + * provided that this copyright notice is + * preserved in its entirety in all copies and derived works. + * + * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, + * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS + * FITNESS FOR ANY PARTICULAR PURPOSE. + * + * Author: Jamey Hicks. + * + * History: + * + * 2001-10-?? Andrew Christian Added support for iPAQ H3800 + * and abstracted EGPIO interface. + * + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/tty.h> +#include <linux/pm.h> +#include <linux/device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/serial_core.h> + +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/setup.h> + +#include <asm/mach/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/irda.h> +#include <asm/mach/map.h> +#include <asm/mach/serial_sa1100.h> + +#include <asm/arch/h3600.h> + +#if defined (CONFIG_SA1100_H3600) || defined (CONFIG_SA1100_H3100) +#include <asm/arch/h3600_gpio.h> +#endif + +#ifdef CONFIG_SA1100_H3800 +#include <asm/arch/h3600_asic.h> +#endif + +#include "generic.h" + +struct ipaq_model_ops ipaq_model_ops; +EXPORT_SYMBOL(ipaq_model_ops); + +static struct mtd_partition h3xxx_partitions[] = { + { + .name = "H3XXX boot firmware", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { +#ifdef CONFIG_MTD_2PARTS_IPAQ + .name = "H3XXX root jffs2", + .size = MTDPART_SIZ_FULL, + .offset = 0x00040000, +#else + .name = "H3XXX kernel", + .size = 0x00080000, + .offset = 0x00040000, + }, { + .name = "H3XXX params", + .size = 0x00040000, + .offset = 0x000C0000, + }, { +#ifdef CONFIG_JFFS2_FS + .name = "H3XXX root jffs2", + .size = MTDPART_SIZ_FULL, + .offset = 0x00100000, +#else + .name = "H3XXX initrd", + .size = 0x00100000, + .offset = 0x00100000, + }, { + .name = "H3XXX root cramfs", + .size = 0x00300000, + .offset = 0x00200000, + }, { + .name = "H3XXX usr cramfs", + .size = 0x00800000, + .offset = 0x00500000, + }, { + .name = "H3XXX usr local", + .size = MTDPART_SIZ_FULL, + .offset = 0x00d00000, +#endif +#endif + } +}; + +static void h3xxx_set_vpp(int vpp) +{ + assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp); +} + +static struct flash_platform_data h3xxx_flash_data = { + .map_name = "cfi_probe", + .set_vpp = h3xxx_set_vpp, + .parts = h3xxx_partitions, + .nr_parts = ARRAY_SIZE(h3xxx_partitions), +}; + +static struct resource h3xxx_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +/* + * This turns the IRDA power on or off on the Compaq H3600 + */ +static int h3600_irda_set_power(struct device *dev, unsigned int state) +{ + assign_h3600_egpio( IPAQ_EGPIO_IR_ON, state ); + + return 0; +} + +static void h3600_irda_set_speed(struct device *dev, int speed) +{ + if (speed < 4000000) { + clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL); + } else { + set_h3600_egpio(IPAQ_EGPIO_IR_FSEL); + } +} + +static struct irda_platform_data h3600_irda_data = { + .set_power = h3600_irda_set_power, + .set_speed = h3600_irda_set_speed, +}; + +static void h3xxx_mach_init(void) +{ + sa11x0_set_flash_data(&h3xxx_flash_data, &h3xxx_flash_resource, 1); + sa11x0_set_irda_data(&h3600_irda_data); +} + +/* + * low-level UART features + */ + +static void h3600_uart_set_mctrl(struct uart_port *port, u_int mctrl) +{ + if (port->mapbase == _Ser3UTCR0) { + if (mctrl & TIOCM_RTS) + GPCR = GPIO_H3600_COM_RTS; + else + GPSR = GPIO_H3600_COM_RTS; + } +} + +static u_int h3600_uart_get_mctrl(struct uart_port *port) +{ + u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; + + if (port->mapbase == _Ser3UTCR0) { + int gplr = GPLR; + /* DCD and CTS bits are inverted in GPLR by RS232 transceiver */ + if (gplr & GPIO_H3600_COM_DCD) + ret &= ~TIOCM_CD; + if (gplr & GPIO_H3600_COM_CTS) + ret &= ~TIOCM_CTS; + } + + return ret; +} + +static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + if (port->mapbase == _Ser2UTCR0) { /* TODO: REMOVE THIS */ + assign_h3600_egpio(IPAQ_EGPIO_IR_ON, !state); + } else if (port->mapbase == _Ser3UTCR0) { + assign_h3600_egpio(IPAQ_EGPIO_RS232_ON, !state); + } +} + +/* + * Enable/Disable wake up events for this serial port. + * Obviously, we only support this on the normal COM port. + */ +static int h3600_uart_set_wake(struct uart_port *port, u_int enable) +{ + int err = -EINVAL; + + if (port->mapbase == _Ser3UTCR0) { + if (enable) + PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */ + else + PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */ + err = 0; + } + return err; +} + +static struct sa1100_port_fns h3600_port_fns __initdata = { + .set_mctrl = h3600_uart_set_mctrl, + .get_mctrl = h3600_uart_get_mctrl, + .pm = h3600_uart_pm, + .set_wake = h3600_uart_set_wake, +}; + +/* + * helper for sa1100fb + */ +static void h3xxx_lcd_power(int enable) +{ + assign_h3600_egpio(IPAQ_EGPIO_LCD_POWER, enable); +} + +static struct map_desc h3600_io_desc[] __initdata = { + /* virtual physical length type */ + { H3600_BANK_2_VIRT, SA1100_CS2_PHYS, 0x02800000, MT_DEVICE }, /* static memory bank 2 CS#2 */ + { H3600_BANK_4_VIRT, SA1100_CS4_PHYS, 0x00800000, MT_DEVICE }, /* static memory bank 4 CS#4 */ + { H3600_EGPIO_VIRT, H3600_EGPIO_PHYS, 0x01000000, MT_DEVICE }, /* EGPIO 0 CS#5 */ +}; + +/* + * Common map_io initialization + */ + +static void __init h3xxx_map_io(void) +{ + sa1100_map_io(); + iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc)); + + sa1100_register_uart_fns(&h3600_port_fns); + sa1100_register_uart(0, 3); /* Common serial port */ +// sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */ + + /* Ensure those pins are outputs and driving low */ + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + + /* Configure suspend conditions */ + PGSR = 0; + PWER = PWER_GPIO0 | PWER_RTC; + PCFR = PCFR_OPDE; + PSDR = 0; + + sa1100fb_lcd_power = h3xxx_lcd_power; +} + +static __inline__ void do_blank(int setp) +{ + if (ipaq_model_ops.blank_callback) + ipaq_model_ops.blank_callback(1-setp); +} + +/************************* H3100 *************************/ + +#ifdef CONFIG_SA1100_H3100 + +#define H3100_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT) +static unsigned int h3100_egpio = 0; + +static void h3100_control_egpio(enum ipaq_egpio_type x, int setp) +{ + unsigned int egpio = 0; + long gpio = 0; + unsigned long flags; + + switch (x) { + case IPAQ_EGPIO_LCD_POWER: + egpio |= EGPIO_H3600_LCD_ON; + gpio |= GPIO_H3100_LCD_3V_ON; + do_blank(setp); + break; + case IPAQ_EGPIO_LCD_ENABLE: + break; + case IPAQ_EGPIO_CODEC_NRESET: + egpio |= EGPIO_H3600_CODEC_NRESET; + break; + case IPAQ_EGPIO_AUDIO_ON: + gpio |= GPIO_H3100_AUD_PWR_ON + | GPIO_H3100_AUD_ON; + break; + case IPAQ_EGPIO_QMUTE: + gpio |= GPIO_H3100_QMUTE; + break; + case IPAQ_EGPIO_OPT_NVRAM_ON: + egpio |= EGPIO_H3600_OPT_NVRAM_ON; + break; + case IPAQ_EGPIO_OPT_ON: + egpio |= EGPIO_H3600_OPT_ON; + break; + case IPAQ_EGPIO_CARD_RESET: + egpio |= EGPIO_H3600_CARD_RESET; + break; + case IPAQ_EGPIO_OPT_RESET: + egpio |= EGPIO_H3600_OPT_RESET; + break; + case IPAQ_EGPIO_IR_ON: + gpio |= GPIO_H3100_IR_ON; + break; + case IPAQ_EGPIO_IR_FSEL: + gpio |= GPIO_H3100_IR_FSEL; + break; + case IPAQ_EGPIO_RS232_ON: + egpio |= EGPIO_H3600_RS232_ON; + break; + case IPAQ_EGPIO_VPP_ON: + egpio |= EGPIO_H3600_VPP_ON; + break; + } + + if (egpio || gpio) { + local_irq_save(flags); + if (setp) { + h3100_egpio |= egpio; + GPSR = gpio; + } else { + h3100_egpio &= ~egpio; + GPCR = gpio; + } + H3100_EGPIO = h3100_egpio; + local_irq_restore(flags); + } +} + +static unsigned long h3100_read_egpio(void) +{ + return h3100_egpio; +} + +static int h3100_pm_callback(int req) +{ + if (ipaq_model_ops.pm_callback_aux) + return ipaq_model_ops.pm_callback_aux(req); + return 0; +} + +static struct ipaq_model_ops h3100_model_ops __initdata = { + .generic_name = "3100", + .control = h3100_control_egpio, + .read = h3100_read_egpio, + .pm_callback = h3100_pm_callback +}; + +#define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON \ + | GPIO_H3100_GPIO3 \ + | GPIO_H3100_QMUTE \ + | GPIO_H3100_LCD_3V_ON \ + | GPIO_H3100_AUD_ON \ + | GPIO_H3100_AUD_PWR_ON \ + | GPIO_H3100_IR_ON \ + | GPIO_H3100_IR_FSEL) + +static void __init h3100_map_io(void) +{ + h3xxx_map_io(); + + /* Initialize h3100-specific values here */ + GPCR = 0x0fffffff; /* All outputs are set low by default */ + GPDR = GPIO_H3600_COM_RTS | GPIO_H3600_L3_CLOCK | + GPIO_H3600_L3_MODE | GPIO_H3600_L3_DATA | + GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 | + H3100_DIRECT_EGPIO; + + /* Older bootldrs put GPIO2-9 in alternate mode on the + assumption that they are used for video */ + GAFR &= ~H3100_DIRECT_EGPIO; + + H3100_EGPIO = h3100_egpio; + ipaq_model_ops = h3100_model_ops; +} + +MACHINE_START(H3100, "Compaq iPAQ H3100") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(h3100_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, + .init_machine = h3xxx_mach_init, +MACHINE_END + +#endif /* CONFIG_SA1100_H3100 */ + +/************************* H3600 *************************/ + +#ifdef CONFIG_SA1100_H3600 + +#define H3600_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT) +static unsigned int h3600_egpio = EGPIO_H3600_RS232_ON; + +static void h3600_control_egpio(enum ipaq_egpio_type x, int setp) +{ + unsigned int egpio = 0; + unsigned long flags; + + switch (x) { + case IPAQ_EGPIO_LCD_POWER: + egpio |= EGPIO_H3600_LCD_ON | + EGPIO_H3600_LCD_PCI | + EGPIO_H3600_LCD_5V_ON | + EGPIO_H3600_LVDD_ON; + do_blank(setp); + break; + case IPAQ_EGPIO_LCD_ENABLE: + break; + case IPAQ_EGPIO_CODEC_NRESET: + egpio |= EGPIO_H3600_CODEC_NRESET; + break; + case IPAQ_EGPIO_AUDIO_ON: + egpio |= EGPIO_H3600_AUD_AMP_ON | + EGPIO_H3600_AUD_PWR_ON; + break; + case IPAQ_EGPIO_QMUTE: + egpio |= EGPIO_H3600_QMUTE; + break; + case IPAQ_EGPIO_OPT_NVRAM_ON: + egpio |= EGPIO_H3600_OPT_NVRAM_ON; + break; + case IPAQ_EGPIO_OPT_ON: + egpio |= EGPIO_H3600_OPT_ON; + break; + case IPAQ_EGPIO_CARD_RESET: + egpio |= EGPIO_H3600_CARD_RESET; + break; + case IPAQ_EGPIO_OPT_RESET: + egpio |= EGPIO_H3600_OPT_RESET; + break; + case IPAQ_EGPIO_IR_ON: + egpio |= EGPIO_H3600_IR_ON; + break; + case IPAQ_EGPIO_IR_FSEL: + egpio |= EGPIO_H3600_IR_FSEL; + break; + case IPAQ_EGPIO_RS232_ON: + egpio |= EGPIO_H3600_RS232_ON; + break; + case IPAQ_EGPIO_VPP_ON: + egpio |= EGPIO_H3600_VPP_ON; + break; + } + + if (egpio) { + local_irq_save(flags); + if (setp) + h3600_egpio |= egpio; + else + h3600_egpio &= ~egpio; + H3600_EGPIO = h3600_egpio; + local_irq_restore(flags); + } +} + +static unsigned long h3600_read_egpio(void) +{ + return h3600_egpio; +} + +static int h3600_pm_callback(int req) +{ + if (ipaq_model_ops.pm_callback_aux) + return ipaq_model_ops.pm_callback_aux(req); + return 0; +} + +static struct ipaq_model_ops h3600_model_ops __initdata = { + .generic_name = "3600", + .control = h3600_control_egpio, + .read = h3600_read_egpio, + .pm_callback = h3600_pm_callback +}; + +static void __init h3600_map_io(void) +{ + h3xxx_map_io(); + + /* Initialize h3600-specific values here */ + + GPCR = 0x0fffffff; /* All outputs are set low by default */ + GPDR = GPIO_H3600_COM_RTS | GPIO_H3600_L3_CLOCK | + GPIO_H3600_L3_MODE | GPIO_H3600_L3_DATA | + GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 | + GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | + GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8; + + H3600_EGPIO = h3600_egpio; /* Maintains across sleep? */ + ipaq_model_ops = h3600_model_ops; +} + +MACHINE_START(H3600, "Compaq iPAQ H3600") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(h3600_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, + .init_machine = h3xxx_mach_init, +MACHINE_END + +#endif /* CONFIG_SA1100_H3600 */ + +#ifdef CONFIG_SA1100_H3800 + +#define SET_ASIC1(x) \ + do {if (setp) { H3800_ASIC1_GPIO_OUT |= (x); } else { H3800_ASIC1_GPIO_OUT &= ~(x); }} while(0) + +#define SET_ASIC2(x) \ + do {if (setp) { H3800_ASIC2_GPIOPIOD |= (x); } else { H3800_ASIC2_GPIOPIOD &= ~(x); }} while(0) + +#define CLEAR_ASIC1(x) \ + do {if (setp) { H3800_ASIC1_GPIO_OUT &= ~(x); } else { H3800_ASIC1_GPIO_OUT |= (x); }} while(0) + +#define CLEAR_ASIC2(x) \ + do {if (setp) { H3800_ASIC2_GPIOPIOD &= ~(x); } else { H3800_ASIC2_GPIOPIOD |= (x); }} while(0) + + +/* + On screen enable, we get + + h3800_video_power_on(1) + LCD controller starts + h3800_video_lcd_enable(1) + + On screen disable, we get + + h3800_video_lcd_enable(0) + LCD controller stops + h3800_video_power_on(0) +*/ + + +static void h3800_video_power_on(int setp) +{ + if (setp) { + H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_ON; + msleep(30); + H3800_ASIC1_GPIO_OUT |= GPIO1_VGL_ON; + msleep(5); + H3800_ASIC1_GPIO_OUT |= GPIO1_VGH_ON; + msleep(50); + H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_5V_ON; + msleep(5); + } else { + msleep(5); + H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_5V_ON; + msleep(50); + H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGL_ON; + msleep(5); + H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGH_ON; + msleep(100); + H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_ON; + } +} + +static void h3800_video_lcd_enable(int setp) +{ + if (setp) { + msleep(17); // Wait one from before turning on + H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_PCI; + } else { + H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_PCI; + msleep(30); // Wait before turning off + } +} + + +static void h3800_control_egpio(enum ipaq_egpio_type x, int setp) +{ + switch (x) { + case IPAQ_EGPIO_LCD_POWER: + h3800_video_power_on(setp); + break; + case IPAQ_EGPIO_LCD_ENABLE: + h3800_video_lcd_enable(setp); + break; + case IPAQ_EGPIO_CODEC_NRESET: + case IPAQ_EGPIO_AUDIO_ON: + case IPAQ_EGPIO_QMUTE: + printk("%s: error - should not be called\n", __FUNCTION__); + break; + case IPAQ_EGPIO_OPT_NVRAM_ON: + SET_ASIC2(GPIO2_OPT_ON_NVRAM); + break; + case IPAQ_EGPIO_OPT_ON: + SET_ASIC2(GPIO2_OPT_ON); + break; + case IPAQ_EGPIO_CARD_RESET: + SET_ASIC2(GPIO2_OPT_PCM_RESET); + break; + case IPAQ_EGPIO_OPT_RESET: + SET_ASIC2(GPIO2_OPT_RESET); + break; + case IPAQ_EGPIO_IR_ON: + CLEAR_ASIC1(GPIO1_IR_ON_N); + break; + case IPAQ_EGPIO_IR_FSEL: + break; + case IPAQ_EGPIO_RS232_ON: + SET_ASIC1(GPIO1_RS232_ON); + break; + case IPAQ_EGPIO_VPP_ON: + H3800_ASIC2_FlashWP_VPP_ON = setp; + break; + } +} + +static unsigned long h3800_read_egpio(void) +{ + return H3800_ASIC1_GPIO_OUT | (H3800_ASIC2_GPIOPIOD << 16); +} + +/* We need to fix ASIC2 GPIO over suspend/resume. At the moment, + it doesn't appear that ASIC1 GPIO has the same problem */ + +static int h3800_pm_callback(int req) +{ + static u16 asic1_data; + static u16 asic2_data; + int result = 0; + + printk("%s %d\n", __FUNCTION__, req); + + switch (req) { + case PM_RESUME: + MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000; /* Set MSC2 correctly */ + + H3800_ASIC2_GPIOPIOD = asic2_data; + H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ + | GPIO2_SD_DETECT + | GPIO2_EAR_IN_N + | GPIO2_USB_DETECT_N + | GPIO2_SD_CON_SLT; + + H3800_ASIC1_GPIO_OUT = asic1_data; + + if (ipaq_model_ops.pm_callback_aux) + result = ipaq_model_ops.pm_callback_aux(req); + break; + + case PM_SUSPEND: + if (ipaq_model_ops.pm_callback_aux && + ((result = ipaq_model_ops.pm_callback_aux(req)) != 0)) + return result; + + asic1_data = H3800_ASIC1_GPIO_OUT; + asic2_data = H3800_ASIC2_GPIOPIOD; + break; + default: + printk("%s: unrecognized PM callback\n", __FUNCTION__); + break; + } + return result; +} + +static struct ipaq_model_ops h3800_model_ops __initdata = { + .generic_name = "3800", + .control = h3800_control_egpio, + .read = h3800_read_egpio, + .pm_callback = h3800_pm_callback +}; + +#define MAX_ASIC_ISR_LOOPS 20 + +/* The order of these is important - see #include <asm/arch/irqs.h> */ +static u32 kpio_irq_mask[] = { + KPIO_KEY_ALL, + KPIO_SPI_INT, + KPIO_OWM_INT, + KPIO_ADC_INT, + KPIO_UART_0_INT, + KPIO_UART_1_INT, + KPIO_TIMER_0_INT, + KPIO_TIMER_1_INT, + KPIO_TIMER_2_INT +}; + +static u32 gpio_irq_mask[] = { + GPIO2_PEN_IRQ, + GPIO2_SD_DETECT, + GPIO2_EAR_IN_N, + GPIO2_USB_DETECT_N, + GPIO2_SD_CON_SLT, +}; + +static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + int i; + + if (0) printk("%s: interrupt received\n", __FUNCTION__); + + desc->chip->ack(irq); + + for (i = 0; i < MAX_ASIC_ISR_LOOPS && (GPLR & GPIO_H3800_ASIC); i++) { + u32 irq; + int j; + + /* KPIO */ + irq = H3800_ASIC2_KPIINTFLAG; + if (0) printk("%s KPIO 0x%08X\n", __FUNCTION__, irq); + for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++) + if (irq & kpio_irq_mask[j]) + do_edge_IRQ(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j, regs); + + /* GPIO2 */ + irq = H3800_ASIC2_GPIINTFLAG; + if (0) printk("%s GPIO 0x%08X\n", __FUNCTION__, irq); + for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++) + if (irq & gpio_irq_mask[j]) + do_edge_IRQ(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j , regs); + } + + if (i >= MAX_ASIC_ISR_LOOPS) + printk("%s: interrupt processing overrun\n", __FUNCTION__); + + /* For level-based interrupts */ + desc->chip->unmask(irq); + +} + +static struct irqaction h3800_irq = { + .name = "h3800_asic", + .handler = h3800_IRQ_demux, + .flags = SA_INTERRUPT, +}; + +u32 kpio_int_shadow = 0; + + +/* mask_ack <- IRQ is first serviced. + mask <- IRQ is disabled. + unmask <- IRQ is enabled + + The INTCLR registers are poorly documented. I believe that writing + a "1" to the register clears the specific interrupt, but the documentation + indicates writing a "0" clears the interrupt. In any case, they shouldn't + be read (that's the INTFLAG register) + */ + +static void h3800_mask_ack_kpio_irq(unsigned int irq) +{ + u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START]; + kpio_int_shadow &= ~mask; + H3800_ASIC2_KPIINTSTAT = kpio_int_shadow; + H3800_ASIC2_KPIINTCLR = mask; +} + +static void h3800_mask_kpio_irq(unsigned int irq) +{ + u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START]; + kpio_int_shadow &= ~mask; + H3800_ASIC2_KPIINTSTAT = kpio_int_shadow; +} + +static void h3800_unmask_kpio_irq(unsigned int irq) +{ + u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START]; + kpio_int_shadow |= mask; + H3800_ASIC2_KPIINTSTAT = kpio_int_shadow; +} + +static void h3800_mask_ack_gpio_irq(unsigned int irq) +{ + u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START]; + H3800_ASIC2_GPIINTSTAT &= ~mask; + H3800_ASIC2_GPIINTCLR = mask; +} + +static void h3800_mask_gpio_irq(unsigned int irq) +{ + u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START]; + H3800_ASIC2_GPIINTSTAT &= ~mask; + } + +static void h3800_unmask_gpio_irq(unsigned int irq) +{ + u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START]; + H3800_ASIC2_GPIINTSTAT |= mask; +} + +static void __init h3800_init_irq(void) +{ + int i; + + /* Initialize standard IRQs */ + sa1100_init_irq(); + + /* Disable all IRQs and set up clock */ + H3800_ASIC2_KPIINTSTAT = 0; /* Disable all interrupts */ + H3800_ASIC2_GPIINTSTAT = 0; + + H3800_ASIC2_KPIINTCLR = 0; /* Clear all KPIO interrupts */ + H3800_ASIC2_GPIINTCLR = 0; /* Clear all GPIO interrupts */ + +// H3800_ASIC2_KPIINTCLR = 0xffff; /* Clear all KPIO interrupts */ +// H3800_ASIC2_GPIINTCLR = 0xffff; /* Clear all GPIO interrupts */ + + H3800_ASIC2_CLOCK_Enable |= ASIC2_CLOCK_EX0; /* 32 kHZ crystal on */ + H3800_ASIC2_INTR_ClockPrescale |= ASIC2_INTCPS_SET; + H3800_ASIC2_INTR_ClockPrescale = ASIC2_INTCPS_CPS(0x0e) | ASIC2_INTCPS_SET; + H3800_ASIC2_INTR_TimerSet = 1; + +#if 0 + for (i = 0; i < H3800_KPIO_IRQ_COUNT; i++) { + int irq = i + H3800_KPIO_IRQ_START; + irq_desc[irq].valid = 1; + irq_desc[irq].probe_ok = 1; + set_irq_chip(irq, &h3800_kpio_irqchip); + } + + for (i = 0; i < H3800_GPIO_IRQ_COUNT; i++) { + int irq = i + H3800_GPIO_IRQ_START; + irq_desc[irq].valid = 1; + irq_desc[irq].probe_ok = 1; + set_irq_chip(irq, &h3800_gpio_irqchip); + } +#endif + set_irq_type(IRQ_GPIO_H3800_ASIC, IRQT_RISING); + set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, &h3800_IRQ_demux); +} + + +#define ASIC1_OUTPUTS 0x7fff /* First 15 bits are used */ + +static void __init h3800_map_io(void) +{ + h3xxx_map_io(); + + /* Add wakeup on AC plug/unplug */ + PWER |= PWER_GPIO12; + + /* Initialize h3800-specific values here */ + GPCR = 0x0fffffff; /* All outputs are set low by default */ + GAFR = GPIO_H3800_CLK_OUT | + GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | + GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8; + GPDR = GPIO_H3800_CLK_OUT | + GPIO_H3600_COM_RTS | GPIO_H3600_L3_CLOCK | + GPIO_H3600_L3_MODE | GPIO_H3600_L3_DATA | + GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | + GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8; + TUCR = TUCR_3_6864MHz; /* Seems to be used only for the Bluetooth UART */ + + /* Fix the memory bus */ + MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000; + + /* Set up ASIC #1 */ + H3800_ASIC1_GPIO_DIR = ASIC1_OUTPUTS; /* All outputs */ + H3800_ASIC1_GPIO_MASK = ASIC1_OUTPUTS; /* No interrupts */ + H3800_ASIC1_GPIO_SLEEP_MASK = ASIC1_OUTPUTS; + H3800_ASIC1_GPIO_SLEEP_DIR = ASIC1_OUTPUTS; + H3800_ASIC1_GPIO_SLEEP_OUT = GPIO1_EAR_ON_N; + H3800_ASIC1_GPIO_BATT_FAULT_DIR = ASIC1_OUTPUTS; + H3800_ASIC1_GPIO_BATT_FAULT_OUT = GPIO1_EAR_ON_N; + + H3800_ASIC1_GPIO_OUT = GPIO1_IR_ON_N + | GPIO1_RS232_ON + | GPIO1_EAR_ON_N; + + /* Set up ASIC #2 */ + H3800_ASIC2_GPIOPIOD = GPIO2_IN_Y1_N | GPIO2_IN_X1_N; + H3800_ASIC2_GPOBFSTAT = GPIO2_IN_Y1_N | GPIO2_IN_X1_N; + + H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ + | GPIO2_SD_DETECT + | GPIO2_EAR_IN_N + | GPIO2_USB_DETECT_N + | GPIO2_SD_CON_SLT; + + /* TODO : Set sleep states & battery fault states */ + + /* Clear VPP Enable */ + H3800_ASIC2_FlashWP_VPP_ON = 0; + ipaq_model_ops = h3800_model_ops; +} + +MACHINE_START(H3800, "Compaq iPAQ H3800") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(h3800_map_io) + INITIRQ(h3800_init_irq) + .timer = &sa1100_timer, + .init_machine = h3xxx_mach_init, +MACHINE_END + +#endif /* CONFIG_SA1100_H3800 */ diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c new file mode 100644 index 0000000..5708417 --- /dev/null +++ b/arch/arm/mach-sa1100/hackkit.c @@ -0,0 +1,200 @@ +/* + * linux/arch/arm/mach-sa1100/hackkit.c + * + * Copyright (C) 2002 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de> + * + * This file contains all HackKit tweaks. Based on original work from + * Nicolas Pitre's assabet fixes + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/tty.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/cpufreq.h> +#include <linux/serial_core.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/setup.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/irq.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/serial_sa1100.h> + +#include "generic.h" + +/********************************************************************** + * prototypes + */ + +/* init funcs */ +static void __init hackkit_map_io(void); + +static u_int hackkit_get_mctrl(struct uart_port *port); +static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl); +static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate); + +/********************************************************************** + * global data + */ + +/********************************************************************** + * static data + */ + +static struct map_desc hackkit_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xe8000000, 0x00000000, 0x01000000, MT_DEVICE } /* Flash bank 0 */ +}; + +static struct sa1100_port_fns hackkit_port_fns __initdata = { + .set_mctrl = hackkit_set_mctrl, + .get_mctrl = hackkit_get_mctrl, + .pm = hackkit_uart_pm, +}; + +/********************************************************************** + * Static functions + */ + +static void __init hackkit_map_io(void) +{ + sa1100_map_io(); + iotable_init(hackkit_io_desc, ARRAY_SIZE(hackkit_io_desc)); + + sa1100_register_uart_fns(&hackkit_port_fns); + sa1100_register_uart(0, 1); /* com port */ + sa1100_register_uart(1, 2); + sa1100_register_uart(2, 3); /* radio module */ + + Ser1SDCR0 |= SDCR0_SUS; +} + +/** + * hackkit_uart_pm - powermgmt callback function for system 3 UART + * @port: uart port structure + * @state: pm state + * @oldstate: old pm state + * + */ +static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + /* TODO: switch on/off uart in powersave mode */ +} + +/* + * Note! this can be called from IRQ context. + * FIXME: No modem ctrl lines yet. + */ +static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl) +{ +#if 0 + if (port->mapbase == _Ser1UTCR0) { + u_int set = 0, clear = 0; + + if (mctrl & TIOCM_RTS) + set |= PT_CTRL2_RS1_RTS; + else + clear |= PT_CTRL2_RS1_RTS; + + if (mctrl & TIOCM_DTR) + set |= PT_CTRL2_RS1_DTR; + else + clear |= PT_CTRL2_RS1_DTR; + + PTCTRL2_clear(clear); + PTCTRL2_set(set); + } +#endif +} + +static u_int hackkit_get_mctrl(struct uart_port *port) +{ + u_int ret = 0; +#if 0 + u_int irqsr = PT_IRQSR; + + /* need 2 reads to read current value */ + irqsr = PT_IRQSR; + + /* TODO: check IRQ source register for modem/com + status lines and set them correctly. */ +#endif + + ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; + + return ret; +} + +static struct mtd_partition hackkit_partitions[] = { + { + .name = "BLOB", + .size = 0x00040000, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "config", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "kernel", + .size = 0x00100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "initrd", + .size = 0x00180000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "rootfs", + .size = 0x700000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "data", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct flash_platform_data hackkit_flash_data = { + .map_name = "cfi_probe", + .parts = hackkit_partitions, + .nr_parts = ARRAY_SIZE(hackkit_partitions), +}; + +static struct resource hackkit_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M, + .flags = IORESOURCE_MEM, +}; + +static void __init hackkit_init(void) +{ + sa11x0_set_flash_data(&hackkit_flash_data, &hackkit_flash_resource, 1); +} + +/********************************************************************** + * Exported Functions + */ + +MACHINE_START(HACKKIT, "HackKit Cpu Board") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(hackkit_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, + .init_machine = hackkit_init, +MACHINE_END diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c new file mode 100644 index 0000000..66a929c --- /dev/null +++ b/arch/arm/mach-sa1100/irq.c @@ -0,0 +1,332 @@ +/* + * linux/arch/arm/mach-sa1100/irq.c + * + * Copyright (C) 1999-2001 Nicolas Pitre + * + * Generic IRQ handling for the SA11x0, GPIO 11-27 IRQ demultiplexing. + * + * 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/init.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/ptrace.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/mach/irq.h> + +#include "generic.h" + + +/* + * SA1100 GPIO edge detection for IRQs: + * IRQs are generated on Falling-Edge, Rising-Edge, or both. + * Use this instead of directly setting GRER/GFER. + */ +static int GPIO_IRQ_rising_edge; +static int GPIO_IRQ_falling_edge; +static int GPIO_IRQ_mask = (1 << 11) - 1; + +/* + * To get the GPIO number from an IRQ number + */ +#define GPIO_11_27_IRQ(i) ((i) - 21) +#define GPIO11_27_MASK(irq) (1 << GPIO_11_27_IRQ(irq)) + +static int sa1100_gpio_type(unsigned int irq, unsigned int type) +{ + unsigned int mask; + + if (irq <= 10) + mask = 1 << irq; + else + mask = GPIO11_27_MASK(irq); + + if (type == IRQT_PROBE) { + if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) + return 0; + type = __IRQT_RISEDGE | __IRQT_FALEDGE; + } + + if (type & __IRQT_RISEDGE) { + GPIO_IRQ_rising_edge |= mask; + } else + GPIO_IRQ_rising_edge &= ~mask; + if (type & __IRQT_FALEDGE) { + GPIO_IRQ_falling_edge |= mask; + } else + GPIO_IRQ_falling_edge &= ~mask; + + GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask; + GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; + + return 0; +} + +/* + * GPIO IRQs must be acknowledged. This is for IRQs from 0 to 10. + */ +static void sa1100_low_gpio_ack(unsigned int irq) +{ + GEDR = (1 << irq); +} + +static void sa1100_low_gpio_mask(unsigned int irq) +{ + ICMR &= ~(1 << irq); +} + +static void sa1100_low_gpio_unmask(unsigned int irq) +{ + ICMR |= 1 << irq; +} + +static int sa1100_low_gpio_wake(unsigned int irq, unsigned int on) +{ + if (on) + PWER |= 1 << irq; + else + PWER &= ~(1 << irq); + return 0; +} + +static struct irqchip sa1100_low_gpio_chip = { + .ack = sa1100_low_gpio_ack, + .mask = sa1100_low_gpio_mask, + .unmask = sa1100_low_gpio_unmask, + .type = sa1100_gpio_type, + .wake = sa1100_low_gpio_wake, +}; + +/* + * IRQ11 (GPIO11 through 27) handler. We enter here with the + * irq_controller_lock held, and IRQs disabled. Decode the IRQ + * and call the handler. + */ +static void +sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int mask; + + mask = GEDR & 0xfffff800; + do { + /* + * clear down all currently active IRQ sources. + * We will be processing them all. + */ + GEDR = mask; + + irq = IRQ_GPIO11; + desc = irq_desc + irq; + mask >>= 11; + do { + if (mask & 1) + desc->handle(irq, desc, regs); + mask >>= 1; + irq++; + desc++; + } while (mask); + + mask = GEDR & 0xfffff800; + } while (mask); +} + +/* + * Like GPIO0 to 10, GPIO11-27 IRQs need to be handled specially. + * In addition, the IRQs are all collected up into one bit in the + * interrupt controller registers. + */ +static void sa1100_high_gpio_ack(unsigned int irq) +{ + unsigned int mask = GPIO11_27_MASK(irq); + + GEDR = mask; +} + +static void sa1100_high_gpio_mask(unsigned int irq) +{ + unsigned int mask = GPIO11_27_MASK(irq); + + GPIO_IRQ_mask &= ~mask; + + GRER &= ~mask; + GFER &= ~mask; +} + +static void sa1100_high_gpio_unmask(unsigned int irq) +{ + unsigned int mask = GPIO11_27_MASK(irq); + + GPIO_IRQ_mask |= mask; + + GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask; + GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; +} + +static int sa1100_high_gpio_wake(unsigned int irq, unsigned int on) +{ + if (on) + PWER |= GPIO11_27_MASK(irq); + else + PWER &= ~GPIO11_27_MASK(irq); + return 0; +} + +static struct irqchip sa1100_high_gpio_chip = { + .ack = sa1100_high_gpio_ack, + .mask = sa1100_high_gpio_mask, + .unmask = sa1100_high_gpio_unmask, + .type = sa1100_gpio_type, + .wake = sa1100_high_gpio_wake, +}; + +/* + * We don't need to ACK IRQs on the SA1100 unless they're GPIOs + * this is for internal IRQs i.e. from 11 to 31. + */ +static void sa1100_mask_irq(unsigned int irq) +{ + ICMR &= ~(1 << irq); +} + +static void sa1100_unmask_irq(unsigned int irq) +{ + ICMR |= (1 << irq); +} + +static struct irqchip sa1100_normal_chip = { + .ack = sa1100_mask_irq, + .mask = sa1100_mask_irq, + .unmask = sa1100_unmask_irq, +}; + +static struct resource irq_resource = { + .name = "irqs", + .start = 0x90050000, + .end = 0x9005ffff, +}; + +static struct sa1100irq_state { + unsigned int saved; + unsigned int icmr; + unsigned int iclr; + unsigned int iccr; +} sa1100irq_state; + +static int sa1100irq_suspend(struct sys_device *dev, pm_message_t state) +{ + struct sa1100irq_state *st = &sa1100irq_state; + + st->saved = 1; + st->icmr = ICMR; + st->iclr = ICLR; + st->iccr = ICCR; + + /* + * Disable all GPIO-based interrupts. + */ + ICMR &= ~(IC_GPIO11_27|IC_GPIO10|IC_GPIO9|IC_GPIO8|IC_GPIO7| + IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2| + IC_GPIO1|IC_GPIO0); + + /* + * Set the appropriate edges for wakeup. + */ + GRER = PWER & GPIO_IRQ_rising_edge; + GFER = PWER & GPIO_IRQ_falling_edge; + + /* + * Clear any pending GPIO interrupts. + */ + GEDR = GEDR; + + return 0; +} + +static int sa1100irq_resume(struct sys_device *dev) +{ + struct sa1100irq_state *st = &sa1100irq_state; + + if (st->saved) { + ICCR = st->iccr; + ICLR = st->iclr; + + GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask; + GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; + + ICMR = st->icmr; + } + return 0; +} + +static struct sysdev_class sa1100irq_sysclass = { + set_kset_name("sa11x0-irq"), + .suspend = sa1100irq_suspend, + .resume = sa1100irq_resume, +}; + +static struct sys_device sa1100irq_device = { + .id = 0, + .cls = &sa1100irq_sysclass, +}; + +static int __init sa1100irq_init_devicefs(void) +{ + sysdev_class_register(&sa1100irq_sysclass); + return sysdev_register(&sa1100irq_device); +} + +device_initcall(sa1100irq_init_devicefs); + +void __init sa1100_init_irq(void) +{ + unsigned int irq; + + request_resource(&iomem_resource, &irq_resource); + + /* disable all IRQs */ + ICMR = 0; + + /* all IRQs are IRQ, not FIQ */ + ICLR = 0; + + /* clear all GPIO edge detects */ + GFER = 0; + GRER = 0; + GEDR = -1; + + /* + * Whatever the doc says, this has to be set for the wait-on-irq + * instruction to work... on a SA1100 rev 9 at least. + */ + ICCR = 1; + + for (irq = 0; irq <= 10; irq++) { + set_irq_chip(irq, &sa1100_low_gpio_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + for (irq = 12; irq <= 31; irq++) { + set_irq_chip(irq, &sa1100_normal_chip); + set_irq_handler(irq, do_level_IRQ); + set_irq_flags(irq, IRQF_VALID); + } + + for (irq = 32; irq <= 48; irq++) { + set_irq_chip(irq, &sa1100_high_gpio_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + /* + * Install handler for GPIO 11-27 edge detect interrupts + */ + set_irq_chip(IRQ_GPIO11_27, &sa1100_normal_chip); + set_irq_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler); +} diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c new file mode 100644 index 0000000..6be7829 --- /dev/null +++ b/arch/arm/mach-sa1100/jornada720.c @@ -0,0 +1,105 @@ +/* + * linux/arch/arm/mach-sa1100/jornada720.c + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/tty.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/ioport.h> + +#include <asm/hardware.h> +#include <asm/hardware/sa1111.h> +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/setup.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/serial_sa1100.h> + +#include "generic.h" + + +#define JORTUCR_VAL 0x20000400 + +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO1, + .end = IRQ_GPIO1, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .dma_mask = &sa1111_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + +static int __init jornada720_init(void) +{ + int ret = -ENODEV; + + if (machine_is_jornada720()) { + GPDR |= GPIO_GPIO20; + TUCR = JORTUCR_VAL; /* set the oscillator out to the SA-1101 */ + + GPSR = GPIO_GPIO20; + udelay(1); + GPCR = GPIO_GPIO20; + udelay(1); + GPSR = GPIO_GPIO20; + udelay(20); + + /* LDD4 is speaker, LDD3 is microphone */ + PPSR &= ~(PPC_LDD3 | PPC_LDD4); + PPDR |= PPC_LDD3 | PPC_LDD4; + + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + } + return ret; +} + +arch_initcall(jornada720_init); + +static struct map_desc jornada720_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xf0000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Epson registers */ + { 0xf1000000, 0x48200000, 0x00100000, MT_DEVICE }, /* Epson frame buffer */ + { 0xf4000000, 0x40000000, 0x00100000, MT_DEVICE } /* SA-1111 */ +}; + +static void __init jornada720_map_io(void) +{ + sa1100_map_io(); + iotable_init(jornada720_io_desc, ARRAY_SIZE(jornada720_io_desc)); + + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); +} + +MACHINE_START(JORNADA720, "HP Jornada 720") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(jornada720_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, +MACHINE_END diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c new file mode 100644 index 0000000..51c08cc --- /dev/null +++ b/arch/arm/mach-sa1100/lart.c @@ -0,0 +1,49 @@ +/* + * linux/arch/arm/mach-sa1100/lart.c + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/tty.h> + +#include <asm/hardware.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/serial_sa1100.h> + +#include "generic.h" + + +#warning "include/asm/arch-sa1100/ide.h needs fixing for lart" + +static struct map_desc lart_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xe8000000, 0x00000000, 0x00400000, MT_DEVICE }, /* main flash memory */ + { 0xec000000, 0x08000000, 0x00400000, MT_DEVICE } /* main flash, alternative location */ +}; + +static void __init lart_map_io(void) +{ + sa1100_map_io(); + iotable_init(lart_io_desc, ARRAY_SIZE(lart_io_desc)); + + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); + sa1100_register_uart(2, 2); + + GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD); + GPDR |= GPIO_UART_TXD; + GPDR &= ~GPIO_UART_RXD; + PPAR |= PPAR_UPR; +} + +MACHINE_START(LART, "LART") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(lart_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, +MACHINE_END diff --git a/arch/arm/mach-sa1100/leds-assabet.c b/arch/arm/mach-sa1100/leds-assabet.c new file mode 100644 index 0000000..e9aa9df --- /dev/null +++ b/arch/arm/mach-sa1100/leds-assabet.c @@ -0,0 +1,115 @@ +/* + * linux/arch/arm/mach-sa1100/leds-assabet.c + * + * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu> + * + * Original (leds-footbridge.c) by Russell King + * + * Assabet uses the LEDs as follows: + * - Green - toggles state every 50 timer interrupts + * - Red - on if system is not idle + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> +#include <asm/arch/assabet.h> + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define ASSABET_BCR_LED_MASK (ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED) + +void assabet_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN; + ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state); + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= ASSABET_BCR_LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= ASSABET_BCR_LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~ASSABET_BCR_LED_RED; + break; +#endif + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~ASSABET_BCR_LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= ASSABET_BCR_LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~ASSABET_BCR_LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= ASSABET_BCR_LED_RED; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state); + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-sa1100/leds-badge4.c b/arch/arm/mach-sa1100/leds-badge4.c new file mode 100644 index 0000000..0a8f87b --- /dev/null +++ b/arch/arm/mach-sa1100/leds-badge4.c @@ -0,0 +1,112 @@ +/* + * linux/arch/arm/mach-sa1100/leds-badge4.c + * + * Author: Christopher Hoover <ch@hpl.hp.com> + * Copyright (C) 2002 Hewlett-Packard Company + * + * 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/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include "leds.h" + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_RED GPIO_GPIO(7) +#define LED_GREEN GPIO_GPIO(9) +#define LED_MASK (LED_RED|LED_GREEN) + +#define LED_IDLE LED_GREEN +#define LED_TIMER LED_RED + +void badge4_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + GPDR |= LED_MASK; + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_TIMER; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + /* LED off when system is idle */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_IDLE; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_IDLE; + break; +#endif + + case led_red_on: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_red_off: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; + + case led_green_on: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_GREEN; + break; + + case led_green_off: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_GREEN; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-sa1100/leds-cerf.c b/arch/arm/mach-sa1100/leds-cerf.c new file mode 100644 index 0000000..f6635a2 --- /dev/null +++ b/arch/arm/mach-sa1100/leds-cerf.c @@ -0,0 +1,111 @@ +/* + * linux/arch/arm/mach-sa1100/leds-cerf.c + * + * Author: ??? + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_D0 GPIO_GPIO(0) +#define LED_D1 GPIO_GPIO(1) +#define LED_D2 GPIO_GPIO(2) +#define LED_D3 GPIO_GPIO(3) +#define LED_MASK (LED_D0|LED_D1|LED_D2|LED_D3) + +void cerf_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_D0; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D1; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D1; + break; +#endif + case led_green_on: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D2; + break; + + case led_green_off: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D2; + break; + + case led_amber_on: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D3; + break; + + case led_amber_off: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D3; + break; + + case led_red_on: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D1; + break; + + case led_red_off: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D1; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-sa1100/leds-hackkit.c b/arch/arm/mach-sa1100/leds-hackkit.c new file mode 100644 index 0000000..2e5fa14 --- /dev/null +++ b/arch/arm/mach-sa1100/leds-hackkit.c @@ -0,0 +1,113 @@ +/* + * linux/arch/arm/mach-sa1100/leds-hackkit.c + * + * based on leds-lart.c + * + * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000 + * (C) Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>, 2002 + * + * The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used + * as cpu led, the green one is used as timer led. + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_GREEN GPIO_GPIO23 +#define LED_RED GPIO_GPIO22 +#define LED_MASK (LED_RED | LED_GREEN) + +void hackkit_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch(evt) { + case led_start: + /* pin 22/23 are outputs */ + GPDR |= LED_MASK; + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + /* The LART people like the LED to be off when the + system is idle... */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + /* ... and on if the system is not idle */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; +#endif + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + default: + break; + } + + /* Now set the GPIO state, or nothing will happen at all */ + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-sa1100/leds-lart.c b/arch/arm/mach-sa1100/leds-lart.c new file mode 100644 index 0000000..1875014 --- /dev/null +++ b/arch/arm/mach-sa1100/leds-lart.c @@ -0,0 +1,102 @@ +/* + * linux/arch/arm/mach-sa1100/leds-lart.c + * + * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000 + * + * LART uses the LED as follows: + * - GPIO23 is the LED, on if system is not idle + * You can use both CONFIG_LEDS_CPU and CONFIG_LEDS_TIMER at the same + * time, but in that case the timer events will still dictate the + * pace of the LED. + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_23 GPIO_GPIO23 +#define LED_MASK (LED_23) + +void lart_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch(evt) { + case led_start: + /* pin 23 is output pin */ + GPDR |= LED_23; + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_23; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + /* The LART people like the LED to be off when the + system is idle... */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_23; + break; + + case led_idle_end: + /* ... and on if the system is not idle */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_23; + break; +#endif + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_23; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_23; + break; + + default: + break; + } + + /* Now set the GPIO state, or nothing will happen at all */ + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-sa1100/leds-simpad.c b/arch/arm/mach-sa1100/leds-simpad.c new file mode 100644 index 0000000..6a27a2d --- /dev/null +++ b/arch/arm/mach-sa1100/leds-simpad.c @@ -0,0 +1,101 @@ +/* + * linux/arch/arm/mach-sa1100/leds-simpad.c + * + * Author: Juergen Messerer <juergen.messerer@siemens.ch> + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/system.h> +#include <asm/arch/simpad.h> + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_GREEN (1) +#define LED_MASK (1) + +extern void set_cs3_bit(int value); +extern void clear_cs3_bit(int value); + +void simpad_leds_event(led_event_t evt) +{ + switch (evt) + { + case led_start: + hw_led_state = LED_GREEN; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_GREEN; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + break; + + case led_idle_end: + break; +#endif + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + break; + + case led_red_off: + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + set_cs3_bit(LED2_ON); + else + clear_cs3_bit(LED2_ON); +} + diff --git a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c new file mode 100644 index 0000000..4cf7c56 --- /dev/null +++ b/arch/arm/mach-sa1100/leds.c @@ -0,0 +1,52 @@ +/* + * linux/arch/arm/mach-sa1100/leds.c + * + * SA1100 LEDs dispatcher + * + * Copyright (C) 2001 Nicolas Pitre + */ +#include <linux/compiler.h> +#include <linux/init.h> + +#include <asm/leds.h> +#include <asm/mach-types.h> + +#include "leds.h" + +static int __init +sa1100_leds_init(void) +{ + if (machine_is_assabet()) + leds_event = assabet_leds_event; + if (machine_is_consus()) + leds_event = consus_leds_event; + if (machine_is_badge4()) + leds_event = badge4_leds_event; + if (machine_is_brutus()) + leds_event = brutus_leds_event; + if (machine_is_cerf()) + leds_event = cerf_leds_event; + if (machine_is_flexanet()) + leds_event = flexanet_leds_event; + if (machine_is_graphicsclient()) + leds_event = graphicsclient_leds_event; + if (machine_is_hackkit()) + leds_event = hackkit_leds_event; + if (machine_is_lart()) + leds_event = lart_leds_event; + if (machine_is_pfs168()) + leds_event = pfs168_leds_event; + if (machine_is_graphicsmaster()) + leds_event = graphicsmaster_leds_event; + if (machine_is_adsbitsy()) + leds_event = adsbitsy_leds_event; + if (machine_is_pt_system3()) + leds_event = system3_leds_event; + if (machine_is_simpad()) + leds_event = simpad_leds_event; /* what about machine registry? including led, apm... -zecke */ + + leds_event(led_start); + return 0; +} + +core_initcall(sa1100_leds_init); diff --git a/arch/arm/mach-sa1100/leds.h b/arch/arm/mach-sa1100/leds.h new file mode 100644 index 0000000..68cc9f7 --- /dev/null +++ b/arch/arm/mach-sa1100/leds.h @@ -0,0 +1,14 @@ +extern void assabet_leds_event(led_event_t evt); +extern void badge4_leds_event(led_event_t evt); +extern void consus_leds_event(led_event_t evt); +extern void brutus_leds_event(led_event_t evt); +extern void cerf_leds_event(led_event_t evt); +extern void flexanet_leds_event(led_event_t evt); +extern void graphicsclient_leds_event(led_event_t evt); +extern void hackkit_leds_event(led_event_t evt); +extern void lart_leds_event(led_event_t evt); +extern void pfs168_leds_event(led_event_t evt); +extern void graphicsmaster_leds_event(led_event_t evt); +extern void adsbitsy_leds_event(led_event_t evt); +extern void system3_leds_event(led_event_t evt); +extern void simpad_leds_event(led_event_t evt); diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c new file mode 100644 index 0000000..1405383 --- /dev/null +++ b/arch/arm/mach-sa1100/neponset.c @@ -0,0 +1,342 @@ +/* + * linux/arch/arm/mach-sa1100/neponset.c + * + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/ptrace.h> +#include <linux/tty.h> +#include <linux/ioport.h> +#include <linux/serial_core.h> +#include <linux/device.h> +#include <linux/slab.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/serial_sa1100.h> +#include <asm/arch/assabet.h> +#include <asm/arch/neponset.h> +#include <asm/hardware/sa1111.h> +#include <asm/sizes.h> + +/* + * Install handler for Neponset IRQ. Note that we have to loop here + * since the ETHERNET and USAR IRQs are level based, and we need to + * ensure that the IRQ signal is deasserted before returning. This + * is rather unfortunate. + */ +static void +neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + unsigned int irr; + + while (1) { + struct irqdesc *d; + + /* + * Acknowledge the parent IRQ. + */ + desc->chip->ack(irq); + + /* + * Read the interrupt reason register. Let's have all + * active IRQ bits high. Note: there is a typo in the + * Neponset user's guide for the SA1111 IRR level. + */ + irr = IRR ^ (IRR_ETHERNET | IRR_USAR); + + if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) + break; + + /* + * Since there is no individual mask, we have to + * mask the parent IRQ. This is safe, since we'll + * recheck the register for any pending IRQs. + */ + if (irr & (IRR_ETHERNET | IRR_USAR)) { + desc->chip->mask(irq); + + if (irr & IRR_ETHERNET) { + d = irq_desc + IRQ_NEPONSET_SMC9196; + d->handle(IRQ_NEPONSET_SMC9196, d, regs); + } + + if (irr & IRR_USAR) { + d = irq_desc + IRQ_NEPONSET_USAR; + d->handle(IRQ_NEPONSET_USAR, d, regs); + } + + desc->chip->unmask(irq); + } + + if (irr & IRR_SA1111) { + d = irq_desc + IRQ_NEPONSET_SA1111; + d->handle(IRQ_NEPONSET_SA1111, d, regs); + } + } +} + +static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) +{ + u_int mdm_ctl0 = MDM_CTL_0; + + if (port->mapbase == _Ser1UTCR0) { + if (mctrl & TIOCM_RTS) + mdm_ctl0 &= ~MDM_CTL0_RTS2; + else + mdm_ctl0 |= MDM_CTL0_RTS2; + + if (mctrl & TIOCM_DTR) + mdm_ctl0 &= ~MDM_CTL0_DTR2; + else + mdm_ctl0 |= MDM_CTL0_DTR2; + } else if (port->mapbase == _Ser3UTCR0) { + if (mctrl & TIOCM_RTS) + mdm_ctl0 &= ~MDM_CTL0_RTS1; + else + mdm_ctl0 |= MDM_CTL0_RTS1; + + if (mctrl & TIOCM_DTR) + mdm_ctl0 &= ~MDM_CTL0_DTR1; + else + mdm_ctl0 |= MDM_CTL0_DTR1; + } + + MDM_CTL_0 = mdm_ctl0; +} + +static u_int neponset_get_mctrl(struct uart_port *port) +{ + u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; + u_int mdm_ctl1 = MDM_CTL_1; + + if (port->mapbase == _Ser1UTCR0) { + if (mdm_ctl1 & MDM_CTL1_DCD2) + ret &= ~TIOCM_CD; + if (mdm_ctl1 & MDM_CTL1_CTS2) + ret &= ~TIOCM_CTS; + if (mdm_ctl1 & MDM_CTL1_DSR2) + ret &= ~TIOCM_DSR; + } else if (port->mapbase == _Ser3UTCR0) { + if (mdm_ctl1 & MDM_CTL1_DCD1) + ret &= ~TIOCM_CD; + if (mdm_ctl1 & MDM_CTL1_CTS1) + ret &= ~TIOCM_CTS; + if (mdm_ctl1 & MDM_CTL1_DSR1) + ret &= ~TIOCM_DSR; + } + + return ret; +} + +static struct sa1100_port_fns neponset_port_fns __initdata = { + .set_mctrl = neponset_set_mctrl, + .get_mctrl = neponset_get_mctrl, +}; + +static int neponset_probe(struct device *dev) +{ + sa1100_register_uart_fns(&neponset_port_fns); + + /* + * Install handler for GPIO25. + */ + set_irq_type(IRQ_GPIO25, IRQT_RISING); + set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler); + + /* + * We would set IRQ_GPIO25 to be a wake-up IRQ, but + * unfortunately something on the Neponset activates + * this IRQ on sleep (ethernet?) + */ +#if 0 + enable_irq_wake(IRQ_GPIO25); +#endif + + /* + * Setup other Neponset IRQs. SA1111 will be done by the + * generic SA1111 code. + */ + set_irq_handler(IRQ_NEPONSET_SMC9196, do_simple_IRQ); + set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE); + set_irq_handler(IRQ_NEPONSET_USAR, do_simple_IRQ); + set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE); + + /* + * Disable GPIO 0/1 drivers so the buttons work on the module. + */ + NCR_0 = NCR_GP01_OFF; + + return 0; +} + +#ifdef CONFIG_PM + +/* + * LDM power management. + */ +static int neponset_suspend(struct device *dev, pm_message_t state, u32 level) +{ + /* + * Save state. + */ + if (level == SUSPEND_SAVE_STATE || + level == SUSPEND_DISABLE || + level == SUSPEND_POWER_DOWN) { + if (!dev->power.saved_state) + dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL); + if (!dev->power.saved_state) + return -ENOMEM; + + *(unsigned int *)dev->power.saved_state = NCR_0; + } + + return 0; +} + +static int neponset_resume(struct device *dev, u32 level) +{ + if (level == RESUME_RESTORE_STATE || level == RESUME_ENABLE) { + if (dev->power.saved_state) { + NCR_0 = *(unsigned int *)dev->power.saved_state; + kfree(dev->power.saved_state); + dev->power.saved_state = NULL; + } + } + + return 0; +} + +#else +#define neponset_suspend NULL +#define neponset_resume NULL +#endif + +static struct device_driver neponset_device_driver = { + .name = "neponset", + .bus = &platform_bus_type, + .probe = neponset_probe, + .suspend = neponset_suspend, + .resume = neponset_resume, +}; + +static struct resource neponset_resources[] = { + [0] = { + .start = 0x10000000, + .end = 0x17ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device neponset_device = { + .name = "neponset", + .id = 0, + .num_resources = ARRAY_SIZE(neponset_resources), + .resource = neponset_resources, +}; + +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NEPONSET_SA1111, + .end = IRQ_NEPONSET_SA1111, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .dma_mask = &sa1111_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = SA1100_CS3_PHYS, + .end = SA1100_CS3_PHYS + 0x01ffffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NEPONSET_SMC9196, + .end = IRQ_NEPONSET_SMC9196, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "smc91x-attrib", + .start = SA1100_CS3_PHYS + 0x02000000, + .end = SA1100_CS3_PHYS + 0x03ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct platform_device *devices[] __initdata = { + &neponset_device, + &sa1111_device, + &smc91x_device, +}; + +static int __init neponset_init(void) +{ + driver_register(&neponset_device_driver); + + /* + * The Neponset is only present on the Assabet machine type. + */ + if (!machine_is_assabet()) + return -ENODEV; + + /* + * Ensure that the memory bus request/grant signals are setup, + * and the grant is held in its inactive state, whether or not + * we actually have a Neponset attached. + */ + sa1110_mb_disable(); + + if (!machine_has_neponset()) { + printk(KERN_DEBUG "Neponset expansion board not present\n"); + return -ENODEV; + } + + if (WHOAMI != 0x11) { + printk(KERN_WARNING "Neponset board detected, but " + "wrong ID: %02x\n", WHOAMI); + return -ENODEV; + } + + return platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +subsys_initcall(neponset_init); + +static struct map_desc neponset_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xf3000000, 0x10000000, SZ_1M, MT_DEVICE }, /* System Registers */ + { 0xf4000000, 0x40000000, SZ_1M, MT_DEVICE } /* SA-1111 */ +}; + +void __init neponset_map_io(void) +{ + iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc)); +} diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c new file mode 100644 index 0000000..5606bd7 --- /dev/null +++ b/arch/arm/mach-sa1100/pleb.c @@ -0,0 +1,154 @@ +/* + * linux/arch/arm/mach-sa1100/pleb.c + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/tty.h> +#include <linux/ioport.h> +#include <linux/device.h> + +#include <linux/mtd/partitions.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/flash.h> +#include <asm/mach/serial_sa1100.h> +#include <asm/arch/irqs.h> + +#include "generic.h" + + +/* + * Ethernet IRQ mappings + */ + +#define PLEB_ETH0_P (0x20000300) /* Ethernet 0 in PCMCIA0 IO */ +#define PLEB_ETH0_V (0xf6000300) + +#define GPIO_ETH0_IRQ GPIO_GPIO(21) +#define GPIO_ETH0_EN GPIO_GPIO(26) + +#define IRQ_GPIO_ETH0_IRQ IRQ_GPIO21 + +static struct resource smc91x_resources[] = { + [0] = { + .start = PLEB_ETH0_P, + .end = PLEB_ETH0_P | 0x03ffffff, + .flags = IORESOURCE_MEM, + }, +#if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */ + [1] = { + .start = IRQ_GPIO_ETH0_IRQ, + .end = IRQ_GPIO_ETH0_IRQ, + .flags = IORESOURCE_IRQ, + }, +#endif +}; + + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static struct platform_device *devices[] __initdata = { + &smc91x_device, +}; + + +/* + * Pleb's memory map + * has flash memory (typically 4 or 8 meg) selected by + * the two SA1100 lowest chip select outputs. + */ +static struct resource pleb_flash_resources[] = { + [0] = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SA1100_CS1_PHYS, + .end = SA1100_CS1_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, + } +}; + + +static struct mtd_partition pleb_partitions[] = { + { + .name = "blob", + .offset = 0, + .size = 0x00020000, + }, { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 0x000e0000, + }, { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 0x00300000, + } +}; + + +static struct flash_platform_data pleb_flash_data = { + .map_name = "cfi_probe", + .parts = pleb_partitions, + .nr_parts = ARRAY_SIZE(pleb_partitions), +}; + + +static void __init pleb_init(void) +{ + sa11x0_set_flash_data(&pleb_flash_data, pleb_flash_resources, + ARRAY_SIZE(pleb_flash_resources)); + + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + + +static void __init pleb_map_io(void) +{ + sa1100_map_io(); + + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); + + GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD); + GPDR |= GPIO_UART_TXD; + GPDR &= ~GPIO_UART_RXD; + PPAR |= PPAR_UPR; + + /* + * Fix expansion memory timing for network card + */ + MECR = ((2<<10) | (2<<5) | (2<<0)); + + /* + * Enable the SMC ethernet controller + */ + GPDR |= GPIO_ETH0_EN; /* set to output */ + GPCR = GPIO_ETH0_EN; /* clear MCLK (enable smc) */ + + GPDR &= ~GPIO_ETH0_IRQ; + + set_irq_type(GPIO_ETH0_IRQ, IRQT_FALLING); +} + +MACHINE_START(PLEB, "PLEB") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + MAPIO(pleb_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, + .init_machine = pleb_init, +MACHINE_END diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c new file mode 100644 index 0000000..379ea5e --- /dev/null +++ b/arch/arm/mach-sa1100/pm.c @@ -0,0 +1,167 @@ +/* + * SA1100 Power Management Routines + * + * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + * + * History: + * + * 2001-02-06: Cliff Brake Initial code + * + * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> & + * Chester Kuo <chester@linux.org.tw> + * Save more value for the resume function! Support + * Bitsy/Assabet/Freebird board + * + * 2001-08-29: Nicolas Pitre <nico@cam.org> + * Cleaned up, pushed platform dependent stuff + * in the platform specific files. + * + * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array. + * Storage is local on the stack now. + */ +#include <linux/init.h> +#include <linux/suspend.h> +#include <linux/errno.h> +#include <linux/time.h> + +#include <asm/hardware.h> +#include <asm/memory.h> +#include <asm/system.h> +#include <asm/mach/time.h> + +extern void sa1100_cpu_suspend(void); +extern void sa1100_cpu_resume(void); + +#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x +#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] + +/* + * List of global SA11x0 peripheral registers to preserve. + * More ones like CP and general purpose register values are preserved + * on the stack and then the stack pointer is stored last in sleep.S. + */ +enum { SLEEP_SAVE_SP = 0, + + SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR, + SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR, + + SLEEP_SAVE_Ser1SDCR0, + + SLEEP_SAVE_SIZE +}; + + +static int sa11x0_pm_enter(suspend_state_t state) +{ + unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE]; + struct timespec delta, rtc; + + if (state != PM_SUSPEND_MEM) + return -EINVAL; + + /* preserve current time */ + rtc.tv_sec = RCNR; + rtc.tv_nsec = 0; + save_time_delta(&delta, &rtc); + gpio = GPLR; + + /* save vital registers */ + SAVE(GPDR); + SAVE(GAFR); + + SAVE(PPDR); + SAVE(PPSR); + SAVE(PPAR); + SAVE(PSDR); + + SAVE(Ser1SDCR0); + + /* Clear previous reset status */ + RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR; + + /* set resume return address */ + PSPR = virt_to_phys(sa1100_cpu_resume); + + /* go zzz */ + sa1100_cpu_suspend(); + + /* + * Ensure not to come back here if it wasn't intended + */ + PSPR = 0; + + /* + * Ensure interrupt sources are disabled; we will re-init + * the interrupt subsystem via the device manager. + */ + ICLR = 0; + ICCR = 1; + ICMR = 0; + + /* restore registers */ + RESTORE(GPDR); + RESTORE(GAFR); + + RESTORE(PPDR); + RESTORE(PPSR); + RESTORE(PPAR); + RESTORE(PSDR); + + RESTORE(Ser1SDCR0); + + GPSR = gpio; + GPCR = ~gpio; + + /* + * Clear the peripheral sleep-hold bit. + */ + PSSR = PSSR_PH; + + /* restore current time */ + rtc.tv_sec = RCNR; + restore_time_delta(&delta, &rtc); + + return 0; +} + +unsigned long sleep_phys_sp(void *sp) +{ + return virt_to_phys(sp); +} + +/* + * Called after processes are frozen, but before we shut down devices. + */ +static int sa11x0_pm_prepare(suspend_state_t state) +{ + return 0; +} + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +static int sa11x0_pm_finish(suspend_state_t state) +{ + return 0; +} + +/* + * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. + */ +static struct pm_ops sa11x0_pm_ops = { + .pm_disk_mode = PM_DISK_FIRMWARE, + .prepare = sa11x0_pm_prepare, + .enter = sa11x0_pm_enter, + .finish = sa11x0_pm_finish, +}; + +static int __init sa11x0_pm_init(void) +{ + pm_set_ops(&sa11x0_pm_ops); + return 0; +} + +late_initcall(sa11x0_pm_init); diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c new file mode 100644 index 0000000..edddd55 --- /dev/null +++ b/arch/arm/mach-sa1100/shannon.c @@ -0,0 +1,85 @@ +/* + * linux/arch/arm/mach-sa1100/shannon.c + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/tty.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/setup.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> +#include <asm/mach/serial_sa1100.h> +#include <asm/arch/shannon.h> + +#include "generic.h" + +static struct mtd_partition shannon_partitions[] = { + { + .name = "BLOB boot loader", + .offset = 0, + .size = 0x20000 + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = 0xe0000 + }, + { + .name = "initrd", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL + } +}; + +static struct flash_platform_data shannon_flash_data = { + .map_name = "cfi_probe", + .parts = shannon_partitions, + .nr_parts = ARRAY_SIZE(shannon_partitions), +}; + +static struct resource shannon_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_4M - 1, + .flags = IORESOURCE_MEM, +}; + +static void __init shannon_init(void) +{ + sa11x0_set_flash_data(&shannon_flash_data, &shannon_flash_resource, 1); +} + +static void __init shannon_map_io(void) +{ + sa1100_map_io(); + + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); + + Ser1SDCR0 |= SDCR0_SUS; + GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD); + GPDR |= GPIO_UART_TXD | SHANNON_GPIO_CODEC_RESET; + GPDR &= ~GPIO_UART_RXD; + PPAR |= PPAR_UPR; + + /* reset the codec */ + GPCR = SHANNON_GPIO_CODEC_RESET; + GPSR = SHANNON_GPIO_CODEC_RESET; +} + +MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(shannon_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, + .init_machine = shannon_init, +MACHINE_END diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c new file mode 100644 index 0000000..8d113d6 --- /dev/null +++ b/arch/arm/mach-sa1100/simpad.c @@ -0,0 +1,224 @@ +/* + * linux/arch/arm/mach-sa1100/simpad.c + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/tty.h> +#include <linux/proc_fs.h> +#include <linux/string.h> +#include <linux/pm.h> +#include <linux/device.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/setup.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/map.h> +#include <asm/mach/serial_sa1100.h> +#include <asm/arch/simpad.h> + +#include <linux/serial_core.h> +#include <linux/ioport.h> +#include <asm/io.h> + +#include "generic.h" + +long cs3_shadow; + +long get_cs3_shadow(void) +{ + return cs3_shadow; +} + +void set_cs3(long value) +{ + *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value; +} + +void set_cs3_bit(int value) +{ + cs3_shadow |= value; + *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow; +} + +void clear_cs3_bit(int value) +{ + cs3_shadow &= ~value; + *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow; +} + +EXPORT_SYMBOL(set_cs3_bit); +EXPORT_SYMBOL(clear_cs3_bit); + +static struct map_desc simpad_io_desc[] __initdata = { + /* virtual physical length type */ + /* MQ200 */ + { 0xf2800000, 0x4b800000, 0x00800000, MT_DEVICE }, + /* Paules CS3, write only */ + { 0xf1000000, 0x18000000, 0x00100000, MT_DEVICE }, +}; + + +static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + if (port->mapbase == (u_int)&Ser1UTCR0) { + if (state) + { + clear_cs3_bit(RS232_ON); + clear_cs3_bit(DECT_POWER_ON); + }else + { + set_cs3_bit(RS232_ON); + set_cs3_bit(DECT_POWER_ON); + } + } +} + +static struct sa1100_port_fns simpad_port_fns __initdata = { + .pm = simpad_uart_pm, +}; + + +static struct mtd_partition simpad_partitions[] = { + { + .name = "SIMpad boot firmware", + .size = 0x00080000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "SIMpad kernel", + .size = 0x0010000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "SIMpad root jffs2", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct flash_platform_data simpad_flash_data = { + .map_name = "cfi_probe", + .parts = simpad_partitions, + .nr_parts = ARRAY_SIZE(simpad_partitions), +}; + + +static struct resource simpad_flash_resources [] = { + { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_16M -1, + .flags = IORESOURCE_MEM, + }, { + .start = SA1100_CS1_PHYS, + .end = SA1100_CS1_PHYS + SZ_16M -1, + .flags = IORESOURCE_MEM, + } +}; + + + +static void __init simpad_map_io(void) +{ + sa1100_map_io(); + + iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc)); + + set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | + ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON); + + + sa1100_register_uart_fns(&simpad_port_fns); + sa1100_register_uart(0, 3); /* serial interface */ + sa1100_register_uart(1, 1); /* DECT */ + + // Reassign UART 1 pins + GAFR |= GPIO_UART_TXD | GPIO_UART_RXD; + GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15; + GPDR &= ~GPIO_UART_RXD; + PPAR |= PPAR_UPR; + + /* + * Set up registers for sleep mode. + */ + + + PWER = PWER_GPIO0| PWER_RTC; + PGSR = 0x818; + PCFR = 0; + PSDR = 0; + + sa11x0_set_flash_data(&simpad_flash_data, simpad_flash_resources, + ARRAY_SIZE(simpad_flash_resources)); +} + +static void simpad_power_off(void) +{ + local_irq_disable(); // was cli + set_cs3(0x800); /* only SD_MEDIAQ */ + + /* disable internal oscillator, float CS lines */ + PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); + /* enable wake-up on GPIO0 (Assabet...) */ + PWER = GFER = GRER = 1; + /* + * set scratchpad to zero, just in case it is used as a + * restart address by the bootloader. + */ + PSPR = 0; + PGSR = 0; + /* enter sleep mode */ + PMCR = PMCR_SF; + while(1); + + local_irq_enable(); /* we won't ever call it */ + + +} + + +/* + * MediaQ Video Device + */ +static struct platform_device simpad_mq200fb = { + .name = "simpad-mq200", + .id = 0, +}; + +static struct platform_device *devices[] __initdata = { + &simpad_mq200fb +}; + + + +static int __init simpad_init(void) +{ + int ret; + + pm_power_off = simpad_power_off; + + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + if(ret) + printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device"); + + return 0; +} + +arch_initcall(simpad_init); + + +MACHINE_START(SIMPAD, "Simpad") + MAINTAINER("Holger Freyther") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(simpad_map_io) + INITIRQ(sa1100_init_irq) + .timer = &sa1100_timer, +MACHINE_END diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S new file mode 100644 index 0000000..2fa1e28 --- /dev/null +++ b/arch/arm/mach-sa1100/sleep.S @@ -0,0 +1,215 @@ +/* + * SA11x0 Assembler Sleep/WakeUp Management Routines + * + * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License. + * + * History: + * + * 2001-02-06: Cliff Brake Initial code + * + * 2001-08-29: Nicolas Pitre Simplified. + * + * 2002-05-27: Nicolas Pitre Revisited, more cleanup and simplification. + * Storage is on the stack now. + */ + +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> + + + + .text + + + +/* + * sa1100_cpu_suspend() + * + * Causes sa11x0 to enter sleep state + * + */ + +ENTRY(sa1100_cpu_suspend) + + stmfd sp!, {r4 - r12, lr} @ save registers on stack + + @ get coprocessor registers + mrc p15, 0, r4, c3, c0, 0 @ domain ID + mrc p15, 0, r5, c2, c0, 0 @ translation table base addr + mrc p15, 0, r6, c13, c0, 0 @ PID + mrc p15, 0, r7, c1, c0, 0 @ control reg + + @ store them plus current virtual stack ptr on stack + mov r8, sp + stmfd sp!, {r4 - r8} + + @ preserve phys address of stack + mov r0, sp + bl sleep_phys_sp + ldr r1, =sleep_save_sp + str r0, [r1] + + @ clean data cache and invalidate WB + bl v4wb_flush_kern_cache_all + + @ disable clock switching + mcr p15, 0, r1, c15, c2, 2 + + @ Adjust memory timing before lowering CPU clock + @ Clock speed adjustment without changing memory timing makes + @ CPU hang in some cases + ldr r0, =MDREFR + ldr r1, [r0] + orr r1, r1, #MDREFR_K1DB2 + str r1, [r0] + + @ delay 90us and set CPU PLL to lowest speed + @ fixes resume problem on high speed SA1110 + mov r0, #90 + bl __udelay + ldr r0, =PPCR + mov r1, #0 + str r1, [r0] + mov r0, #90 + bl __udelay + + /* + * SA1110 SDRAM controller workaround. register values: + * + * r0 = &MSC0 + * r1 = &MSC1 + * r2 = &MSC2 + * r3 = MSC0 value + * r4 = MSC1 value + * r5 = MSC2 value + * r6 = &MDREFR + * r7 = first MDREFR value + * r8 = second MDREFR value + * r9 = &MDCNFG + * r10 = MDCNFG value + * r11 = third MDREFR value + * r12 = &PMCR + * r13 = PMCR value (1) + */ + + ldr r0, =MSC0 + ldr r1, =MSC1 + ldr r2, =MSC2 + + ldr r3, [r0] + bic r3, r3, #FMsk(MSC_RT) + bic r3, r3, #FMsk(MSC_RT)<<16 + + ldr r4, [r1] + bic r4, r4, #FMsk(MSC_RT) + bic r4, r4, #FMsk(MSC_RT)<<16 + + ldr r5, [r2] + bic r5, r5, #FMsk(MSC_RT) + bic r5, r5, #FMsk(MSC_RT)<<16 + + ldr r6, =MDREFR + + ldr r7, [r6] + bic r7, r7, #0x0000FF00 + bic r7, r7, #0x000000F0 + orr r8, r7, #MDREFR_SLFRSH + + ldr r9, =MDCNFG + ldr r10, [r9] + bic r10, r10, #(MDCNFG_DE0+MDCNFG_DE1) + bic r10, r10, #(MDCNFG_DE2+MDCNFG_DE3) + + bic r11, r8, #MDREFR_SLFRSH + bic r11, r11, #MDREFR_E1PIN + + ldr r12, =PMCR + + mov r13, #PMCR_SF + + b sa1110_sdram_controller_fix + + .align 5 +sa1110_sdram_controller_fix: + + @ Step 1 clear RT field of all MSCx registers + str r3, [r0] + str r4, [r1] + str r5, [r2] + + @ Step 2 clear DRI field in MDREFR + str r7, [r6] + + @ Step 3 set SLFRSH bit in MDREFR + str r8, [r6] + + @ Step 4 clear DE bis in MDCNFG + str r10, [r9] + + @ Step 5 clear DRAM refresh control register + str r11, [r6] + + @ Wow, now the hardware suspend request pins can be used, that makes them functional for + @ about 7 ns out of the entire time that the CPU is running! + + @ Step 6 set force sleep bit in PMCR + + str r13, [r12] + +20: b 20b @ loop waiting for sleep + +/* + * cpu_sa1100_resume() + * + * entry point from bootloader into kernel during resume + * + * Note: Yes, part of the following code is located into the .data section. + * This is to allow sleep_save_sp to be accessed with a relative load + * while we can't rely on any MMU translation. We could have put + * sleep_save_sp in the .text section as well, but some setups might + * insist on it to be truly read-only. + */ + + .data + .align 5 +ENTRY(sa1100_cpu_resume) + mov r0, #PSR_F_BIT | PSR_I_BIT | MODE_SVC + msr cpsr_c, r0 @ set SVC, irqs off + + ldr r0, sleep_save_sp @ stack phys addr + ldr r2, =resume_after_mmu @ its absolute virtual address + ldmfd r0, {r4 - r7, sp} @ CP regs + virt stack ptr + + mov r1, #0 + mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs + mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache + mcr p15, 0, r1, c9, c0, 0 @ invalidate RB + mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB + + mcr p15, 0, r4, c3, c0, 0 @ domain ID + mcr p15, 0, r5, c2, c0, 0 @ translation table base addr + mcr p15, 0, r6, c13, c0, 0 @ PID + b resume_turn_on_mmu @ cache align execution + + .align 5 +resume_turn_on_mmu: + mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, caches, etc. + nop + mov pc, r2 @ jump to virtual addr + nop + nop + nop + +sleep_save_sp: + .word 0 @ preserve stack phys ptr here + + .text +resume_after_mmu: + mcr p15, 0, r1, c15, c1, 2 @ enable clock switching + ldmfd sp!, {r4 - r12, pc} @ return to caller + + diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c new file mode 100644 index 0000000..1604dad --- /dev/null +++ b/arch/arm/mach-sa1100/ssp.c @@ -0,0 +1,214 @@ +/* + * linux/arch/arm/mach-sa1100/ssp.c + * + * Copyright (C) 2003 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. + * + * Generic SSP driver. This provides the generic core for simple + * IO-based SSP applications. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/hardware/ssp.h> + +static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int status = Ser4SSSR; + + if (status & SSSR_ROR) { + printk(KERN_WARNING "SSP: receiver overrun\n"); + } + + Ser4SSSR = SSSR_ROR; + + return status ? IRQ_HANDLED : IRQ_NONE; +} + +/** + * ssp_write_word - write a word to the SSP port + * @data: 16-bit, MSB justified data to write. + * + * Wait for a free entry in the SSP transmit FIFO, and write a data + * word to the SSP port. Wait for the SSP port to start sending + * the data. + * + * The caller is expected to perform the necessary locking. + * + * Returns: + * %-ETIMEDOUT timeout occurred (for future) + * 0 success + */ +int ssp_write_word(u16 data) +{ + while (!(Ser4SSSR & SSSR_TNF)) + cpu_relax(); + + Ser4SSDR = data; + + while (!(Ser4SSSR & SSSR_BSY)) + cpu_relax(); + + return 0; +} + +/** + * ssp_read_word - read a word from the SSP port + * + * Wait for a data word in the SSP receive FIFO, and return the + * received data. Data is LSB justified. + * + * Note: Currently, if data is not expected to be received, this + * function will wait for ever. + * + * The caller is expected to perform the necessary locking. + * + * Returns: + * %-ETIMEDOUT timeout occurred (for future) + * 16-bit data success + */ +int ssp_read_word(void) +{ + while (!(Ser4SSSR & SSSR_RNE)) + cpu_relax(); + + return Ser4SSDR; +} + +/** + * ssp_flush - flush the transmit and receive FIFOs + * + * Wait for the SSP to idle, and ensure that the receive FIFO + * is empty. + * + * The caller is expected to perform the necessary locking. + */ +void ssp_flush(void) +{ + do { + while (Ser4SSSR & SSSR_RNE) { + (void) Ser4SSDR; + } + } while (Ser4SSSR & SSSR_BSY); +} + +/** + * ssp_enable - enable the SSP port + * + * Turn on the SSP port. + */ +void ssp_enable(void) +{ + Ser4SSCR0 |= SSCR0_SSE; +} + +/** + * ssp_disable - shut down the SSP port + * + * Turn off the SSP port, optionally powering it down. + */ +void ssp_disable(void) +{ + Ser4SSCR0 &= ~SSCR0_SSE; +} + +/** + * ssp_save_state - save the SSP configuration + * @ssp: pointer to structure to save SSP configuration + * + * Save the configured SSP state for suspend. + */ +void ssp_save_state(struct ssp_state *ssp) +{ + ssp->cr0 = Ser4SSCR0; + ssp->cr1 = Ser4SSCR1; + + Ser4SSCR0 &= ~SSCR0_SSE; +} + +/** + * ssp_restore_state - restore a previously saved SSP configuration + * @ssp: pointer to configuration saved by ssp_save_state + * + * Restore the SSP configuration saved previously by ssp_save_state. + */ +void ssp_restore_state(struct ssp_state *ssp) +{ + Ser4SSSR = SSSR_ROR; + + Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE; + Ser4SSCR1 = ssp->cr1; + Ser4SSCR0 = ssp->cr0; +} + +/** + * ssp_init - setup the SSP port + * + * initialise and claim resources for the SSP port. + * + * Returns: + * %-ENODEV if the SSP port is unavailable + * %-EBUSY if the resources are already in use + * %0 on success + */ +int ssp_init(void) +{ + int ret; + + if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE)) + return -ENODEV; + + if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) { + return -EBUSY; + } + + Ser4SSSR = SSSR_ROR; + + ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL); + if (ret) + goto out_region; + + return 0; + + out_region: + release_mem_region(__PREG(Ser4SSCR0), 0x18); + return ret; +} + +/** + * ssp_exit - undo the effects of ssp_init + * + * release and free resources for the SSP port. + */ +void ssp_exit(void) +{ + Ser4SSCR0 &= ~SSCR0_SSE; + + free_irq(IRQ_Ser4SSP, NULL); + release_mem_region(__PREG(Ser4SSCR0), 0x18); +} + +MODULE_AUTHOR("Russell King"); +MODULE_DESCRIPTION("SA11x0 SSP PIO driver"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(ssp_write_word); +EXPORT_SYMBOL(ssp_read_word); +EXPORT_SYMBOL(ssp_flush); +EXPORT_SYMBOL(ssp_enable); +EXPORT_SYMBOL(ssp_disable); +EXPORT_SYMBOL(ssp_save_state); +EXPORT_SYMBOL(ssp_restore_state); +EXPORT_SYMBOL(ssp_init); +EXPORT_SYMBOL(ssp_exit); diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c new file mode 100644 index 0000000..19b0c0f --- /dev/null +++ b/arch/arm/mach-sa1100/time.c @@ -0,0 +1,159 @@ +/* + * linux/arch/arm/mach-sa1100/time.c + * + * Copyright (C) 1998 Deborah Wallach. + * Twiddles (C) 1999 Hugo Fiennes <hugo@empeg.com> + * + * 2000/03/29 (C) Nicolas Pitre <nico@cam.org> + * Rewritten: big cleanup, much simpler, better HZ accuracy. + * + */ +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/timex.h> +#include <linux/signal.h> + +#include <asm/mach/time.h> +#include <asm/hardware.h> + +#define RTC_DEF_DIVIDER (32768 - 1) +#define RTC_DEF_TRIM 0 + +static unsigned long __init sa1100_get_rtc_time(void) +{ + /* + * According to the manual we should be able to let RTTR be zero + * and then a default diviser for a 32.768KHz clock is used. + * Apparently this doesn't work, at least for my SA1110 rev 5. + * If the clock divider is uninitialized then reset it to the + * default value to get the 1Hz clock. + */ + if (RTTR == 0) { + RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); + printk(KERN_WARNING "Warning: uninitialized Real Time Clock\n"); + /* The current RTC value probably doesn't make sense either */ + RCNR = 0; + return 0; + } + return RCNR; +} + +static int sa1100_set_rtc(void) +{ + unsigned long current_time = xtime.tv_sec; + + if (RTSR & RTSR_ALE) { + /* make sure not to forward the clock over an alarm */ + unsigned long alarm = RTAR; + if (current_time >= alarm && alarm >= RCNR) + return -ERESTARTSYS; + } + RCNR = current_time; + return 0; +} + +/* IRQs are disabled before entering here from do_gettimeofday() */ +static unsigned long sa1100_gettimeoffset (void) +{ + unsigned long ticks_to_match, elapsed, usec; + + /* Get ticks before next timer match */ + ticks_to_match = OSMR0 - OSCR; + + /* We need elapsed ticks since last match */ + elapsed = LATCH - ticks_to_match; + + /* Now convert them to usec */ + usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; + + return usec; +} + +/* + * We will be entered with IRQs enabled. + * + * Loop until we get ahead of the free running timer. + * This ensures an exact clock tick count and time accuracy. + * IRQs are disabled inside the loop to ensure coherence between + * lost_ticks (updated in do_timer()) and the match reg value, so we + * can use do_gettimeofday() from interrupt handlers. + */ +static irqreturn_t +sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int next_match; + + write_seqlock(&xtime_lock); + + do { + timer_tick(regs); + OSSR = OSSR_M0; /* Clear match on timer 0 */ + next_match = (OSMR0 += LATCH); + } while ((signed long)(next_match - OSCR) <= 0); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction sa1100_timer_irq = { + .name = "SA11xx Timer Tick", + .flags = SA_INTERRUPT, + .handler = sa1100_timer_interrupt +}; + +static void __init sa1100_timer_init(void) +{ + struct timespec tv; + + set_rtc = sa1100_set_rtc; + + tv.tv_nsec = 0; + tv.tv_sec = sa1100_get_rtc_time(); + do_settimeofday(&tv); + + OSMR0 = 0; /* set initial match at 0 */ + OSSR = 0xf; /* clear status on all timers */ + setup_irq(IRQ_OST0, &sa1100_timer_irq); + OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ + OSCR = 0; /* initialize free-running timer, force first match */ +} + +#ifdef CONFIG_PM +unsigned long osmr[4], oier; + +static void sa1100_timer_suspend(void) +{ + osmr[0] = OSMR0; + osmr[1] = OSMR1; + osmr[2] = OSMR2; + osmr[3] = OSMR3; + oier = OIER; +} + +static void sa1100_timer_resume(void) +{ + OSSR = 0x0f; + OSMR0 = osmr[0]; + OSMR1 = osmr[1]; + OSMR2 = osmr[2]; + OSMR3 = osmr[3]; + OIER = oier; + + /* + * OSMR0 is the system timer: make sure OSCR is sufficiently behind + */ + OSCR = OSMR0 - LATCH; +} +#else +#define sa1100_timer_suspend NULL +#define sa1100_timer_resume NULL +#endif + +struct sys_timer sa1100_timer = { + .init = sa1100_timer_init, + .suspend = sa1100_timer_suspend, + .resume = sa1100_timer_resume, + .offset = sa1100_gettimeoffset, +}; diff --git a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile new file mode 100644 index 0000000..45be9b0 --- /dev/null +++ b/arch/arm/mach-shark/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := core.o dma.o irq.o pci.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_LEDS) += leds.o diff --git a/arch/arm/mach-shark/Makefile.boot b/arch/arm/mach-shark/Makefile.boot new file mode 100644 index 0000000..4320f8b --- /dev/null +++ b/arch/arm/mach-shark/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y := 0x08008000 + diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c new file mode 100644 index 0000000..a9bc5d0 --- /dev/null +++ b/arch/arm/mach-shark/core.c @@ -0,0 +1,114 @@ +/* + * linux/arch/arm/mach-shark/arch.c + * + * Architecture specific stuff. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/sched.h> +#include <linux/serial_8250.h> + +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/io.h> +#include <asm/leds.h> +#include <asm/param.h> + +#include <asm/mach/map.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +static struct plat_serial8250_port serial_platform_data[] = { + { + .iobase = 0x3f8, + .irq = 4, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = 0x2f8, + .irq = 3, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static int __init shark_init(void) +{ + int ret; + + if (machine_is_shark()) + ret = platform_device_register(&serial_device); + + return ret; +} + +arch_initcall(shark_init); + +extern void shark_init_irq(void); + +static struct map_desc shark_io_desc[] __initdata = { + { IO_BASE , IO_START , IO_SIZE , MT_DEVICE } +}; + +static void __init shark_map_io(void) +{ + iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc)); +} + +#define IRQ_TIMER 0 +#define HZ_TIME ((1193180 + HZ/2) / HZ) + +static irqreturn_t +shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + timer_tick(regs); + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +static struct irqaction shark_timer_irq = { + .name = "Shark Timer Tick", + .flags = SA_INTERRUPT, + .handler = shark_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +static void __init shark_timer_init(void) +{ + outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */ + outb(HZ_TIME & 0xff, 0x40); /* LSB of count */ + outb(HZ_TIME >> 8, 0x40); + + setup_irq(IRQ_TIMER, &shark_timer_irq); +} + +static struct sys_timer shark_timer = { + .init = shark_timer_init, +}; + +MACHINE_START(SHARK, "Shark") + MAINTAINER("Alexander Schulz") + BOOT_MEM(0x08000000, 0x40000000, 0xe0000000) + BOOT_PARAMS(0x08003000) + MAPIO(shark_map_io) + INITIRQ(shark_init_irq) + .timer = &shark_timer, +MACHINE_END diff --git a/arch/arm/mach-shark/dma.c b/arch/arm/mach-shark/dma.c new file mode 100644 index 0000000..835989a --- /dev/null +++ b/arch/arm/mach-shark/dma.c @@ -0,0 +1,22 @@ +/* + * linux/arch/arm/mach-shark/dma.c + * + * by Alexander Schulz + * + * derived from: + * arch/arm/kernel/dma-ebsa285.c + * Copyright (C) 1998 Phil Blundell + */ + +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/dma.h> +#include <asm/mach/dma.h> + +void __init arch_dma_init(dma_t *dma) +{ +#ifdef CONFIG_ISA_DMA + isa_init_dma(dma); +#endif +} diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c new file mode 100644 index 0000000..6cb67bd --- /dev/null +++ b/arch/arm/mach-shark/irq.c @@ -0,0 +1,109 @@ +/* + * linux/arch/arm/mach-shark/irq.c + * + * by Alexander Schulz + * + * derived from linux/arch/ppc/kernel/i8259.c and: + * include/asm-arm/arch-ebsa110/irq.h + * Copyright (C) 1996-1998 Russell King + */ + +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/ptrace.h> +#include <linux/interrupt.h> + +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/mach/irq.h> + +/* + * 8259A PIC functions to handle ISA devices: + */ + +/* + * This contains the irq mask for both 8259A irq controllers, + * Let through the cascade-interrupt no. 2 (ff-(1<<2)==fb) + */ +static unsigned char cached_irq_mask[2] = { 0xfb, 0xff }; + +/* + * These have to be protected by the irq controller spinlock + * before being called. + */ +static void shark_disable_8259A_irq(unsigned int irq) +{ + unsigned int mask; + if (irq<8) { + mask = 1 << irq; + cached_irq_mask[0] |= mask; + outb(cached_irq_mask[1],0xA1); + } else { + mask = 1 << (irq-8); + cached_irq_mask[1] |= mask; + outb(cached_irq_mask[0],0x21); + } +} + +static void shark_enable_8259A_irq(unsigned int irq) +{ + unsigned int mask; + if (irq<8) { + mask = ~(1 << irq); + cached_irq_mask[0] &= mask; + outb(cached_irq_mask[0],0x21); + } else { + mask = ~(1 << (irq-8)); + cached_irq_mask[1] &= mask; + outb(cached_irq_mask[1],0xA1); + } +} + +static void shark_ack_8259A_irq(unsigned int irq){} + +static irqreturn_t bogus_int(int irq, void *dev_id, struct pt_regs *regs) +{ + printk("Got interrupt %i!\n",irq); + return IRQ_NONE; +} + +static struct irqaction cascade; + +static struct irqchip fb_chip = { + .ack = shark_ack_8259A_irq, + .mask = shark_disable_8259A_irq, + .unmask = shark_enable_8259A_irq, +}; + +void __init shark_init_irq(void) +{ + int irq; + + for (irq = 0; irq < NR_IRQS; irq++) { + set_irq_chip(irq, &fb_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + /* init master interrupt controller */ + outb(0x11, 0x20); /* Start init sequence, edge triggered (level: 0x19)*/ + outb(0x00, 0x21); /* Vector base */ + outb(0x04, 0x21); /* Cascade (slave) on IRQ2 */ + outb(0x03, 0x21); /* Select 8086 mode , auto eoi*/ + outb(0x0A, 0x20); + /* init slave interrupt controller */ + outb(0x11, 0xA0); /* Start init sequence, edge triggered */ + outb(0x08, 0xA1); /* Vector base */ + outb(0x02, 0xA1); /* Cascade (slave) on IRQ2 */ + outb(0x03, 0xA1); /* Select 8086 mode, auto eoi */ + outb(0x0A, 0xA0); + outb(cached_irq_mask[1],0xA1); + outb(cached_irq_mask[0],0x21); + //request_region(0x20,0x2,"pic1"); + //request_region(0xA0,0x2,"pic2"); + + cascade.handler = bogus_int; + cascade.name = "cascade"; + setup_irq(2,&cascade); +} + diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c new file mode 100644 index 0000000..7bdeb70 --- /dev/null +++ b/arch/arm/mach-shark/leds.c @@ -0,0 +1,163 @@ +/* + * arch/arm/kernel/leds-shark.c + * by Alexander Schulz + * + * derived from: + * arch/arm/kernel/leds-footbridge.c + * Copyright (C) 1998-1999 Russell King + * + * DIGITAL Shark LED control routines. + * + * The leds use is as follows: + * - Green front - toggles state every 50 timer interrupts + * - Amber front - Unused, this is a dual color led (Amber/Green) + * - Amber back - On if system is not idle + * + * Changelog: + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/ioport.h> + +#include <asm/hardware.h> +#include <asm/leds.h> +#include <asm/io.h> +#include <asm/system.h> + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 +static char led_state; +static short hw_led_state; +static short saved_state; + +static DEFINE_SPINLOCK(leds_lock); + +short sequoia_read(int addr) { + outw(addr,0x24); + return inw(0x26); +} + +void sequoia_write(short value,short addr) { + outw(addr,0x24); + outw(value,0x26); +} + +static void sequoia_leds_event(led_event_t evt) +{ + unsigned long flags; + + spin_lock_irqsave(&leds_lock, flags); + + hw_led_state = sequoia_read(0x09); + + switch (evt) { + case led_start: + hw_led_state |= SEQUOIA_LED_GREEN; + hw_led_state |= SEQUOIA_LED_AMBER; +#ifdef CONFIG_LEDS_CPU + hw_led_state |= SEQUOIA_LED_BACK; +#else + hw_led_state &= ~SEQUOIA_LED_BACK; +#endif + led_state |= LED_STATE_ENABLED; + break; + + case led_stop: + hw_led_state &= ~SEQUOIA_LED_BACK; + hw_led_state |= SEQUOIA_LED_GREEN; + hw_led_state |= SEQUOIA_LED_AMBER; + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + saved_state = hw_led_state; + hw_led_state &= ~SEQUOIA_LED_BACK; + hw_led_state |= SEQUOIA_LED_GREEN; + hw_led_state |= SEQUOIA_LED_AMBER; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = saved_state; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= SEQUOIA_LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~SEQUOIA_LED_BACK; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= SEQUOIA_LED_BACK; + break; +#endif + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~SEQUOIA_LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= SEQUOIA_LED_GREEN; + break; + + case led_amber_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~SEQUOIA_LED_AMBER; + break; + + case led_amber_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= SEQUOIA_LED_AMBER; + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= SEQUOIA_LED_BACK; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~SEQUOIA_LED_BACK; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + sequoia_write(hw_led_state,0x09); + + spin_unlock_irqrestore(&leds_lock, flags); +} + +static int __init leds_init(void) +{ + extern void (*leds_event)(led_event_t); + short temp; + + leds_event = sequoia_leds_event; + + /* Make LEDs independent of power-state */ + request_region(0x24,4,"sequoia"); + temp = sequoia_read(0x09); + temp |= 1<<10; + sequoia_write(temp,0x09); + leds_event(led_start); + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c new file mode 100644 index 0000000..37a7112 --- /dev/null +++ b/arch/arm/mach-shark/pci.c @@ -0,0 +1,42 @@ +/* + * linux/arch/arm/mach-shark/pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/irq.h> +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->bus->number == 0) + if (dev->devfn == 0) return 255; + else return 11; + else return 255; +} + +extern void __init via82c505_preinit(void); + +static struct hw_pci shark_pci __initdata = { + .setup = via82c505_setup, + .swizzle = pci_std_swizzle, + .map_irq = shark_map_irq, + .nr_controllers = 1, + .scan = via82c505_scan_bus, + .preinit = via82c505_preinit, +}; + +static int __init shark_pci_init(void) +{ + if (machine_is_shark()) + pci_common_init(&shark_pci); + return 0; +} + +subsys_initcall(shark_pci_init); diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig new file mode 100644 index 0000000..8d787f4 --- /dev/null +++ b/arch/arm/mach-versatile/Kconfig @@ -0,0 +1,16 @@ +menu "Versatile platform type" + depends on ARCH_VERSATILE + +config ARCH_VERSATILE_PB + bool "Support Versatile/PB platform" + default y + help + Include support for the ARM(R) Versatile/PB platform. + +config MACH_VERSATILE_AB + bool "Support Versatile/AB platform" + default n + help + Include support for the ARM(R) Versatile/AP platform. + +endmenu diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile new file mode 100644 index 0000000..5d60883 --- /dev/null +++ b/arch/arm/mach-versatile/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the linux kernel. +# + +obj-y := core.o clock.o +obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o +obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o diff --git a/arch/arm/mach-versatile/Makefile.boot b/arch/arm/mach-versatile/Makefile.boot new file mode 100644 index 0000000..c7e75ac --- /dev/null +++ b/arch/arm/mach-versatile/Makefile.boot @@ -0,0 +1,4 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 + diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c new file mode 100644 index 0000000..48025c2 --- /dev/null +++ b/arch/arm/mach-versatile/clock.c @@ -0,0 +1,145 @@ +/* + * linux/arch/arm/mach-versatile/clock.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> + +#include <asm/semaphore.h> +#include <asm/hardware/clock.h> +#include <asm/hardware/icst307.h> + +#include "clock.h" + +static LIST_HEAD(clocks); +static DECLARE_MUTEX(clocks_sem); + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + down(&clocks_sem); + list_for_each_entry(p, &clocks, node) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + break; + } + } + up(&clocks_sem); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +void clk_put(struct clk *clk) +{ + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +int clk_use(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_use); + +void clk_unuse(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_unuse); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return rate; +} +EXPORT_SYMBOL(clk_round_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EIO; + + if (clk->setvco) { + struct icst307_vco vco; + + vco = icst307_khz_to_vco(clk->params, rate / 1000); + clk->rate = icst307_khz(clk->params, vco) * 1000; + + printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n", + clk->name, vco.s, vco.r, vco.v); + + clk->setvco(clk, vco); + ret = 0; + } + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +/* + * These are fixed clocks. + */ +static struct clk kmi_clk = { + .name = "KMIREFCLK", + .rate = 24000000, +}; + +static struct clk uart_clk = { + .name = "UARTCLK", + .rate = 24000000, +}; + +static struct clk mmci_clk = { + .name = "MCLK", + .rate = 33000000, +}; + +int clk_register(struct clk *clk) +{ + down(&clocks_sem); + list_add(&clk->node, &clocks); + up(&clocks_sem); + return 0; +} +EXPORT_SYMBOL(clk_register); + +void clk_unregister(struct clk *clk) +{ + down(&clocks_sem); + list_del(&clk->node); + up(&clocks_sem); +} +EXPORT_SYMBOL(clk_unregister); + +static int __init clk_init(void) +{ + clk_register(&kmi_clk); + clk_register(&uart_clk); + clk_register(&mmci_clk); + return 0; +} +arch_initcall(clk_init); diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h new file mode 100644 index 0000000..8b0b61d --- /dev/null +++ b/arch/arm/mach-versatile/clock.h @@ -0,0 +1,25 @@ +/* + * linux/arch/arm/mach-versatile/clock.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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. + */ +struct module; +struct icst307_params; + +struct clk { + struct list_head node; + unsigned long rate; + struct module *owner; + const char *name; + const struct icst307_params *params; + void *data; + void (*setvco)(struct clk *, struct icst307_vco vco); +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c new file mode 100644 index 0000000..554e1bd --- /dev/null +++ b/arch/arm/mach-versatile/core.c @@ -0,0 +1,918 @@ +/* + * linux/arch/arm/mach-versatile/core.c + * + * Copyright (C) 1999 - 2003 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/config.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/sysdev.h> +#include <linux/interrupt.h> + +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/leds.h> +#include <asm/mach-types.h> +#include <asm/hardware/amba.h> +#include <asm/hardware/amba_clcd.h> +#include <asm/hardware/icst307.h> + +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> +#include <asm/mach/map.h> +#include <asm/mach/mmc.h> + +#include "core.h" +#include "clock.h" + +/* + * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx + * is the (PA >> 12). + * + * Setup a VA for the Versatile Vectored Interrupt Controller. + */ +#define VA_VIC_BASE IO_ADDRESS(VERSATILE_VIC_BASE) +#define VA_SIC_BASE IO_ADDRESS(VERSATILE_SIC_BASE) + +static void vic_mask_irq(unsigned int irq) +{ + irq -= IRQ_VIC_START; + writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR); +} + +static void vic_unmask_irq(unsigned int irq) +{ + irq -= IRQ_VIC_START; + writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE); +} + +static struct irqchip vic_chip = { + .ack = vic_mask_irq, + .mask = vic_mask_irq, + .unmask = vic_unmask_irq, +}; + +static void sic_mask_irq(unsigned int irq) +{ + irq -= IRQ_SIC_START; + writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); +} + +static void sic_unmask_irq(unsigned int irq) +{ + irq -= IRQ_SIC_START; + writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET); +} + +static struct irqchip sic_chip = { + .ack = sic_mask_irq, + .mask = sic_mask_irq, + .unmask = sic_unmask_irq, +}; + +static void +sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS); + + if (status == 0) { + do_bad_IRQ(irq, desc, regs); + return; + } + + do { + irq = ffs(status) - 1; + status &= ~(1 << irq); + + irq += IRQ_SIC_START; + + desc = irq_desc + irq; + desc->handle(irq, desc, regs); + } while (status); +} + +#if 1 +#define IRQ_MMCI0A IRQ_VICSOURCE22 +#define IRQ_AACI IRQ_VICSOURCE24 +#define IRQ_ETH IRQ_VICSOURCE25 +#define PIC_MASK 0xFFD00000 +#else +#define IRQ_MMCI0A IRQ_SIC_MMCI0A +#define IRQ_AACI IRQ_SIC_AACI +#define IRQ_ETH IRQ_SIC_ETH +#define PIC_MASK 0 +#endif + +void __init versatile_init_irq(void) +{ + unsigned int i, value; + + /* Disable all interrupts initially. */ + + writel(0, VA_VIC_BASE + VIC_INT_SELECT); + writel(0, VA_VIC_BASE + VIC_IRQ_ENABLE); + writel(~0, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR); + writel(0, VA_VIC_BASE + VIC_IRQ_STATUS); + writel(0, VA_VIC_BASE + VIC_ITCR); + writel(~0, VA_VIC_BASE + VIC_IRQ_SOFT_CLEAR); + + /* + * Make sure we clear all existing interrupts + */ + writel(0, VA_VIC_BASE + VIC_VECT_ADDR); + for (i = 0; i < 19; i++) { + value = readl(VA_VIC_BASE + VIC_VECT_ADDR); + writel(value, VA_VIC_BASE + VIC_VECT_ADDR); + } + + for (i = 0; i < 16; i++) { + value = readl(VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4)); + writel(value | VICVectCntl_Enable | i, VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4)); + } + + writel(32, VA_VIC_BASE + VIC_DEF_VECT_ADDR); + + for (i = IRQ_VIC_START; i <= IRQ_VIC_END; i++) { + if (i != IRQ_VICSOURCE31) { + set_irq_chip(i, &vic_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + } + + set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq); + vic_unmask_irq(IRQ_VICSOURCE31); + + /* Do second interrupt controller */ + writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); + + for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { + if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) { + set_irq_chip(i, &sic_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + } + + /* + * Interrupts on secondary controller from 0 to 8 are routed to + * source 31 on PIC. + * Interrupts from 21 to 31 are routed directly to the VIC on + * the corresponding number on primary controller. This is controlled + * by setting PIC_ENABLEx. + */ + writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE); +} + +static struct map_desc versatile_io_desc[] __initdata = { + { IO_ADDRESS(VERSATILE_SYS_BASE), VERSATILE_SYS_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(VERSATILE_SIC_BASE), VERSATILE_SIC_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(VERSATILE_VIC_BASE), VERSATILE_VIC_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(VERSATILE_SCTL_BASE), VERSATILE_SCTL_BASE, SZ_4K * 9, MT_DEVICE }, +#ifdef CONFIG_MACH_VERSATILE_AB + { IO_ADDRESS(VERSATILE_GPIO0_BASE), VERSATILE_GPIO0_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(VERSATILE_IB2_BASE), VERSATILE_IB2_BASE, SZ_64M, MT_DEVICE }, +#endif +#ifdef CONFIG_DEBUG_LL + { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE }, +#endif +#ifdef FIXME + { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE }, + { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE }, + { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_512K, MT_DEVICE }, + { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE }, +#endif +}; + +void __init versatile_map_io(void) +{ + iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc)); +} + +#define VERSATILE_REFCOUNTER (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET) + +/* + * This is the Versatile sched_clock implementation. This has + * a resolution of 41.7ns, and a maximum value of about 179s. + */ +unsigned long long sched_clock(void) +{ + unsigned long long v; + + v = (unsigned long long)readl(VERSATILE_REFCOUNTER) * 125; + do_div(v, 3); + + return v; +} + + +#define VERSATILE_FLASHCTRL (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET) + +static int versatile_flash_init(void) +{ + u32 val; + + val = __raw_readl(VERSATILE_FLASHCTRL); + val &= ~VERSATILE_FLASHPROG_FLVPPEN; + __raw_writel(val, VERSATILE_FLASHCTRL); + + return 0; +} + +static void versatile_flash_exit(void) +{ + u32 val; + + val = __raw_readl(VERSATILE_FLASHCTRL); + val &= ~VERSATILE_FLASHPROG_FLVPPEN; + __raw_writel(val, VERSATILE_FLASHCTRL); +} + +static void versatile_flash_set_vpp(int on) +{ + u32 val; + + val = __raw_readl(VERSATILE_FLASHCTRL); + if (on) + val |= VERSATILE_FLASHPROG_FLVPPEN; + else + val &= ~VERSATILE_FLASHPROG_FLVPPEN; + __raw_writel(val, VERSATILE_FLASHCTRL); +} + +static struct flash_platform_data versatile_flash_data = { + .map_name = "cfi_probe", + .width = 4, + .init = versatile_flash_init, + .exit = versatile_flash_exit, + .set_vpp = versatile_flash_set_vpp, +}; + +static struct resource versatile_flash_resource = { + .start = VERSATILE_FLASH_BASE, + .end = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device versatile_flash_device = { + .name = "armflash", + .id = 0, + .dev = { + .platform_data = &versatile_flash_data, + }, + .num_resources = 1, + .resource = &versatile_flash_resource, +}; + +static struct resource smc91x_resources[] = { + [0] = { + .start = VERSATILE_ETH_BASE, + .end = VERSATILE_ETH_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_ETH, + .end = IRQ_ETH, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +#define VERSATILE_SYSMCI (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET) + +unsigned int mmc_status(struct device *dev) +{ + struct amba_device *adev = container_of(dev, struct amba_device, dev); + u32 mask; + + if (adev->res.start == VERSATILE_MMCI0_BASE) + mask = 1; + else + mask = 2; + + return readl(VERSATILE_SYSMCI) & mask; +} + +static struct mmc_platform_data mmc0_plat_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .status = mmc_status, +}; + +/* + * Clock handling + */ +static const struct icst307_params versatile_oscvco_params = { + .ref = 24000, + .vco_max = 200000, + .vd_min = 4 + 8, + .vd_max = 511 + 8, + .rd_min = 1 + 2, + .rd_max = 127 + 2, +}; + +static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco) +{ + unsigned long sys_lock = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET; +#if defined(CONFIG_ARCH_VERSATILE_PB) + unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC4_OFFSET; +#elif defined(CONFIG_MACH_VERSATILE_AB) + unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC1_OFFSET; +#endif + u32 val; + + val = readl(sys_osc) & ~0x7ffff; + val |= vco.v | (vco.r << 9) | (vco.s << 16); + + writel(0xa05f, sys_lock); + writel(val, sys_osc); + writel(0, sys_lock); +} + +static struct clk versatile_clcd_clk = { + .name = "CLCDCLK", + .params = &versatile_oscvco_params, + .setvco = versatile_oscvco_set, +}; + +/* + * CLCD support. + */ +#define SYS_CLCD_MODE_MASK (3 << 0) +#define SYS_CLCD_MODE_888 (0 << 0) +#define SYS_CLCD_MODE_5551 (1 << 0) +#define SYS_CLCD_MODE_565_RLSB (2 << 0) +#define SYS_CLCD_MODE_565_BLSB (3 << 0) +#define SYS_CLCD_NLCDIOON (1 << 2) +#define SYS_CLCD_VDDPOSSWITCH (1 << 3) +#define SYS_CLCD_PWR3V5SWITCH (1 << 4) +#define SYS_CLCD_ID_MASK (0x1f << 8) +#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8) +#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8) +#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8) +#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) +#define SYS_CLCD_ID_VGA (0x1f << 8) + +static struct clcd_panel vga = { + .mode = { + .name = "VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39721, + .left_margin = 40, + .right_margin = 24, + .upper_margin = 32, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .bpp = 16, +}; + +static struct clcd_panel sanyo_3_8_in = { + .mode = { + .name = "Sanyo QVGA", + .refresh = 116, + .xres = 320, + .yres = 240, + .pixclock = 100000, + .left_margin = 6, + .right_margin = 6, + .upper_margin = 5, + .lower_margin = 5, + .hsync_len = 6, + .vsync_len = 6, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .bpp = 16, +}; + +static struct clcd_panel sanyo_2_5_in = { + .mode = { + .name = "Sanyo QVGA Portrait", + .refresh = 116, + .xres = 240, + .yres = 320, + .pixclock = 100000, + .left_margin = 20, + .right_margin = 10, + .upper_margin = 2, + .lower_margin = 2, + .hsync_len = 10, + .vsync_len = 2, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .bpp = 16, +}; + +static struct clcd_panel epson_2_2_in = { + .mode = { + .name = "Epson QCIF", + .refresh = 390, + .xres = 176, + .yres = 220, + .pixclock = 62500, + .left_margin = 3, + .right_margin = 2, + .upper_margin = 1, + .lower_margin = 0, + .hsync_len = 3, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_BCD | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .bpp = 16, +}; + +/* + * Detect which LCD panel is connected, and return the appropriate + * clcd_panel structure. Note: we do not have any information on + * the required timings for the 8.4in panel, so we presently assume + * VGA timings. + */ +static struct clcd_panel *versatile_clcd_panel(void) +{ + unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; + struct clcd_panel *panel = &vga; + u32 val; + + val = readl(sys_clcd) & SYS_CLCD_ID_MASK; + if (val == SYS_CLCD_ID_SANYO_3_8) + panel = &sanyo_3_8_in; + else if (val == SYS_CLCD_ID_SANYO_2_5) + panel = &sanyo_2_5_in; + else if (val == SYS_CLCD_ID_EPSON_2_2) + panel = &epson_2_2_in; + else if (val == SYS_CLCD_ID_VGA) + panel = &vga; + else { + printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n", + val); + panel = &vga; + } + + return panel; +} + +/* + * Disable all display connectors on the interface module. + */ +static void versatile_clcd_disable(struct clcd_fb *fb) +{ + unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; + u32 val; + + val = readl(sys_clcd); + val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; + writel(val, sys_clcd); + +#ifdef CONFIG_MACH_VERSATILE_AB + /* + * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off + */ + if (fb->panel == &sanyo_2_5_in) { + unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL); + unsigned long ctrl; + + ctrl = readl(versatile_ib2_ctrl); + ctrl &= ~0x01; + writel(ctrl, versatile_ib2_ctrl); + } +#endif +} + +/* + * Enable the relevant connector on the interface module. + */ +static void versatile_clcd_enable(struct clcd_fb *fb) +{ + unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET; + u32 val; + + val = readl(sys_clcd); + val &= ~SYS_CLCD_MODE_MASK; + + switch (fb->fb.var.green.length) { + case 5: + val |= SYS_CLCD_MODE_5551; + break; + case 6: + val |= SYS_CLCD_MODE_565_BLSB; + break; + case 8: + val |= SYS_CLCD_MODE_888; + break; + } + + /* + * Set the MUX + */ + writel(val, sys_clcd); + + /* + * And now enable the PSUs + */ + val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; + writel(val, sys_clcd); + +#ifdef CONFIG_MACH_VERSATILE_AB + /* + * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on + */ + if (fb->panel == &sanyo_2_5_in) { + unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL); + unsigned long ctrl; + + ctrl = readl(versatile_ib2_ctrl); + ctrl |= 0x01; + writel(ctrl, versatile_ib2_ctrl); + } +#endif +} + +static unsigned long framesize = SZ_1M; + +static int versatile_clcd_setup(struct clcd_fb *fb) +{ + dma_addr_t dma; + + fb->panel = versatile_clcd_panel(); + + fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, + &dma, GFP_KERNEL); + if (!fb->fb.screen_base) { + printk(KERN_ERR "CLCD: unable to map framebuffer\n"); + return -ENOMEM; + } + + fb->fb.fix.smem_start = dma; + fb->fb.fix.smem_len = framesize; + + return 0; +} + +static int versatile_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) +{ + return dma_mmap_writecombine(&fb->dev->dev, vma, + fb->fb.screen_base, + fb->fb.fix.smem_start, + fb->fb.fix.smem_len); +} + +static void versatile_clcd_remove(struct clcd_fb *fb) +{ + dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, + fb->fb.screen_base, fb->fb.fix.smem_start); +} + +static struct clcd_board clcd_plat_data = { + .name = "Versatile", + .check = clcdfb_check, + .decode = clcdfb_decode, + .disable = versatile_clcd_disable, + .enable = versatile_clcd_enable, + .setup = versatile_clcd_setup, + .mmap = versatile_clcd_mmap, + .remove = versatile_clcd_remove, +}; + +#define AACI_IRQ { IRQ_AACI, NO_IRQ } +#define AACI_DMA { 0x80, 0x81 } +#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } +#define MMCI0_DMA { 0x84, 0 } +#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ } +#define KMI0_DMA { 0, 0 } +#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ } +#define KMI1_DMA { 0, 0 } + +/* + * These devices are connected directly to the multi-layer AHB switch + */ +#define SMC_IRQ { NO_IRQ, NO_IRQ } +#define SMC_DMA { 0, 0 } +#define MPMC_IRQ { NO_IRQ, NO_IRQ } +#define MPMC_DMA { 0, 0 } +#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ } +#define CLCD_DMA { 0, 0 } +#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ } +#define DMAC_DMA { 0, 0 } + +/* + * These devices are connected via the core APB bridge + */ +#define SCTL_IRQ { NO_IRQ, NO_IRQ } +#define SCTL_DMA { 0, 0 } +#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ } +#define WATCHDOG_DMA { 0, 0 } +#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ } +#define GPIO0_DMA { 0, 0 } +#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ } +#define GPIO1_DMA { 0, 0 } +#define RTC_IRQ { IRQ_RTCINT, NO_IRQ } +#define RTC_DMA { 0, 0 } + +/* + * These devices are connected via the DMA APB bridge + */ +#define SCI_IRQ { IRQ_SCIINT, NO_IRQ } +#define SCI_DMA { 7, 6 } +#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ } +#define UART0_DMA { 15, 14 } +#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ } +#define UART1_DMA { 13, 12 } +#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ } +#define UART2_DMA { 11, 10 } +#define SSP_IRQ { IRQ_SSPINT, NO_IRQ } +#define SSP_DMA { 9, 8 } + +/* FPGA Primecells */ +AMBA_DEVICE(aaci, "fpga:04", AACI, NULL); +AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data); +AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL); +AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL); + +/* DevChip Primecells */ +AMBA_DEVICE(smc, "dev:00", SMC, NULL); +AMBA_DEVICE(mpmc, "dev:10", MPMC, NULL); +AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data); +AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); +AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); +AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); +AMBA_DEVICE(gpio0, "dev:e4", GPIO0, NULL); +AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); +AMBA_DEVICE(rtc, "dev:e8", RTC, NULL); +AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); +AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); +AMBA_DEVICE(uart1, "dev:f2", UART1, NULL); +AMBA_DEVICE(uart2, "dev:f3", UART2, NULL); +AMBA_DEVICE(ssp0, "dev:f4", SSP, NULL); + +static struct amba_device *amba_devs[] __initdata = { + &dmac_device, + &uart0_device, + &uart1_device, + &uart2_device, + &smc_device, + &mpmc_device, + &clcd_device, + &sctl_device, + &wdog_device, + &gpio0_device, + &gpio1_device, + &rtc_device, + &sci0_device, + &ssp0_device, + &aaci_device, + &mmc0_device, + &kmi0_device, + &kmi1_device, +}; + +#ifdef CONFIG_LEDS +#define VA_LEDS_BASE (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET) + +static void versatile_leds_event(led_event_t ledevt) +{ + unsigned long flags; + u32 val; + + local_irq_save(flags); + val = readl(VA_LEDS_BASE); + + switch (ledevt) { + case led_idle_start: + val = val & ~VERSATILE_SYS_LED0; + break; + + case led_idle_end: + val = val | VERSATILE_SYS_LED0; + break; + + case led_timer: + val = val ^ VERSATILE_SYS_LED1; + break; + + case led_halted: + val = 0; + break; + + default: + break; + } + + writel(val, VA_LEDS_BASE); + local_irq_restore(flags); +} +#endif /* CONFIG_LEDS */ + +void __init versatile_init(void) +{ + int i; + + clk_register(&versatile_clcd_clk); + + platform_device_register(&versatile_flash_device); + platform_device_register(&smc91x_device); + + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + +#ifdef CONFIG_LEDS + leds_event = versatile_leds_event; +#endif +} + +/* + * Where is the timer (VA)? + */ +#define TIMER0_VA_BASE IO_ADDRESS(VERSATILE_TIMER0_1_BASE) +#define TIMER1_VA_BASE (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20) +#define TIMER2_VA_BASE IO_ADDRESS(VERSATILE_TIMER2_3_BASE) +#define TIMER3_VA_BASE (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20) +#define VA_IC_BASE IO_ADDRESS(VERSATILE_VIC_BASE) + +/* + * How long is the timer interval? + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) +#if TIMER_INTERVAL >= 0x100000 +#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ +#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ +#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) +#elif TIMER_INTERVAL >= 0x10000 +#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ +#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ +#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) +#else +#define TIMER_RELOAD (TIMER_INTERVAL) +#define TIMER_CTRL 0x80 /* Enable */ +#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) +#endif + +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ + +/* + * What does it look like? + */ +typedef struct TimerStruct { + unsigned long TimerLoad; + unsigned long TimerValue; + unsigned long TimerControl; + unsigned long TimerClear; +} TimerStruct_t; + +/* + * Returns number of ms since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +static unsigned long versatile_gettimeoffset(void) +{ + volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE; + unsigned long ticks1, ticks2, status; + + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + ticks2 = timer0->TimerValue & 0xffff; + do { + ticks1 = ticks2; + status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); + ticks2 = timer0->TimerValue & 0xffff; + } while (ticks2 > ticks1); + + /* + * Number of ticks since last interrupt. + */ + ticks1 = TIMER_RELOAD - ticks2; + + /* + * Interrupt pending? If so, we've reloaded once already. + * + * FIXME: Need to check this is effectively timer 0 that expires + */ + if (status & IRQMASK_TIMERINT0_1) + ticks1 += TIMER_RELOAD; + + /* + * Convert the ticks to usecs + */ + return TICKS2USECS(ticks1); +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; + + write_seqlock(&xtime_lock); + + // ...clear the interrupt + timer0->TimerClear = 1; + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction versatile_timer_irq = { + .name = "Versatile Timer Tick", + .flags = SA_INTERRUPT, + .handler = versatile_timer_interrupt +}; + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +static void __init versatile_timer_init(void) +{ + volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; + volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; + volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; + volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE; + + /* + * set clock frequency: + * VERSATILE_REFCLK is 32KHz + * VERSATILE_TIMCLK is 1MHz + */ + *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= + ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); + + /* + * Initialise to a known state (all timers off) + */ + timer0->TimerControl = 0; + timer1->TimerControl = 0; + timer2->TimerControl = 0; + timer3->TimerControl = 0; + + timer0->TimerLoad = TIMER_RELOAD; + timer0->TimerValue = TIMER_RELOAD; + timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ + + /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq); +} + +struct sys_timer versatile_timer = { + .init = versatile_timer_init, + .offset = versatile_gettimeoffset, +}; diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h new file mode 100644 index 0000000..588c206 --- /dev/null +++ b/arch/arm/mach-versatile/core.h @@ -0,0 +1,50 @@ +/* + * linux/arch/arm/mach-versatile/core.h + * + * Copyright (C) 2004 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 + */ + +#ifndef __ASM_ARCH_VERSATILE_H +#define __ASM_ARCH_VERSATILE_H + +#include <asm/hardware/amba.h> + +extern void __init versatile_init(void); +extern void __init versatile_init_irq(void); +extern void __init versatile_map_io(void); +extern struct sys_timer versatile_timer; +extern unsigned int mmc_status(struct device *dev); + +#define AMBA_DEVICE(name,busid,base,plat) \ +static struct amba_device name##_device = { \ + .dev = { \ + .coherent_dma_mask = ~0, \ + .bus_id = busid, \ + .platform_data = plat, \ + }, \ + .res = { \ + .start = VERSATILE_##base##_BASE, \ + .end = (VERSATILE_##base##_BASE) + SZ_4K - 1,\ + .flags = IORESOURCE_MEM, \ + }, \ + .dma_mask = ~0, \ + .irq = base##_IRQ, \ + /* .dma = base##_DMA,*/ \ +} + +#endif diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c new file mode 100644 index 0000000..d332084 --- /dev/null +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mach-versatile/versatile_ab.c + * + * Copyright (C) 2004 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/config.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/hardware/amba.h> + +#include <asm/mach/arch.h> + +#include "core.h" + +MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) + BOOT_PARAMS(0x00000100) + MAPIO(versatile_map_io) + INITIRQ(versatile_init_irq) + .timer = &versatile_timer, + INIT_MACHINE(versatile_init) +MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c new file mode 100644 index 0000000..2702099 --- /dev/null +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -0,0 +1,109 @@ +/* + * linux/arch/arm/mach-versatile/versatile_pb.c + * + * Copyright (C) 2004 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/config.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/hardware/amba.h> + +#include <asm/mach/arch.h> +#include <asm/mach/mmc.h> + +#include "core.h" + +#if 1 +#define IRQ_MMCI1A IRQ_VICSOURCE23 +#else +#define IRQ_MMCI1A IRQ_SIC_MMCI1A +#endif + +static struct mmc_platform_data mmc1_plat_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .status = mmc_status, +}; + +#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } +#define UART3_DMA { 0x86, 0x87 } +#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ } +#define SCI1_DMA { 0x88, 0x89 } +#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B } +#define MMCI1_DMA { 0x85, 0 } + +/* + * These devices are connected via the core APB bridge + */ +#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ } +#define GPIO2_DMA { 0, 0 } +#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ } +#define GPIO3_DMA { 0, 0 } + +/* + * These devices are connected via the DMA APB bridge + */ + +/* FPGA Primecells */ +AMBA_DEVICE(uart3, "fpga:09", UART3, NULL); +AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL); +AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); + +/* DevChip Primecells */ +AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); +AMBA_DEVICE(gpio3, "dev:e7", GPIO3, NULL); + +static struct amba_device *amba_devs[] __initdata = { + &uart3_device, + &gpio2_device, + &gpio3_device, + &sci1_device, + &mmc1_device, +}; + +static int __init versatile_pb_init(void) +{ + int i; + + if (machine_is_versatile_pb()) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + } + + return 0; +} + +arch_initcall(versatile_pb_init); + +MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) + BOOT_PARAMS(0x00000100) + MAPIO(versatile_map_io) + INITIRQ(versatile_init_irq) + .timer = &versatile_timer, + INIT_MACHINE(versatile_init) +MACHINE_END diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig new file mode 100644 index 0000000..5b670c9 --- /dev/null +++ b/arch/arm/mm/Kconfig @@ -0,0 +1,411 @@ +comment "Processor Type" + +config CPU_32 + bool + default y + +# Select CPU types depending on the architecture selected. This selects +# which CPUs we support in the kernel image, and the compiler instruction +# optimiser behaviour. + +# ARM610 +config CPU_ARM610 + bool "Support ARM610 processor" + depends on ARCH_RPC + select CPU_32v3 + select CPU_CACHE_V3 + select CPU_CACHE_VIVT + select CPU_COPY_V3 + select CPU_TLB_V3 + help + The ARM610 is the successor to the ARM3 processor + and was produced by VLSI Technology Inc. + + Say Y if you want support for the ARM610 processor. + Otherwise, say N. + +# ARM710 +config CPU_ARM710 + bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC + default y if ARCH_CLPS7500 + select CPU_32v3 + select CPU_CACHE_V3 + select CPU_CACHE_VIVT + select CPU_COPY_V3 + select CPU_TLB_V3 + help + A 32-bit RISC microprocessor based on the ARM7 processor core + designed by Advanced RISC Machines Ltd. The ARM710 is the + successor to the ARM610 processor. It was released in + July 1994 by VLSI Technology Inc. + + Say Y if you want support for the ARM710 processor. + Otherwise, say N. + +# ARM720T +config CPU_ARM720T + bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR + default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X + select CPU_32v4 + select CPU_ABRT_LV4T + select CPU_CACHE_V4 + select CPU_CACHE_VIVT + select CPU_COPY_V4WT + select CPU_TLB_V4WT + help + A 32-bit RISC processor with 8kByte Cache, Write Buffer and + MMU built around an ARM7TDMI core. + + Say Y if you want support for the ARM720T processor. + Otherwise, say N. + +# ARM920T +config CPU_ARM920T + bool "Support ARM920T processor" if !ARCH_S3C2410 + depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX + default y if ARCH_S3C2410 + select CPU_32v4 + select CPU_ABRT_EV4T + select CPU_CACHE_V4WT + select CPU_CACHE_VIVT + select CPU_COPY_V4WB + select CPU_TLB_V4WBI + help + The ARM920T is licensed to be produced by numerous vendors, + and is used in the Maverick EP9312 and the Samsung S3C2410. + + More information on the Maverick EP9312 at + <http://linuxdevices.com/products/PD2382866068.html>. + + Say Y if you want support for the ARM920T processor. + Otherwise, say N. + +# ARM922T +config CPU_ARM922T + bool "Support ARM922T processor" if ARCH_INTEGRATOR + depends on ARCH_CAMELOT || ARCH_LH7A40X || ARCH_INTEGRATOR + default y if ARCH_CAMELOT || ARCH_LH7A40X + select CPU_32v4 + select CPU_ABRT_EV4T + select CPU_CACHE_V4WT + select CPU_CACHE_VIVT + select CPU_COPY_V4WB + select CPU_TLB_V4WBI + help + The ARM922T is a version of the ARM920T, but with smaller + instruction and data caches. It is used in Altera's + Excalibur XA device family. + + Say Y if you want support for the ARM922T processor. + Otherwise, say N. + +# ARM925T +config CPU_ARM925T + bool "Support ARM925T processor" if ARCH_OMAP + depends on ARCH_OMAP1510 + default y if ARCH_OMAP1510 + select CPU_32v4 + select CPU_ABRT_EV4T + select CPU_CACHE_V4WT + select CPU_CACHE_VIVT + select CPU_COPY_V4WB + select CPU_TLB_V4WBI + help + The ARM925T is a mix between the ARM920T and ARM926T, but with + different instruction and data caches. It is used in TI's OMAP + device family. + + Say Y if you want support for the ARM925T processor. + Otherwise, say N. + +# ARM926T +config CPU_ARM926T + bool "Support ARM926T processor" if ARCH_INTEGRATOR + depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX + default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX + select CPU_32v5 + select CPU_ABRT_EV5TJ + select CPU_CACHE_VIVT + select CPU_COPY_V4WB + select CPU_TLB_V4WBI + help + This is a variant of the ARM920. It has slightly different + instruction sequences for cache and TLB operations. Curiously, + there is no documentation on it at the ARM corporate website. + + Say Y if you want support for the ARM926T processor. + Otherwise, say N. + +# ARM1020 - needs validating +config CPU_ARM1020 + bool "Support ARM1020T (rev 0) processor" + depends on ARCH_INTEGRATOR + select CPU_32v5 + select CPU_ABRT_EV4T + select CPU_CACHE_V4WT + select CPU_CACHE_VIVT + select CPU_COPY_V4WB + select CPU_TLB_V4WBI + help + The ARM1020 is the 32K cached version of the ARM10 processor, + with an addition of a floating-point unit. + + Say Y if you want support for the ARM1020 processor. + Otherwise, say N. + +# ARM1020E - needs validating +config CPU_ARM1020E + bool "Support ARM1020E processor" + depends on ARCH_INTEGRATOR + select CPU_32v5 + select CPU_ABRT_EV4T + select CPU_CACHE_V4WT + select CPU_CACHE_VIVT + select CPU_COPY_V4WB + select CPU_TLB_V4WBI + depends on n + +# ARM1022E +config CPU_ARM1022 + bool "Support ARM1022E processor" + depends on ARCH_INTEGRATOR + select CPU_32v5 + select CPU_ABRT_EV4T + select CPU_CACHE_VIVT + select CPU_COPY_V4WB # can probably do better + select CPU_TLB_V4WBI + help + The ARM1022E is an implementation of the ARMv5TE architecture + based upon the ARM10 integer core with a 16KiB L1 Harvard cache, + embedded trace macrocell, and a floating-point unit. + + Say Y if you want support for the ARM1022E processor. + Otherwise, say N. + +# ARM1026EJ-S +config CPU_ARM1026 + bool "Support ARM1026EJ-S processor" + depends on ARCH_INTEGRATOR + select CPU_32v5 + select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 + select CPU_CACHE_VIVT + select CPU_COPY_V4WB # can probably do better + select CPU_TLB_V4WBI + help + The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture + based upon the ARM10 integer core. + + Say Y if you want support for the ARM1026EJ-S processor. + Otherwise, say N. + +# SA110 +config CPU_SA110 + bool "Support StrongARM(R) SA-110 processor" if !ARCH_EBSA110 && !FOOTBRIDGE && !ARCH_TBOX && !ARCH_SHARK && !ARCH_NEXUSPCI && ARCH_RPC + default y if ARCH_EBSA110 || FOOTBRIDGE || ARCH_TBOX || ARCH_SHARK || ARCH_NEXUSPCI + select CPU_32v3 if ARCH_RPC + select CPU_32v4 if !ARCH_RPC + select CPU_ABRT_EV4 + select CPU_CACHE_V4WB + select CPU_CACHE_VIVT + select CPU_COPY_V4WB + select CPU_TLB_V4WB + help + The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and + is available at five speeds ranging from 100 MHz to 233 MHz. + More information is available at + <http://developer.intel.com/design/strong/sa110.htm>. + + Say Y if you want support for the SA-110 processor. + Otherwise, say N. + +# SA1100 +config CPU_SA1100 + bool + depends on ARCH_SA1100 + default y + select CPU_32v4 + select CPU_ABRT_EV4 + select CPU_CACHE_V4WB + select CPU_CACHE_VIVT + select CPU_TLB_V4WB + select CPU_MINICACHE + +# XScale +config CPU_XSCALE + bool + depends on ARCH_IOP3XX || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 + default y + select CPU_32v5 + select CPU_ABRT_EV5T + select CPU_CACHE_VIVT + select CPU_TLB_V4WBI + select CPU_MINICACHE + +# ARMv6 +config CPU_V6 + bool "Support ARM V6 processor" + depends on ARCH_INTEGRATOR + select CPU_32v6 + select CPU_ABRT_EV6 + select CPU_CACHE_V6 + select CPU_CACHE_VIPT + select CPU_COPY_V6 + select CPU_TLB_V6 + +# Figure out what processor architecture version we should be using. +# This defines the compiler instruction set which depends on the machine type. +config CPU_32v3 + bool + +config CPU_32v4 + bool + +config CPU_32v5 + bool + +config CPU_32v6 + bool + +# The abort model +config CPU_ABRT_EV4 + bool + +config CPU_ABRT_EV4T + bool + +config CPU_ABRT_LV4T + bool + +config CPU_ABRT_EV5T + bool + +config CPU_ABRT_EV5TJ + bool + +config CPU_ABRT_EV6 + bool + +# The cache model +config CPU_CACHE_V3 + bool + +config CPU_CACHE_V4 + bool + +config CPU_CACHE_V4WT + bool + +config CPU_CACHE_V4WB + bool + +config CPU_CACHE_V6 + bool + +config CPU_CACHE_VIVT + bool + +config CPU_CACHE_VIPT + bool + +# The copy-page model +config CPU_COPY_V3 + bool + +config CPU_COPY_V4WT + bool + +config CPU_COPY_V4WB + bool + +config CPU_COPY_V6 + bool + +# This selects the TLB model +config CPU_TLB_V3 + bool + help + ARM Architecture Version 3 TLB. + +config CPU_TLB_V4WT + bool + help + ARM Architecture Version 4 TLB with writethrough cache. + +config CPU_TLB_V4WB + bool + help + ARM Architecture Version 4 TLB with writeback cache. + +config CPU_TLB_V4WBI + bool + help + ARM Architecture Version 4 TLB with writeback cache and invalidate + instruction cache entry. + +config CPU_TLB_V6 + bool + +config CPU_MINICACHE + bool + help + Processor has a minicache. + +comment "Processor Features" + +config ARM_THUMB + bool "Support Thumb user binaries" + depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_V6 + default y + help + Say Y if you want to include kernel support for running user space + Thumb binaries. + + The Thumb instruction set is a compressed form of the standard ARM + instruction set resulting in smaller binaries at the expense of + slightly less efficient code. + + If you don't know what this all is, saying Y is a safe choice. + +config CPU_BIG_ENDIAN + bool "Build big-endian kernel" + depends on ARCH_SUPPORTS_BIG_ENDIAN + help + Say Y if you plan on running a kernel in big-endian mode. + Note that your board must be properly built and your board + port must properly enable any big-endian related features + of your chipset/board/processor. + +config CPU_ICACHE_DISABLE + bool "Disable I-Cache" + depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 + help + Say Y here to disable the processor instruction cache. Unless + you have a reason not to or are unsure, say N. + +config CPU_DCACHE_DISABLE + bool "Disable D-Cache" + depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 + help + Say Y here to disable the processor data cache. Unless + you have a reason not to or are unsure, say N. + +config CPU_DCACHE_WRITETHROUGH + bool "Force write through D-cache" + depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020) && !CPU_DISABLE_DCACHE + default y if CPU_ARM925T + help + Say Y here to use the data cache in writethrough mode. Unless you + specifically require this or are unsure, say N. + +config CPU_CACHE_ROUND_ROBIN + bool "Round robin I and D cache replacement algorithm" + depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) + help + Say Y here to use the predictable round-robin cache replacement + policy. Unless you specifically require this or are unsure, say N. + +config CPU_BPREDICT_DISABLE + bool "Disable branch prediction" + depends on CPU_ARM1020 + help + Say Y here to disable branch prediction. If unsure, say N. diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile new file mode 100644 index 0000000..ccf316c --- /dev/null +++ b/arch/arm/mm/Makefile @@ -0,0 +1,56 @@ +# +# Makefile for the linux arm-specific parts of the memory manager. +# + +obj-y := consistent.o extable.o fault-armv.o \ + fault.o flush.o init.o ioremap.o mmap.o \ + mm-armv.o + +obj-$(CONFIG_MODULES) += proc-syms.o + +obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o +obj-$(CONFIG_DISCONTIGMEM) += discontig.o + +obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o +obj-$(CONFIG_CPU_ABRT_EV4T) += abort-ev4t.o +obj-$(CONFIG_CPU_ABRT_LV4T) += abort-lv4t.o +obj-$(CONFIG_CPU_ABRT_EV5T) += abort-ev5t.o +obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o +obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o + +obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o +obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o +obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o +obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o +obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o + +obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o +obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o +obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o +obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o +obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o +obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o + +obj-$(CONFIG_CPU_MINICACHE) += minicache.o + +obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o +obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o +obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o +obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o +obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o + +obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o +obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o +obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o +obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o +obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o +obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o +obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o +obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o +obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o +obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o +obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o +obj-$(CONFIG_CPU_SA110) += proc-sa110.o +obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o +obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o +obj-$(CONFIG_CPU_V6) += proc-v6.o blockops.o diff --git a/arch/arm/mm/abort-ev4.S b/arch/arm/mm/abort-ev4.S new file mode 100644 index 0000000..4f18f9e --- /dev/null +++ b/arch/arm/mm/abort-ev4.S @@ -0,0 +1,30 @@ +#include <linux/linkage.h> +#include <asm/assembler.h> +/* + * Function: v4_early_abort + * + * Params : r2 = address of aborted instruction + * : r3 = saved SPSR + * + * Returns : r0 = address of abort + * : r1 = FSR, bit 11 = write + * : r2-r8 = corrupted + * : r9 = preserved + * : sp = pointer to registers + * + * Purpose : obtain information about current aborted instruction. + * Note: we read user space. This means we might cause a data + * abort here if the I-TLB and D-TLB aren't seeing the same + * picture. Unfortunately, this does happen. We live with it. + */ + .align 5 +ENTRY(v4_early_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + ldr r3, [r2] @ read aborted ARM instruction + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR + tst r3, #1 << 20 @ L = 1 -> write? + orreq r1, r1, #1 << 11 @ yes. + mov pc, lr + + diff --git a/arch/arm/mm/abort-ev4t.S b/arch/arm/mm/abort-ev4t.S new file mode 100644 index 0000000..b628254 --- /dev/null +++ b/arch/arm/mm/abort-ev4t.S @@ -0,0 +1,30 @@ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include "abort-macro.S" +/* + * Function: v4t_early_abort + * + * Params : r2 = address of aborted instruction + * : r3 = saved SPSR + * + * Returns : r0 = address of abort + * : r1 = FSR, bit 11 = write + * : r2-r8 = corrupted + * : r9 = preserved + * : sp = pointer to registers + * + * Purpose : obtain information about current aborted instruction. + * Note: we read user space. This means we might cause a data + * abort here if the I-TLB and D-TLB aren't seeing the same + * picture. Unfortunately, this does happen. We live with it. + */ + .align 5 +ENTRY(v4t_early_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + do_thumb_abort + ldreq r3, [r2] @ read aborted ARM instruction + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR + tst r3, #1 << 20 @ check write + orreq r1, r1, #1 << 11 + mov pc, lr diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S new file mode 100644 index 0000000..02251b5 --- /dev/null +++ b/arch/arm/mm/abort-ev5t.S @@ -0,0 +1,31 @@ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include "abort-macro.S" +/* + * Function: v5t_early_abort + * + * Params : r2 = address of aborted instruction + * : r3 = saved SPSR + * + * Returns : r0 = address of abort + * : r1 = FSR, bit 11 = write + * : r2-r8 = corrupted + * : r9 = preserved + * : sp = pointer to registers + * + * Purpose : obtain information about current aborted instruction. + * Note: we read user space. This means we might cause a data + * abort here if the I-TLB and D-TLB aren't seeing the same + * picture. Unfortunately, this does happen. We live with it. + */ + .align 5 +ENTRY(v5t_early_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + do_thumb_abort + ldreq r3, [r2] @ read aborted ARM instruction + bic r1, r1, #1 << 11 @ clear bits 11 of FSR + do_ldrd_abort + tst r3, #1 << 20 @ check write + orreq r1, r1, #1 << 11 + mov pc, lr diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S new file mode 100644 index 0000000..bce68d6 --- /dev/null +++ b/arch/arm/mm/abort-ev5tj.S @@ -0,0 +1,35 @@ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include "abort-macro.S" +/* + * Function: v5tj_early_abort + * + * Params : r2 = address of aborted instruction + * : r3 = saved SPSR + * + * Returns : r0 = address of abort + * : r1 = FSR, bit 11 = write + * : r2-r8 = corrupted + * : r9 = preserved + * : sp = pointer to registers + * + * Purpose : obtain information about current aborted instruction. + * Note: we read user space. This means we might cause a data + * abort here if the I-TLB and D-TLB aren't seeing the same + * picture. Unfortunately, this does happen. We live with it. + */ + .align 5 +ENTRY(v5tj_early_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR + tst r3, #PSR_J_BIT @ Java? + movne pc, lr + do_thumb_abort + ldreq r3, [r2] @ read aborted ARM instruction + do_ldrd_abort + tst r3, #1 << 20 @ L = 0 -> write + orreq r1, r1, #1 << 11 @ yes. + mov pc, lr + + diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S new file mode 100644 index 0000000..38b2cbb --- /dev/null +++ b/arch/arm/mm/abort-ev6.S @@ -0,0 +1,23 @@ +#include <linux/linkage.h> +#include <asm/assembler.h> +/* + * Function: v6_early_abort + * + * Params : r2 = address of aborted instruction + * : r3 = saved SPSR + * + * Returns : r0 = address of abort + * : r1 = FSR, bit 11 = write + * : r2-r8 = corrupted + * : r9 = preserved + * : sp = pointer to registers + * + * Purpose : obtain information about current aborted instruction. + */ + .align 5 +ENTRY(v6_early_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + mov pc, lr + + diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S new file mode 100644 index 0000000..db743e5 --- /dev/null +++ b/arch/arm/mm/abort-lv4t.S @@ -0,0 +1,220 @@ +#include <linux/linkage.h> +#include <asm/assembler.h> +/* + * Function: v4t_late_abort + * + * Params : r2 = address of aborted instruction + * : r3 = saved SPSR + * + * Returns : r0 = address of abort + * : r1 = FSR, bit 11 = write + * : r2-r8 = corrupted + * : r9 = preserved + * : sp = pointer to registers + * + * Purpose : obtain information about current aborted instruction. + * Note: we read user space. This means we might cause a data + * abort here if the I-TLB and D-TLB aren't seeing the same + * picture. Unfortunately, this does happen. We live with it. + */ +ENTRY(v4t_late_abort) + tst r3, #PSR_T_BIT @ check for thumb mode + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + bne .data_thumb_abort + ldr r8, [r2] @ read arm instruction + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR + tst r8, #1 << 20 @ L = 1 -> write? + orreq r1, r1, #1 << 11 @ yes. + and r7, r8, #15 << 24 + add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine + nop + +/* 0 */ b .data_arm_lateldrhpost @ ldrh rd, [rn], #m/rm +/* 1 */ b .data_arm_lateldrhpre @ ldrh rd, [rn, #m/rm] +/* 2 */ b .data_unknown +/* 3 */ b .data_unknown +/* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m +/* 5 */ b .data_arm_lateldrpreconst @ ldr rd, [rn, #m] +/* 6 */ b .data_arm_lateldrpostreg @ ldr rd, [rn], rm +/* 7 */ b .data_arm_lateldrprereg @ ldr rd, [rn, rm] +/* 8 */ b .data_arm_ldmstm @ ldm*a rn, <rlist> +/* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> +/* a */ b .data_unknown +/* b */ b .data_unknown +/* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m +/* d */ mov pc, lr @ ldc rd, [rn, #m] +/* e */ b .data_unknown +/* f */ +.data_unknown: @ Part of jumptable + mov r0, r2 + mov r1, r8 + mov r2, sp + bl baddataabort + b ret_from_exception + +.data_arm_ldmstm: + tst r8, #1 << 21 @ check writeback bit + moveq pc, lr @ no writeback -> no fixup + mov r7, #0x11 + orr r7, r7, #0x1100 + and r6, r8, r7 + and r2, r8, r7, lsl #1 + add r6, r6, r2, lsr #1 + and r2, r8, r7, lsl #2 + add r6, r6, r2, lsr #2 + and r2, r8, r7, lsl #3 + add r6, r6, r2, lsr #3 + add r6, r6, r6, lsr #8 + add r6, r6, r6, lsr #4 + and r6, r6, #15 @ r6 = no. of registers to transfer. + and r5, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r6, lsl #2 @ Undo increment + addeq r7, r7, r6, lsl #2 @ Undo decrement + str r7, [sp, r5, lsr #14] @ Put register 'Rn' + mov pc, lr + +.data_arm_lateldrhpre: + tst r8, #1 << 21 @ Check writeback bit + moveq pc, lr @ No writeback -> no fixup +.data_arm_lateldrhpost: + and r5, r8, #0x00f @ get Rm / low nibble of immediate value + tst r8, #1 << 22 @ if (immediate offset) + andne r6, r8, #0xf00 @ { immediate high nibble + orrne r6, r5, r6, lsr #4 @ combine nibbles } else + ldreq r6, [sp, r5, lsl #2] @ { load Rm value } +.data_arm_apply_r6_and_rn: + and r5, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r6 @ Undo incrmenet + addeq r7, r7, r6 @ Undo decrement + str r7, [sp, r5, lsr #14] @ Put register 'Rn' + mov pc, lr + +.data_arm_lateldrpreconst: + tst r8, #1 << 21 @ check writeback bit + moveq pc, lr @ no writeback -> no fixup +.data_arm_lateldrpostconst: + movs r2, r8, lsl #20 @ Get offset + moveq pc, lr @ zero -> no fixup + and r5, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r2, lsr #20 @ Undo increment + addeq r7, r7, r2, lsr #20 @ Undo decrement + str r7, [sp, r5, lsr #14] @ Put register 'Rn' + mov pc, lr + +.data_arm_lateldrprereg: + tst r8, #1 << 21 @ check writeback bit + moveq pc, lr @ no writeback -> no fixup +.data_arm_lateldrpostreg: + and r7, r8, #15 @ Extract 'm' from instruction + ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' + mov r5, r8, lsr #7 @ get shift count + ands r5, r5, #31 + and r7, r8, #0x70 @ get shift type + orreq r7, r7, #8 @ shift count = 0 + add pc, pc, r7 + nop + + mov r6, r6, lsl r5 @ 0: LSL #!0 + b .data_arm_apply_r6_and_rn + b .data_arm_apply_r6_and_rn @ 1: LSL #0 + nop + b .data_unknown @ 2: MUL? + nop + b .data_unknown @ 3: MUL? + nop + mov r6, r6, lsr r5 @ 4: LSR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, lsr #32 @ 5: LSR #32 + b .data_arm_apply_r6_and_rn + b .data_unknown @ 6: MUL? + nop + b .data_unknown @ 7: MUL? + nop + mov r6, r6, asr r5 @ 8: ASR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, asr #32 @ 9: ASR #32 + b .data_arm_apply_r6_and_rn + b .data_unknown @ A: MUL? + nop + b .data_unknown @ B: MUL? + nop + mov r6, r6, ror r5 @ C: ROR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, rrx @ D: RRX + b .data_arm_apply_r6_and_rn + b .data_unknown @ E: MUL? + nop + b .data_unknown @ F: MUL? + +.data_thumb_abort: + ldrh r8, [r2] @ read instruction + tst r8, #1 << 11 @ L = 1 -> write? + orreq r1, r1, #1 << 8 @ yes + and r7, r8, #15 << 12 + add pc, pc, r7, lsr #10 @ lookup in table + nop + +/* 0 */ b .data_unknown +/* 1 */ b .data_unknown +/* 2 */ b .data_unknown +/* 3 */ b .data_unknown +/* 4 */ b .data_unknown +/* 5 */ b .data_thumb_reg +/* 6 */ mov pc, lr +/* 7 */ mov pc, lr +/* 8 */ mov pc, lr +/* 9 */ mov pc, lr +/* A */ b .data_unknown +/* B */ b .data_thumb_pushpop +/* C */ b .data_thumb_ldmstm +/* D */ b .data_unknown +/* E */ b .data_unknown +/* F */ b .data_unknown + +.data_thumb_reg: + tst r8, #1 << 9 + moveq pc, lr + tst r8, #1 << 10 @ If 'S' (signed) bit is set + movne r1, #0 @ it must be a load instr + mov pc, lr + +.data_thumb_pushpop: + tst r8, #1 << 10 + beq .data_unknown + and r6, r8, #0x55 @ hweight8(r8) + R bit + and r2, r8, #0xaa + add r6, r6, r2, lsr #1 + and r2, r6, #0xcc + and r6, r6, #0x33 + add r6, r6, r2, lsr #2 + movs r7, r8, lsr #9 @ C = r8 bit 8 (R bit) + adc r6, r6, r6, lsr #4 @ high + low nibble + R bit + and r6, r6, #15 @ number of regs to transfer + ldr r7, [sp, #13 << 2] + tst r8, #1 << 11 + addeq r7, r7, r6, lsl #2 @ increment SP if PUSH + subne r7, r7, r6, lsl #2 @ decrement SP if POP + str r7, [sp, #13 << 2] + mov pc, lr + +.data_thumb_ldmstm: + and r6, r8, #0x55 @ hweight8(r8) + and r2, r8, #0xaa + add r6, r6, r2, lsr #1 + and r2, r6, #0xcc + and r6, r6, #0x33 + add r6, r6, r2, lsr #2 + add r6, r6, r6, lsr #4 + and r5, r8, #7 << 8 + ldr r7, [sp, r5, lsr #6] + and r6, r6, #15 @ number of regs to transfer + sub r7, r7, r6, lsl #2 @ always decrement + str r7, [sp, r5, lsr #6] + mov pc, lr diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S new file mode 100644 index 0000000..d7cb1bf --- /dev/null +++ b/arch/arm/mm/abort-macro.S @@ -0,0 +1,42 @@ +/* + * The ARM LDRD and Thumb LDRSB instructions use bit 20/11 (ARM/Thumb) + * differently than every other instruction, so it is set to 0 (write) + * even though the instructions are read instructions. This means that + * during an abort the instructions will be treated as a write and the + * handler will raise a signal from unwriteable locations if they + * fault. We have to specifically check for these instructions + * from the abort handlers to treat them properly. + * + */ + + .macro do_thumb_abort + tst r3, #PSR_T_BIT + beq not_thumb + ldrh r3, [r2] @ Read aborted Thumb instruction + and r3, r3, # 0xfe00 @ Mask opcode field + cmp r3, # 0x5600 @ Is it ldrsb? + orreq r3, r3, #1 << 11 @ Set L-bit if yes + tst r3, #1 << 11 @ L = 0 -> write + orreq r1, r1, #1 << 11 @ yes. + mov pc, lr +not_thumb: + .endm + +/* + * We check for the following insturction encoding for LDRD. + * + * [27:25] == 0 + * [7:4] == 1101 + * [20] == 0 + */ + .macro do_ldrd_abort + tst r3, #0x0e000000 @ [27:25] == 0 + bne not_ldrd + and r2, r3, #0x000000f0 @ [7:4] == 1101 + cmp r2, #0x000000d0 + bne not_ldrd + tst r3, #1 << 20 @ [20] == 0 + moveq pc, lr +not_ldrd: + .endm + diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c new file mode 100644 index 0000000..81f4a8a --- /dev/null +++ b/arch/arm/mm/alignment.c @@ -0,0 +1,756 @@ +/* + * linux/arch/arm/mm/alignment.c + * + * Copyright (C) 1995 Linus Torvalds + * Modifications for ARM processor (c) 1995-2001 Russell King + * Thumb aligment fault fixups (c) 2004 MontaVista Software, Inc. + * - Adapted from gdb/sim/arm/thumbemu.c -- Thumb instruction emulation. + * Copyright (C) 1996, Cygnus Software Technologies Ltd. + * + * 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/compiler.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/ptrace.h> +#include <linux/proc_fs.h> +#include <linux/init.h> + +#include <asm/uaccess.h> +#include <asm/unaligned.h> + +#include "fault.h" + +/* + * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998 + * /proc/sys/debug/alignment, modified and integrated into + * Linux 2.1 by Russell King + * + * Speed optimisations and better fault handling by Russell King. + * + * *** NOTE *** + * This code is not portable to processors with late data abort handling. + */ +#define CODING_BITS(i) (i & 0x0e000000) + +#define LDST_I_BIT(i) (i & (1 << 26)) /* Immediate constant */ +#define LDST_P_BIT(i) (i & (1 << 24)) /* Preindex */ +#define LDST_U_BIT(i) (i & (1 << 23)) /* Add offset */ +#define LDST_W_BIT(i) (i & (1 << 21)) /* Writeback */ +#define LDST_L_BIT(i) (i & (1 << 20)) /* Load */ + +#define LDST_P_EQ_U(i) ((((i) ^ ((i) >> 1)) & (1 << 23)) == 0) + +#define LDSTH_I_BIT(i) (i & (1 << 22)) /* half-word immed */ +#define LDM_S_BIT(i) (i & (1 << 22)) /* write CPSR from SPSR */ + +#define RN_BITS(i) ((i >> 16) & 15) /* Rn */ +#define RD_BITS(i) ((i >> 12) & 15) /* Rd */ +#define RM_BITS(i) (i & 15) /* Rm */ + +#define REGMASK_BITS(i) (i & 0xffff) +#define OFFSET_BITS(i) (i & 0x0fff) + +#define IS_SHIFT(i) (i & 0x0ff0) +#define SHIFT_BITS(i) ((i >> 7) & 0x1f) +#define SHIFT_TYPE(i) (i & 0x60) +#define SHIFT_LSL 0x00 +#define SHIFT_LSR 0x20 +#define SHIFT_ASR 0x40 +#define SHIFT_RORRRX 0x60 + +static unsigned long ai_user; +static unsigned long ai_sys; +static unsigned long ai_skipped; +static unsigned long ai_half; +static unsigned long ai_word; +static unsigned long ai_multi; +static int ai_usermode; + +#ifdef CONFIG_PROC_FS +static const char *usermode_action[] = { + "ignored", + "warn", + "fixup", + "fixup+warn", + "signal", + "signal+warn" +}; + +static int +proc_alignment_read(char *page, char **start, off_t off, int count, int *eof, + void *data) +{ + char *p = page; + int len; + + p += sprintf(p, "User:\t\t%lu\n", ai_user); + p += sprintf(p, "System:\t\t%lu\n", ai_sys); + p += sprintf(p, "Skipped:\t%lu\n", ai_skipped); + p += sprintf(p, "Half:\t\t%lu\n", ai_half); + p += sprintf(p, "Word:\t\t%lu\n", ai_word); + p += sprintf(p, "Multi:\t\t%lu\n", ai_multi); + p += sprintf(p, "User faults:\t%i (%s)\n", ai_usermode, + usermode_action[ai_usermode]); + + len = (p - page) - off; + if (len < 0) + len = 0; + + *eof = (len <= count) ? 1 : 0; + *start = page + off; + + return len; +} + +static int proc_alignment_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + char mode; + + if (count > 0) { + if (get_user(mode, buffer)) + return -EFAULT; + if (mode >= '0' && mode <= '5') + ai_usermode = mode - '0'; + } + return count; +} + +#endif /* CONFIG_PROC_FS */ + +union offset_union { + unsigned long un; + signed long sn; +}; + +#define TYPE_ERROR 0 +#define TYPE_FAULT 1 +#define TYPE_LDST 2 +#define TYPE_DONE 3 + +#ifdef __ARMEB__ +#define BE 1 +#define FIRST_BYTE_16 "mov %1, %1, ror #8\n" +#define FIRST_BYTE_32 "mov %1, %1, ror #24\n" +#define NEXT_BYTE "ror #24" +#else +#define BE 0 +#define FIRST_BYTE_16 +#define FIRST_BYTE_32 +#define NEXT_BYTE "lsr #8" +#endif + +#define __get8_unaligned_check(ins,val,addr,err) \ + __asm__( \ + "1: "ins" %1, [%2], #1\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, #1\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous\n" \ + : "=r" (err), "=&r" (val), "=r" (addr) \ + : "0" (err), "2" (addr)) + +#define __get16_unaligned_check(ins,val,addr) \ + do { \ + unsigned int err = 0, v, a = addr; \ + __get8_unaligned_check(ins,v,a,err); \ + val = v << ((BE) ? 8 : 0); \ + __get8_unaligned_check(ins,v,a,err); \ + val |= v << ((BE) ? 0 : 8); \ + if (err) \ + goto fault; \ + } while (0) + +#define get16_unaligned_check(val,addr) \ + __get16_unaligned_check("ldrb",val,addr) + +#define get16t_unaligned_check(val,addr) \ + __get16_unaligned_check("ldrbt",val,addr) + +#define __get32_unaligned_check(ins,val,addr) \ + do { \ + unsigned int err = 0, v, a = addr; \ + __get8_unaligned_check(ins,v,a,err); \ + val = v << ((BE) ? 24 : 0); \ + __get8_unaligned_check(ins,v,a,err); \ + val |= v << ((BE) ? 16 : 8); \ + __get8_unaligned_check(ins,v,a,err); \ + val |= v << ((BE) ? 8 : 16); \ + __get8_unaligned_check(ins,v,a,err); \ + val |= v << ((BE) ? 0 : 24); \ + if (err) \ + goto fault; \ + } while (0) + +#define get32_unaligned_check(val,addr) \ + __get32_unaligned_check("ldrb",val,addr) + +#define get32t_unaligned_check(val,addr) \ + __get32_unaligned_check("ldrbt",val,addr) + +#define __put16_unaligned_check(ins,val,addr) \ + do { \ + unsigned int err = 0, v = val, a = addr; \ + __asm__( FIRST_BYTE_16 \ + "1: "ins" %1, [%2], #1\n" \ + " mov %1, %1, "NEXT_BYTE"\n" \ + "2: "ins" %1, [%2]\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "4: mov %0, #1\n" \ + " b 3b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 4b\n" \ + " .long 2b, 4b\n" \ + " .previous\n" \ + : "=r" (err), "=&r" (v), "=&r" (a) \ + : "0" (err), "1" (v), "2" (a)); \ + if (err) \ + goto fault; \ + } while (0) + +#define put16_unaligned_check(val,addr) \ + __put16_unaligned_check("strb",val,addr) + +#define put16t_unaligned_check(val,addr) \ + __put16_unaligned_check("strbt",val,addr) + +#define __put32_unaligned_check(ins,val,addr) \ + do { \ + unsigned int err = 0, v = val, a = addr; \ + __asm__( FIRST_BYTE_32 \ + "1: "ins" %1, [%2], #1\n" \ + " mov %1, %1, "NEXT_BYTE"\n" \ + "2: "ins" %1, [%2], #1\n" \ + " mov %1, %1, "NEXT_BYTE"\n" \ + "3: "ins" %1, [%2], #1\n" \ + " mov %1, %1, "NEXT_BYTE"\n" \ + "4: "ins" %1, [%2]\n" \ + "5:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "6: mov %0, #1\n" \ + " b 5b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 6b\n" \ + " .long 2b, 6b\n" \ + " .long 3b, 6b\n" \ + " .long 4b, 6b\n" \ + " .previous\n" \ + : "=r" (err), "=&r" (v), "=&r" (a) \ + : "0" (err), "1" (v), "2" (a)); \ + if (err) \ + goto fault; \ + } while (0) + +#define put32_unaligned_check(val,addr) \ + __put32_unaligned_check("strb", val, addr) + +#define put32t_unaligned_check(val,addr) \ + __put32_unaligned_check("strbt", val, addr) + +static void +do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs *regs, union offset_union offset) +{ + if (!LDST_U_BIT(instr)) + offset.un = -offset.un; + + if (!LDST_P_BIT(instr)) + addr += offset.un; + + if (!LDST_P_BIT(instr) || LDST_W_BIT(instr)) + regs->uregs[RN_BITS(instr)] = addr; +} + +static int +do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs) +{ + unsigned int rd = RD_BITS(instr); + + if ((instr & 0x01f00ff0) == 0x01000090) + goto swp; + + if ((instr & 0x90) != 0x90 || (instr & 0x60) == 0) + goto bad; + + ai_half += 1; + + if (user_mode(regs)) + goto user; + + if (LDST_L_BIT(instr)) { + unsigned long val; + get16_unaligned_check(val, addr); + + /* signed half-word? */ + if (instr & 0x40) + val = (signed long)((signed short) val); + + regs->uregs[rd] = val; + } else + put16_unaligned_check(regs->uregs[rd], addr); + + return TYPE_LDST; + + user: + if (LDST_L_BIT(instr)) { + unsigned long val; + get16t_unaligned_check(val, addr); + + /* signed half-word? */ + if (instr & 0x40) + val = (signed long)((signed short) val); + + regs->uregs[rd] = val; + } else + put16t_unaligned_check(regs->uregs[rd], addr); + + return TYPE_LDST; + + swp: + printk(KERN_ERR "Alignment trap: not handling swp instruction\n"); + bad: + return TYPE_ERROR; + + fault: + return TYPE_FAULT; +} + +static int +do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *regs) +{ + unsigned int rd = RD_BITS(instr); + + ai_word += 1; + + if ((!LDST_P_BIT(instr) && LDST_W_BIT(instr)) || user_mode(regs)) + goto trans; + + if (LDST_L_BIT(instr)) { + unsigned int val; + get32_unaligned_check(val, addr); + regs->uregs[rd] = val; + } else + put32_unaligned_check(regs->uregs[rd], addr); + return TYPE_LDST; + + trans: + if (LDST_L_BIT(instr)) { + unsigned int val; + get32t_unaligned_check(val, addr); + regs->uregs[rd] = val; + } else + put32t_unaligned_check(regs->uregs[rd], addr); + return TYPE_LDST; + + fault: + return TYPE_FAULT; +} + +/* + * LDM/STM alignment handler. + * + * There are 4 variants of this instruction: + * + * B = rn pointer before instruction, A = rn pointer after instruction + * ------ increasing address -----> + * | | r0 | r1 | ... | rx | | + * PU = 01 B A + * PU = 11 B A + * PU = 00 A B + * PU = 10 A B + */ +static int +do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs) +{ + unsigned int rd, rn, correction, nr_regs, regbits; + unsigned long eaddr, newaddr; + + if (LDM_S_BIT(instr)) + goto bad; + + correction = 4; /* processor implementation defined */ + regs->ARM_pc += correction; + + ai_multi += 1; + + /* count the number of registers in the mask to be transferred */ + nr_regs = hweight16(REGMASK_BITS(instr)) * 4; + + rn = RN_BITS(instr); + newaddr = eaddr = regs->uregs[rn]; + + if (!LDST_U_BIT(instr)) + nr_regs = -nr_regs; + newaddr += nr_regs; + if (!LDST_U_BIT(instr)) + eaddr = newaddr; + + if (LDST_P_EQ_U(instr)) /* U = P */ + eaddr += 4; + + /* + * For alignment faults on the ARM922T/ARM920T the MMU makes + * the FSR (and hence addr) equal to the updated base address + * of the multiple access rather than the restored value. + * Switch this message off if we've got a ARM92[02], otherwise + * [ls]dm alignment faults are noisy! + */ +#if !(defined CONFIG_CPU_ARM922T) && !(defined CONFIG_CPU_ARM920T) + /* + * This is a "hint" - we already have eaddr worked out by the + * processor for us. + */ + if (addr != eaddr) { + printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, " + "addr = %08lx, eaddr = %08lx\n", + instruction_pointer(regs), instr, addr, eaddr); + show_regs(regs); + } +#endif + + if (user_mode(regs)) { + for (regbits = REGMASK_BITS(instr), rd = 0; regbits; + regbits >>= 1, rd += 1) + if (regbits & 1) { + if (LDST_L_BIT(instr)) { + unsigned int val; + get32t_unaligned_check(val, eaddr); + regs->uregs[rd] = val; + } else + put32t_unaligned_check(regs->uregs[rd], eaddr); + eaddr += 4; + } + } else { + for (regbits = REGMASK_BITS(instr), rd = 0; regbits; + regbits >>= 1, rd += 1) + if (regbits & 1) { + if (LDST_L_BIT(instr)) { + unsigned int val; + get32_unaligned_check(val, eaddr); + regs->uregs[rd] = val; + } else + put32_unaligned_check(regs->uregs[rd], eaddr); + eaddr += 4; + } + } + + if (LDST_W_BIT(instr)) + regs->uregs[rn] = newaddr; + if (!LDST_L_BIT(instr) || !(REGMASK_BITS(instr) & (1 << 15))) + regs->ARM_pc -= correction; + return TYPE_DONE; + +fault: + regs->ARM_pc -= correction; + return TYPE_FAULT; + +bad: + printk(KERN_ERR "Alignment trap: not handling ldm with s-bit set\n"); + return TYPE_ERROR; +} + +/* + * Convert Thumb ld/st instruction forms to equivalent ARM instructions so + * we can reuse ARM userland alignment fault fixups for Thumb. + * + * This implementation was initially based on the algorithm found in + * gdb/sim/arm/thumbemu.c. It is basically just a code reduction of same + * to convert only Thumb ld/st instruction forms to equivalent ARM forms. + * + * NOTES: + * 1. Comments below refer to ARM ARM DDI0100E Thumb Instruction sections. + * 2. If for some reason we're passed an non-ld/st Thumb instruction to + * decode, we return 0xdeadc0de. This should never happen under normal + * circumstances but if it does, we've got other problems to deal with + * elsewhere and we obviously can't fix those problems here. + */ + +static unsigned long +thumb2arm(u16 tinstr) +{ + u32 L = (tinstr & (1<<11)) >> 11; + + switch ((tinstr & 0xf800) >> 11) { + /* 6.5.1 Format 1: */ + case 0x6000 >> 11: /* 7.1.52 STR(1) */ + case 0x6800 >> 11: /* 7.1.26 LDR(1) */ + case 0x7000 >> 11: /* 7.1.55 STRB(1) */ + case 0x7800 >> 11: /* 7.1.30 LDRB(1) */ + return 0xe5800000 | + ((tinstr & (1<<12)) << (22-12)) | /* fixup */ + (L<<20) | /* L==1? */ + ((tinstr & (7<<0)) << (12-0)) | /* Rd */ + ((tinstr & (7<<3)) << (16-3)) | /* Rn */ + ((tinstr & (31<<6)) >> /* immed_5 */ + (6 - ((tinstr & (1<<12)) ? 0 : 2))); + case 0x8000 >> 11: /* 7.1.57 STRH(1) */ + case 0x8800 >> 11: /* 7.1.32 LDRH(1) */ + return 0xe1c000b0 | + (L<<20) | /* L==1? */ + ((tinstr & (7<<0)) << (12-0)) | /* Rd */ + ((tinstr & (7<<3)) << (16-3)) | /* Rn */ + ((tinstr & (7<<6)) >> (6-1)) | /* immed_5[2:0] */ + ((tinstr & (3<<9)) >> (9-8)); /* immed_5[4:3] */ + + /* 6.5.1 Format 2: */ + case 0x5000 >> 11: + case 0x5800 >> 11: + { + static const u32 subset[8] = { + 0xe7800000, /* 7.1.53 STR(2) */ + 0xe18000b0, /* 7.1.58 STRH(2) */ + 0xe7c00000, /* 7.1.56 STRB(2) */ + 0xe19000d0, /* 7.1.34 LDRSB */ + 0xe7900000, /* 7.1.27 LDR(2) */ + 0xe19000b0, /* 7.1.33 LDRH(2) */ + 0xe7d00000, /* 7.1.31 LDRB(2) */ + 0xe19000f0 /* 7.1.35 LDRSH */ + }; + return subset[(tinstr & (7<<9)) >> 9] | + ((tinstr & (7<<0)) << (12-0)) | /* Rd */ + ((tinstr & (7<<3)) << (16-3)) | /* Rn */ + ((tinstr & (7<<6)) >> (6-0)); /* Rm */ + } + + /* 6.5.1 Format 3: */ + case 0x4800 >> 11: /* 7.1.28 LDR(3) */ + /* NOTE: This case is not technically possible. We're + * loading 32-bit memory data via PC relative + * addressing mode. So we can and should eliminate + * this case. But I'll leave it here for now. + */ + return 0xe59f0000 | + ((tinstr & (7<<8)) << (12-8)) | /* Rd */ + ((tinstr & 255) << (2-0)); /* immed_8 */ + + /* 6.5.1 Format 4: */ + case 0x9000 >> 11: /* 7.1.54 STR(3) */ + case 0x9800 >> 11: /* 7.1.29 LDR(4) */ + return 0xe58d0000 | + (L<<20) | /* L==1? */ + ((tinstr & (7<<8)) << (12-8)) | /* Rd */ + ((tinstr & 255) << 2); /* immed_8 */ + + /* 6.6.1 Format 1: */ + case 0xc000 >> 11: /* 7.1.51 STMIA */ + case 0xc800 >> 11: /* 7.1.25 LDMIA */ + { + u32 Rn = (tinstr & (7<<8)) >> 8; + u32 W = ((L<<Rn) & (tinstr&255)) ? 0 : 1<<21; + + return 0xe8800000 | W | (L<<20) | (Rn<<16) | + (tinstr&255); + } + + /* 6.6.1 Format 2: */ + case 0xb000 >> 11: /* 7.1.48 PUSH */ + case 0xb800 >> 11: /* 7.1.47 POP */ + if ((tinstr & (3 << 9)) == 0x0400) { + static const u32 subset[4] = { + 0xe92d0000, /* STMDB sp!,{registers} */ + 0xe92d4000, /* STMDB sp!,{registers,lr} */ + 0xe8bd0000, /* LDMIA sp!,{registers} */ + 0xe8bd8000 /* LDMIA sp!,{registers,pc} */ + }; + return subset[(L<<1) | ((tinstr & (1<<8)) >> 8)] | + (tinstr & 255); /* register_list */ + } + /* Else fall through for illegal instruction case */ + + default: + return 0xdeadc0de; + } +} + +static int +do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + union offset_union offset; + unsigned long instr = 0, instrptr; + int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); + unsigned int type; + mm_segment_t fs; + unsigned int fault; + u16 tinstr = 0; + + instrptr = instruction_pointer(regs); + + fs = get_fs(); + set_fs(KERNEL_DS); + if thumb_mode(regs) { + fault = __get_user(tinstr, (u16 *)(instrptr & ~1)); + if (!(fault)) + instr = thumb2arm(tinstr); + } else + fault = __get_user(instr, (u32 *)instrptr); + set_fs(fs); + + if (fault) { + type = TYPE_FAULT; + goto bad_or_fault; + } + + if (user_mode(regs)) + goto user; + + ai_sys += 1; + + fixup: + + regs->ARM_pc += thumb_mode(regs) ? 2 : 4; + + switch (CODING_BITS(instr)) { + case 0x00000000: /* ldrh or strh */ + if (LDSTH_I_BIT(instr)) + offset.un = (instr & 0xf00) >> 4 | (instr & 15); + else + offset.un = regs->uregs[RM_BITS(instr)]; + handler = do_alignment_ldrhstrh; + break; + + case 0x04000000: /* ldr or str immediate */ + offset.un = OFFSET_BITS(instr); + handler = do_alignment_ldrstr; + break; + + case 0x06000000: /* ldr or str register */ + offset.un = regs->uregs[RM_BITS(instr)]; + + if (IS_SHIFT(instr)) { + unsigned int shiftval = SHIFT_BITS(instr); + + switch(SHIFT_TYPE(instr)) { + case SHIFT_LSL: + offset.un <<= shiftval; + break; + + case SHIFT_LSR: + offset.un >>= shiftval; + break; + + case SHIFT_ASR: + offset.sn >>= shiftval; + break; + + case SHIFT_RORRRX: + if (shiftval == 0) { + offset.un >>= 1; + if (regs->ARM_cpsr & PSR_C_BIT) + offset.un |= 1 << 31; + } else + offset.un = offset.un >> shiftval | + offset.un << (32 - shiftval); + break; + } + } + handler = do_alignment_ldrstr; + break; + + case 0x08000000: /* ldm or stm */ + handler = do_alignment_ldmstm; + break; + + default: + goto bad; + } + + type = handler(addr, instr, regs); + + if (type == TYPE_ERROR || type == TYPE_FAULT) + goto bad_or_fault; + + if (type == TYPE_LDST) + do_alignment_finish_ldst(addr, instr, regs, offset); + + return 0; + + bad_or_fault: + if (type == TYPE_ERROR) + goto bad; + regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; + /* + * We got a fault - fix it up, or die. + */ + do_bad_area(current, current->mm, addr, fsr, regs); + return 0; + + bad: + /* + * Oops, we didn't handle the instruction. + */ + printk(KERN_ERR "Alignment trap: not handling instruction " + "%0*lx at [<%08lx>]\n", + thumb_mode(regs) ? 4 : 8, + thumb_mode(regs) ? tinstr : instr, instrptr); + ai_skipped += 1; + return 1; + + user: + ai_user += 1; + + if (ai_usermode & 1) + printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx " + "Address=0x%08lx FSR 0x%03x\n", current->comm, + current->pid, instrptr, + thumb_mode(regs) ? 4 : 8, + thumb_mode(regs) ? tinstr : instr, + addr, fsr); + + if (ai_usermode & 2) + goto fixup; + + if (ai_usermode & 4) + force_sig(SIGBUS, current); + else + set_cr(cr_no_alignment); + + return 0; +} + +/* + * This needs to be done after sysctl_init, otherwise sys/ will be + * overwritten. Actually, this shouldn't be in sys/ at all since + * it isn't a sysctl, and it doesn't contain sysctl information. + * We now locate it in /proc/cpu/alignment instead. + */ +static int __init alignment_init(void) +{ +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *res; + + res = proc_mkdir("cpu", NULL); + if (!res) + return -ENOMEM; + + res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res); + if (!res) + return -ENOMEM; + + res->read_proc = proc_alignment_read; + res->write_proc = proc_alignment_write; +#endif + + hook_fault_code(1, do_alignment, SIGILL, "alignment exception"); + hook_fault_code(3, do_alignment, SIGILL, "alignment exception"); + + return 0; +} + +fs_initcall(alignment_init); diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c new file mode 100644 index 0000000..806c6ee --- /dev/null +++ b/arch/arm/mm/blockops.c @@ -0,0 +1,184 @@ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/mm.h> + +#include <asm/memory.h> +#include <asm/ptrace.h> +#include <asm/cacheflush.h> +#include <asm/traps.h> + +extern struct cpu_cache_fns blk_cache_fns; + +#define HARVARD_CACHE + +/* + * blk_flush_kern_dcache_page(kaddr) + * + * Ensure that the data held in the page kaddr is written back + * to the page in question. + * + * - kaddr - kernel address (guaranteed to be page aligned) + */ +static void __attribute__((naked)) +blk_flush_kern_dcache_page(void *kaddr) +{ + asm( + "add r1, r0, %0 \n\ +1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\ + mov r0, #0 \n\ + mcr p15, 0, r0, c7, c5, 0 \n\ + mcr p15, 0, r0, c7, c10, 4 \n\ + mov pc, lr" + : + : "I" (PAGE_SIZE)); +} + +/* + * blk_dma_inv_range(start,end) + * + * Invalidate the data cache within the specified region; we will + * be performing a DMA operation in this region and we want to + * purge old data in the cache. + * + * - start - virtual start address of region + * - end - virtual end address of region + */ +static void __attribute__((naked)) +blk_dma_inv_range_unified(unsigned long start, unsigned long end) +{ + asm( + "tst r0, %0 \n\ + mcrne p15, 0, r0, c7, c11, 1 @ clean unified line \n\ + tst r1, %0 \n\ + mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line\n\ + .word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\ + mov r0, #0 \n\ + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\ + mov pc, lr" + : + : "I" (L1_CACHE_BYTES - 1)); +} + +static void __attribute__((naked)) +blk_dma_inv_range_harvard(unsigned long start, unsigned long end) +{ + asm( + "tst r0, %0 \n\ + mcrne p15, 0, r0, c7, c10, 1 @ clean D line \n\ + tst r1, %0 \n\ + mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line \n\ + .word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\ + mov r0, #0 \n\ + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\ + mov pc, lr" + : + : "I" (L1_CACHE_BYTES - 1)); +} + +/* + * blk_dma_clean_range(start,end) + * - start - virtual start address of region + * - end - virtual end address of region + */ +static void __attribute__((naked)) +blk_dma_clean_range(unsigned long start, unsigned long end) +{ + asm( + ".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0 @ blocking \n\ + mov r0, #0 \n\ + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\ + mov pc, lr"); +} + +/* + * blk_dma_flush_range(start,end) + * - start - virtual start address of region + * - end - virtual end address of region + */ +static void __attribute__((naked)) +blk_dma_flush_range(unsigned long start, unsigned long end) +{ + asm( + ".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0 @ blocking \n\ + mov pc, lr"); +} + +static int blockops_trap(struct pt_regs *regs, unsigned int instr) +{ + regs->ARM_r4 |= regs->ARM_r2; + regs->ARM_pc += 4; + return 0; +} + +static char *func[] = { + "Prefetch data range", + "Clean+Invalidate data range", + "Clean data range", + "Invalidate data range", + "Invalidate instr range" +}; + +static struct undef_hook blockops_hook __initdata = { + .instr_mask = 0x0fffffd0, + .instr_val = 0x0c401f00, + .cpsr_mask = PSR_T_BIT, + .cpsr_val = 0, + .fn = blockops_trap, +}; + +static int __init blockops_check(void) +{ + register unsigned int err asm("r4") = 0; + unsigned int err_pos = 1; + unsigned int cache_type; + int i; + + asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_type)); + + printk("Checking V6 block cache operations:\n"); + register_undef_hook(&blockops_hook); + + __asm__ ("mov r0, %0\n\t" + "mov r1, %1\n\t" + "mov r2, #1\n\t" + ".word 0xec401f2c @ mcrr p15, 0, r1, r0, c12, 2\n\t" + "mov r2, #2\n\t" + ".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0\n\t" + "mov r2, #4\n\t" + ".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0\n\t" + "mov r2, #8\n\t" + ".word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0\n\t" + "mov r2, #16\n\t" + ".word 0xec401f05 @ mcrr p15, 0, r1, r0, c5, 0\n\t" + : + : "r" (PAGE_OFFSET), "r" (PAGE_OFFSET + 128) + : "r0", "r1", "r2"); + + unregister_undef_hook(&blockops_hook); + + for (i = 0; i < ARRAY_SIZE(func); i++, err_pos <<= 1) + printk("%30s: %ssupported\n", func[i], err & err_pos ? "not " : ""); + + if ((err & 8) == 0) { + printk(" --> Using %s block cache invalidate\n", + cache_type & (1 << 24) ? "harvard" : "unified"); + if (cache_type & (1 << 24)) + cpu_cache.dma_inv_range = blk_dma_inv_range_harvard; + else + cpu_cache.dma_inv_range = blk_dma_inv_range_unified; + } + if ((err & 4) == 0) { + printk(" --> Using block cache clean\n"); + cpu_cache.dma_clean_range = blk_dma_clean_range; + } + if ((err & 2) == 0) { + printk(" --> Using block cache clean+invalidate\n"); + cpu_cache.dma_flush_range = blk_dma_flush_range; + cpu_cache.flush_kern_dcache_page = blk_flush_kern_dcache_page; + } + + return 0; +} + +__initcall(blockops_check); diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S new file mode 100644 index 0000000..e199478 --- /dev/null +++ b/arch/arm/mm/cache-v3.S @@ -0,0 +1,137 @@ +/* + * linux/arch/arm/mm/cache-v3.S + * + * Copyright (C) 1997-2002 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/linkage.h> +#include <linux/init.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include "proc-macros.S" + +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + * + * - mm - mm_struct describing address space + */ +ENTRY(v3_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(v3_flush_kern_cache_all) + /* FALLTHROUGH */ + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - flags - vma_area_struct flags describing address space + */ +ENTRY(v3_flush_user_cache_range) + mov ip, #0 + mcreq p15, 0, ip, c7, c0, 0 @ flush ID cache + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_coherent_user_range) + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(v3_flush_kern_dcache_page) + /* FALLTHROUGH */ + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_dma_inv_range) + /* FALLTHROUGH */ + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_dma_flush_range) + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ flush ID cache + /* FALLTHROUGH */ + +/* + * dma_clean_range(start, end) + * + * Clean (write back) the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_dma_clean_range) + mov pc, lr + + __INITDATA + + .type v3_cache_fns, #object +ENTRY(v3_cache_fns) + .long v3_flush_kern_cache_all + .long v3_flush_user_cache_all + .long v3_flush_user_cache_range + .long v3_coherent_kern_range + .long v3_coherent_user_range + .long v3_flush_kern_dcache_page + .long v3_dma_inv_range + .long v3_dma_clean_range + .long v3_dma_flush_range + .size v3_cache_fns, . - v3_cache_fns diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S new file mode 100644 index 0000000..b8ad5d5 --- /dev/null +++ b/arch/arm/mm/cache-v4.S @@ -0,0 +1,139 @@ +/* + * linux/arch/arm/mm/cache-v4.S + * + * Copyright (C) 1997-2002 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/linkage.h> +#include <linux/init.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include "proc-macros.S" + +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + * + * - mm - mm_struct describing address space + */ +ENTRY(v4_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(v4_flush_kern_cache_all) + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 @ flush ID cache + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - flags - vma_area_struct flags describing address space + */ +ENTRY(v4_flush_user_cache_range) + mov ip, #0 + mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4_coherent_user_range) + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(v4_flush_kern_dcache_page) + /* FALLTHROUGH */ + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4_dma_inv_range) + /* FALLTHROUGH */ + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4_dma_flush_range) + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 @ flush ID cache + /* FALLTHROUGH */ + +/* + * dma_clean_range(start, end) + * + * Clean (write back) the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4_dma_clean_range) + mov pc, lr + + __INITDATA + + .type v4_cache_fns, #object +ENTRY(v4_cache_fns) + .long v4_flush_kern_cache_all + .long v4_flush_user_cache_all + .long v4_flush_user_cache_range + .long v4_coherent_kern_range + .long v4_coherent_user_range + .long v4_flush_kern_dcache_page + .long v4_dma_inv_range + .long v4_dma_clean_range + .long v4_dma_flush_range + .size v4_cache_fns, . - v4_cache_fns diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S new file mode 100644 index 0000000..5c4055b --- /dev/null +++ b/arch/arm/mm/cache-v4wb.S @@ -0,0 +1,216 @@ +/* + * linux/arch/arm/mm/cache-v4wb.S + * + * Copyright (C) 1997-2002 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/linkage.h> +#include <linux/init.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include "proc-macros.S" + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 32 + +/* + * The total size of the data cache. + */ +#if defined(CONFIG_CPU_SA110) +# define CACHE_DSIZE 16384 +#elif defined(CONFIG_CPU_SA1100) +# define CACHE_DSIZE 8192 +#else +# error Unknown cache size +#endif + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. + * + * Size Clean (ticks) Dirty (ticks) + * 4096 21 20 21 53 55 54 + * 8192 40 41 40 106 100 102 + * 16384 77 77 76 140 140 138 + * 32768 150 149 150 214 216 212 <--- + * 65536 296 297 296 351 358 361 + * 131072 591 591 591 656 657 651 + * Whole 132 136 132 221 217 207 <--- + */ +#define CACHE_DLIMIT (CACHE_DSIZE * 4) + +/* + * flush_user_cache_all() + * + * Clean and invalidate all cache entries in a particular address + * space. + */ +ENTRY(v4wb_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(v4wb_flush_kern_cache_all) + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache +__flush_whole_cache: + mov r0, #FLUSH_BASE + add r1, r0, #CACHE_DSIZE +1: ldr r2, [r0], #32 + cmp r0, r1 + blo 1b + mcr p15, 0, ip, c7, c10, 4 @ drain write buffer + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (inclusive, page aligned) + * - end - end address (exclusive, page aligned) + * - flags - vma_area_struct flags describing address space + */ +ENTRY(v4wb_flush_user_cache_range) + sub r3, r1, r0 @ calculate total size + tst r2, #VM_EXEC @ executable region? + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + + cmp r3, #CACHE_DLIMIT @ total size >= limit? + bhs __flush_whole_cache @ flush whole D cache + +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(v4wb_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ + /* fall through */ + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4wb_coherent_kern_range) + /* fall through */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4wb_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4wb_dma_inv_range) + tst r0, #CACHE_DLINESIZE - 1 + bic r0, r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean (write back) the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4wb_dma_clean_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * This is actually the same as v4wb_coherent_kern_range() + */ + .globl v4wb_dma_flush_range + .set v4wb_dma_flush_range, v4wb_coherent_kern_range + + __INITDATA + + .type v4wb_cache_fns, #object +ENTRY(v4wb_cache_fns) + .long v4wb_flush_kern_cache_all + .long v4wb_flush_user_cache_all + .long v4wb_flush_user_cache_range + .long v4wb_coherent_kern_range + .long v4wb_coherent_user_range + .long v4wb_flush_kern_dcache_page + .long v4wb_dma_inv_range + .long v4wb_dma_clean_range + .long v4wb_dma_flush_range + .size v4wb_cache_fns, . - v4wb_cache_fns diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S new file mode 100644 index 0000000..9bcabd8 --- /dev/null +++ b/arch/arm/mm/cache-v4wt.S @@ -0,0 +1,188 @@ +/* + * linux/arch/arm/mm/cache-v4wt.S + * + * Copyright (C) 1997-2002 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. + * + * ARMv4 write through cache operations support. + * + * We assume that the write buffer is not enabled. + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include "proc-macros.S" + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 32 + +/* + * The number of data cache segments. + */ +#define CACHE_DSEGMENTS 8 + +/* + * The number of lines in a cache segment. + */ +#define CACHE_DENTRIES 64 + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. + * + * *** This needs benchmarking + */ +#define CACHE_DLIMIT 16384 + +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + */ +ENTRY(v4wt_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(v4wt_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (inclusive, page aligned) + * - end - end address (exclusive, page aligned) + * - flags - vma_area_struct flags describing address space + */ +ENTRY(v4wt_flush_user_cache_range) + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + tst r2, #VM_EXEC + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4wt_coherent_kern_range) + /* FALLTRHOUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4wt_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(v4wt_flush_kern_dcache_page) + mov r2, #0 + mcr p15, 0, r2, c7, c5, 0 @ invalidate I cache + add r1, r0, #PAGE_SZ + /* fallthrough */ + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4wt_dma_inv_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + /* FALLTHROUGH */ + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v4wt_dma_clean_range) + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ + .globl v4wt_dma_flush_range + .equ v4wt_dma_flush_range, v4wt_dma_inv_range + + __INITDATA + + .type v4wt_cache_fns, #object +ENTRY(v4wt_cache_fns) + .long v4wt_flush_kern_cache_all + .long v4wt_flush_user_cache_all + .long v4wt_flush_user_cache_range + .long v4wt_coherent_kern_range + .long v4wt_coherent_user_range + .long v4wt_flush_kern_dcache_page + .long v4wt_dma_inv_range + .long v4wt_dma_clean_range + .long v4wt_dma_flush_range + .size v4wt_cache_fns, . - v4wt_cache_fns diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S new file mode 100644 index 0000000..85c10a7 --- /dev/null +++ b/arch/arm/mm/cache-v6.S @@ -0,0 +1,227 @@ +/* + * linux/arch/arm/mm/cache-v6.S + * + * Copyright (C) 2001 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 version 2 as + * published by the Free Software Foundation. + * + * This is the "shell" of the ARMv6 processor support. + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> + +#include "proc-macros.S" + +#define HARVARD_CACHE +#define CACHE_LINE_SIZE 32 +#define D_CACHE_LINE_SIZE 32 + +/* + * v6_flush_cache_all() + * + * Flush the entire cache. + * + * It is assumed that: + */ +ENTRY(v6_flush_kern_cache_all) + mov r0, #0 +#ifdef HARVARD_CACHE + mcr p15, 0, r0, c7, c14, 0 @ D cache clean+invalidate + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate +#else + mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate +#endif + mov pc, lr + +/* + * v6_flush_cache_all() + * + * Flush all TLB entries in a particular address space + * + * - mm - mm_struct describing address space + */ +ENTRY(v6_flush_user_cache_all) + /*FALLTHROUGH*/ + +/* + * v6_flush_cache_range(start, end, flags) + * + * Flush a range of TLB entries in the specified address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - flags - vm_area_struct flags describing address space + * + * It is assumed that: + * - we have a VIPT cache. + */ +ENTRY(v6_flush_user_cache_range) + mov pc, lr + +/* + * v6_coherent_kern_range(start,end) + * + * Ensure that the I and D caches are coherent within specified + * region. This is typically used when code has been written to + * a memory region, and will be executed. + * + * - start - virtual start address of region + * - end - virtual end address of region + * + * It is assumed that: + * - the Icache does not read data from the write buffer + */ +ENTRY(v6_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * v6_coherent_user_range(start,end) + * + * Ensure that the I and D caches are coherent within specified + * region. This is typically used when code has been written to + * a memory region, and will be executed. + * + * - start - virtual start address of region + * - end - virtual end address of region + * + * It is assumed that: + * - the Icache does not read data from the write buffer + */ +ENTRY(v6_coherent_user_range) + bic r0, r0, #CACHE_LINE_SIZE - 1 +1: +#ifdef HARVARD_CACHE + mcr p15, 0, r0, c7, c10, 1 @ clean D line + mcr p15, 0, r0, c7, c5, 1 @ invalidate I line +#endif + mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry + add r0, r0, #CACHE_LINE_SIZE + cmp r0, r1 + blo 1b +#ifdef HARVARD_CACHE + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer +#endif + mov pc, lr + +/* + * v6_flush_kern_dcache_page(kaddr) + * + * Ensure that the data held in the page kaddr is written back + * to the page in question. + * + * - kaddr - kernel address (guaranteed to be page aligned) + */ +ENTRY(v6_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: +#ifdef HARVARD_CACHE + mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line +#else + mcr p15, 0, r0, c7, c15, 1 @ clean & invalidate unified line +#endif + add r0, r0, #D_CACHE_LINE_SIZE + cmp r0, r1 + blo 1b +#ifdef HARVARD_CACHE + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 +#endif + mov pc, lr + + +/* + * v6_dma_inv_range(start,end) + * + * Invalidate the data cache within the specified region; we will + * be performing a DMA operation in this region and we want to + * purge old data in the cache. + * + * - start - virtual start address of region + * - end - virtual end address of region + */ +ENTRY(v6_dma_inv_range) + tst r0, #D_CACHE_LINE_SIZE - 1 + bic r0, r0, #D_CACHE_LINE_SIZE - 1 +#ifdef HARVARD_CACHE + mcrne p15, 0, r0, c7, c10, 1 @ clean D line +#else + mcrne p15, 0, r0, c7, c11, 1 @ clean unified line +#endif + tst r1, #D_CACHE_LINE_SIZE - 1 + bic r1, r1, #D_CACHE_LINE_SIZE - 1 +#ifdef HARVARD_CACHE + mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line +#else + mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line +#endif +1: +#ifdef HARVARD_CACHE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D line +#else + mcr p15, 0, r0, c7, c7, 1 @ invalidate unified line +#endif + add r0, r0, #D_CACHE_LINE_SIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mov pc, lr + +/* + * v6_dma_clean_range(start,end) + * - start - virtual start address of region + * - end - virtual end address of region + */ +ENTRY(v6_dma_clean_range) + bic r0, r0, #D_CACHE_LINE_SIZE - 1 +1: +#ifdef HARVARD_CACHE + mcr p15, 0, r0, c7, c10, 1 @ clean D line +#else + mcr p15, 0, r0, c7, c11, 1 @ clean unified line +#endif + add r0, r0, #D_CACHE_LINE_SIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mov pc, lr + +/* + * v6_dma_flush_range(start,end) + * - start - virtual start address of region + * - end - virtual end address of region + */ +ENTRY(v6_dma_flush_range) + bic r0, r0, #D_CACHE_LINE_SIZE - 1 +1: +#ifdef HARVARD_CACHE + mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line +#else + mcr p15, 0, r0, c7, c15, 1 @ clean & invalidate line +#endif + add r0, r0, #D_CACHE_LINE_SIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mov pc, lr + + __INITDATA + + .type v6_cache_fns, #object +ENTRY(v6_cache_fns) + .long v6_flush_kern_cache_all + .long v6_flush_user_cache_all + .long v6_flush_user_cache_range + .long v6_coherent_kern_range + .long v6_coherent_user_range + .long v6_flush_kern_dcache_page + .long v6_dma_inv_range + .long v6_dma_clean_range + .long v6_dma_flush_range + .size v6_cache_fns, . - v6_cache_fns diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c new file mode 100644 index 0000000..26356ce --- /dev/null +++ b/arch/arm/mm/consistent.c @@ -0,0 +1,451 @@ +/* + * linux/arch/arm/mm/consistent.c + * + * Copyright (C) 2000-2004 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. + * + * DMA uncached mapping support. + */ +#include <linux/module.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/errno.h> +#include <linux/list.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> + +#include <asm/cacheflush.h> +#include <asm/io.h> +#include <asm/tlbflush.h> + +#define CONSISTENT_BASE (0xffc00000) +#define CONSISTENT_END (0xffe00000) +#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) + +/* + * This is the page table (2MB) covering uncached, DMA consistent allocations + */ +static pte_t *consistent_pte; +static DEFINE_SPINLOCK(consistent_lock); + +/* + * VM region handling support. + * + * This should become something generic, handling VM region allocations for + * vmalloc and similar (ioremap, module space, etc). + * + * I envisage vmalloc()'s supporting vm_struct becoming: + * + * struct vm_struct { + * struct vm_region region; + * unsigned long flags; + * struct page **pages; + * unsigned int nr_pages; + * unsigned long phys_addr; + * }; + * + * get_vm_area() would then call vm_region_alloc with an appropriate + * struct vm_region head (eg): + * + * struct vm_region vmalloc_head = { + * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list), + * .vm_start = VMALLOC_START, + * .vm_end = VMALLOC_END, + * }; + * + * However, vmalloc_head.vm_start is variable (typically, it is dependent on + * the amount of RAM found at boot time.) I would imagine that get_vm_area() + * would have to initialise this each time prior to calling vm_region_alloc(). + */ +struct vm_region { + struct list_head vm_list; + unsigned long vm_start; + unsigned long vm_end; + struct page *vm_pages; +}; + +static struct vm_region consistent_head = { + .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), + .vm_start = CONSISTENT_BASE, + .vm_end = CONSISTENT_END, +}; + +static struct vm_region * +vm_region_alloc(struct vm_region *head, size_t size, int gfp) +{ + unsigned long addr = head->vm_start, end = head->vm_end - size; + unsigned long flags; + struct vm_region *c, *new; + + new = kmalloc(sizeof(struct vm_region), gfp); + if (!new) + goto out; + + spin_lock_irqsave(&consistent_lock, flags); + + list_for_each_entry(c, &head->vm_list, vm_list) { + if ((addr + size) < addr) + goto nospc; + if ((addr + size) <= c->vm_start) + goto found; + addr = c->vm_end; + if (addr > end) + goto nospc; + } + + found: + /* + * Insert this entry _before_ the one we found. + */ + list_add_tail(&new->vm_list, &c->vm_list); + new->vm_start = addr; + new->vm_end = addr + size; + + spin_unlock_irqrestore(&consistent_lock, flags); + return new; + + nospc: + spin_unlock_irqrestore(&consistent_lock, flags); + kfree(new); + out: + return NULL; +} + +static struct vm_region *vm_region_find(struct vm_region *head, unsigned long addr) +{ + struct vm_region *c; + + list_for_each_entry(c, &head->vm_list, vm_list) { + if (c->vm_start == addr) + goto out; + } + c = NULL; + out: + return c; +} + +#ifdef CONFIG_HUGETLB_PAGE +#error ARM Coherent DMA allocator does not (yet) support huge TLB +#endif + +static void * +__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, int gfp, + pgprot_t prot) +{ + struct page *page; + struct vm_region *c; + unsigned long order; + u64 mask = ISA_DMA_THRESHOLD, limit; + + if (!consistent_pte) { + printk(KERN_ERR "%s: not initialised\n", __func__); + dump_stack(); + return NULL; + } + + if (dev) { + mask = dev->coherent_dma_mask; + + /* + * Sanity check the DMA mask - it must be non-zero, and + * must be able to be satisfied by a DMA allocation. + */ + if (mask == 0) { + dev_warn(dev, "coherent DMA mask is unset\n"); + goto no_page; + } + + if ((~mask) & ISA_DMA_THRESHOLD) { + dev_warn(dev, "coherent DMA mask %#llx is smaller " + "than system GFP_DMA mask %#llx\n", + mask, (unsigned long long)ISA_DMA_THRESHOLD); + goto no_page; + } + } + + /* + * Sanity check the allocation size. + */ + size = PAGE_ALIGN(size); + limit = (mask + 1) & ~mask; + if ((limit && size >= limit) || + size >= (CONSISTENT_END - CONSISTENT_BASE)) { + printk(KERN_WARNING "coherent allocation too big " + "(requested %#x mask %#llx)\n", size, mask); + goto no_page; + } + + order = get_order(size); + + if (mask != 0xffffffff) + gfp |= GFP_DMA; + + page = alloc_pages(gfp, order); + if (!page) + goto no_page; + + /* + * Invalidate any data that might be lurking in the + * kernel direct-mapped region for device DMA. + */ + { + unsigned long kaddr = (unsigned long)page_address(page); + memset(page_address(page), 0, size); + dmac_flush_range(kaddr, kaddr + size); + } + + /* + * Allocate a virtual address in the consistent mapping region. + */ + c = vm_region_alloc(&consistent_head, size, + gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); + if (c) { + pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start); + struct page *end = page + (1 << order); + + c->vm_pages = page; + + /* + * Set the "dma handle" + */ + *handle = page_to_dma(dev, page); + + do { + BUG_ON(!pte_none(*pte)); + + set_page_count(page, 1); + /* + * x86 does not mark the pages reserved... + */ + SetPageReserved(page); + set_pte(pte, mk_pte(page, prot)); + page++; + pte++; + } while (size -= PAGE_SIZE); + + /* + * Free the otherwise unused pages. + */ + while (page < end) { + set_page_count(page, 1); + __free_page(page); + page++; + } + + return (void *)c->vm_start; + } + + if (page) + __free_pages(page, order); + no_page: + *handle = ~0; + return NULL; +} + +/* + * Allocate DMA-coherent memory space and return both the kernel remapped + * virtual and bus address for that space. + */ +void * +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp) +{ + return __dma_alloc(dev, size, handle, gfp, + pgprot_noncached(pgprot_kernel)); +} +EXPORT_SYMBOL(dma_alloc_coherent); + +/* + * Allocate a writecombining region, in much the same way as + * dma_alloc_coherent above. + */ +void * +dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, int gfp) +{ + return __dma_alloc(dev, size, handle, gfp, + pgprot_writecombine(pgprot_kernel)); +} +EXPORT_SYMBOL(dma_alloc_writecombine); + +static int dma_mmap(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size) +{ + unsigned long flags, user_size, kern_size; + struct vm_region *c; + int ret = -ENXIO; + + user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + + spin_lock_irqsave(&consistent_lock, flags); + c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); + spin_unlock_irqrestore(&consistent_lock, flags); + + if (c) { + unsigned long off = vma->vm_pgoff; + + kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT; + + if (off < kern_size && + user_size <= (kern_size - off)) { + vma->vm_flags |= VM_RESERVED; + ret = remap_pfn_range(vma, vma->vm_start, + page_to_pfn(c->vm_pages) + off, + user_size << PAGE_SHIFT, + vma->vm_page_prot); + } + } + + return ret; +} + +int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size) +{ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + return dma_mmap(dev, vma, cpu_addr, dma_addr, size); +} +EXPORT_SYMBOL(dma_mmap_coherent); + +int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size) +{ + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + return dma_mmap(dev, vma, cpu_addr, dma_addr, size); +} +EXPORT_SYMBOL(dma_mmap_writecombine); + +/* + * free a page as defined by the above mapping. + */ +void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) +{ + struct vm_region *c; + unsigned long flags, addr; + pte_t *ptep; + + size = PAGE_ALIGN(size); + + spin_lock_irqsave(&consistent_lock, flags); + + c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); + if (!c) + goto no_area; + + if ((c->vm_end - c->vm_start) != size) { + printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", + __func__, c->vm_end - c->vm_start, size); + dump_stack(); + size = c->vm_end - c->vm_start; + } + + ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start); + addr = c->vm_start; + do { + pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); + unsigned long pfn; + + ptep++; + addr += PAGE_SIZE; + + if (!pte_none(pte) && pte_present(pte)) { + pfn = pte_pfn(pte); + + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + + /* + * x86 does not mark the pages reserved... + */ + ClearPageReserved(page); + + __free_page(page); + continue; + } + } + + printk(KERN_CRIT "%s: bad page in kernel page table\n", + __func__); + } while (size -= PAGE_SIZE); + + flush_tlb_kernel_range(c->vm_start, c->vm_end); + + list_del(&c->vm_list); + + spin_unlock_irqrestore(&consistent_lock, flags); + + kfree(c); + return; + + no_area: + spin_unlock_irqrestore(&consistent_lock, flags); + printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n", + __func__, cpu_addr); + dump_stack(); +} +EXPORT_SYMBOL(dma_free_coherent); + +/* + * Initialise the consistent memory allocation. + */ +static int __init consistent_init(void) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + int ret = 0; + + spin_lock(&init_mm.page_table_lock); + + do { + pgd = pgd_offset(&init_mm, CONSISTENT_BASE); + pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE); + if (!pmd) { + printk(KERN_ERR "%s: no pmd tables\n", __func__); + ret = -ENOMEM; + break; + } + WARN_ON(!pmd_none(*pmd)); + + pte = pte_alloc_kernel(&init_mm, pmd, CONSISTENT_BASE); + if (!pte) { + printk(KERN_ERR "%s: no pte tables\n", __func__); + ret = -ENOMEM; + break; + } + + consistent_pte = pte; + } while (0); + + spin_unlock(&init_mm.page_table_lock); + + return ret; +} + +core_initcall(consistent_init); + +/* + * Make an area consistent for devices. + */ +void consistent_sync(void *vaddr, size_t size, int direction) +{ + unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; + + switch (direction) { + case DMA_FROM_DEVICE: /* invalidate only */ + dmac_inv_range(start, end); + break; + case DMA_TO_DEVICE: /* writeback only */ + dmac_clean_range(start, end); + break; + case DMA_BIDIRECTIONAL: /* writeback and invalidate */ + dmac_flush_range(start, end); + break; + default: + BUG(); + } +} +EXPORT_SYMBOL(consistent_sync); diff --git a/arch/arm/mm/copypage-v3.S b/arch/arm/mm/copypage-v3.S new file mode 100644 index 0000000..4940f19 --- /dev/null +++ b/arch/arm/mm/copypage-v3.S @@ -0,0 +1,67 @@ +/* + * linux/arch/arm/lib/copypage.S + * + * Copyright (C) 1995-1999 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> + + .text + .align 5 +/* + * ARMv3 optimised copy_user_page + * + * FIXME: do we need to handle cache stuff... + */ +ENTRY(v3_copy_user_page) + stmfd sp!, {r4, lr} @ 2 + mov r2, #PAGE_SZ/64 @ 1 + ldmia r1!, {r3, r4, ip, lr} @ 4+1 +1: stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4+1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4+1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4 + subs r2, r2, #1 @ 1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmneia r1!, {r3, r4, ip, lr} @ 4 + bne 1b @ 1 + LOADREGS(fd, sp!, {r4, pc}) @ 3 + + .align 5 +/* + * ARMv3 optimised clear_user_page + * + * FIXME: do we need to handle cache stuff... + */ +ENTRY(v3_clear_user_page) + str lr, [sp, #-4]! + mov r1, #PAGE_SZ/64 @ 1 + mov r2, #0 @ 1 + mov r3, #0 @ 1 + mov ip, #0 @ 1 + mov lr, #0 @ 1 +1: stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + subs r1, r1, #1 @ 1 + bne 1b @ 1 + ldr pc, [sp], #4 + + __INITDATA + + .type v3_user_fns, #object +ENTRY(v3_user_fns) + .long v3_clear_user_page + .long v3_copy_user_page + .size v3_user_fns, . - v3_user_fns diff --git a/arch/arm/mm/copypage-v4mc.S b/arch/arm/mm/copypage-v4mc.S new file mode 100644 index 0000000..305af3d --- /dev/null +++ b/arch/arm/mm/copypage-v4mc.S @@ -0,0 +1,80 @@ +/* + * linux/arch/arm/lib/copy_page-armv4mc.S + * + * 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> + + .text + .align 5 +/* + * ARMv4 mini-dcache optimised copy_user_page + * + * We flush the destination cache lines just before we write the data into the + * corresponding address. Since the Dcache is read-allocate, this removes the + * Dcache aliasing issue. The writes will be forwarded to the write buffer, + * and merged as appropriate. + * + * Note: We rely on all ARMv4 processors implementing the "invalidate D line" + * instruction. If your processor does not supply this, you have to write your + * own copy_user_page that does the right thing. + */ +ENTRY(v4_mc_copy_user_page) + stmfd sp!, {r4, lr} @ 2 + mov r4, r0 + mov r0, r1 + bl map_page_minicache + mov r1, #PAGE_SZ/64 @ 1 + ldmia r0!, {r2, r3, ip, lr} @ 4 +1: mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line + stmia r4!, {r2, r3, ip, lr} @ 4 + ldmia r0!, {r2, r3, ip, lr} @ 4+1 + stmia r4!, {r2, r3, ip, lr} @ 4 + ldmia r0!, {r2, r3, ip, lr} @ 4 + mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line + stmia r4!, {r2, r3, ip, lr} @ 4 + ldmia r0!, {r2, r3, ip, lr} @ 4 + subs r1, r1, #1 @ 1 + stmia r4!, {r2, r3, ip, lr} @ 4 + ldmneia r0!, {r2, r3, ip, lr} @ 4 + bne 1b @ 1 + ldmfd sp!, {r4, pc} @ 3 + + .align 5 +/* + * ARMv4 optimised clear_user_page + * + * Same story as above. + */ +ENTRY(v4_mc_clear_user_page) + str lr, [sp, #-4]! + mov r1, #PAGE_SZ/64 @ 1 + mov r2, #0 @ 1 + mov r3, #0 @ 1 + mov ip, #0 @ 1 + mov lr, #0 @ 1 +1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line + stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line + stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + subs r1, r1, #1 @ 1 + bne 1b @ 1 + ldr pc, [sp], #4 + + __INITDATA + + .type v4_mc_user_fns, #object +ENTRY(v4_mc_user_fns) + .long v4_mc_clear_user_page + .long v4_mc_copy_user_page + .size v4_mc_user_fns, . - v4_mc_user_fns diff --git a/arch/arm/mm/copypage-v4wb.S b/arch/arm/mm/copypage-v4wb.S new file mode 100644 index 0000000..b94c345 --- /dev/null +++ b/arch/arm/mm/copypage-v4wb.S @@ -0,0 +1,79 @@ +/* + * linux/arch/arm/lib/copypage.S + * + * Copyright (C) 1995-1999 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. + * + * ASM optimised string functions + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> + + .text + .align 5 +/* + * ARMv4 optimised copy_user_page + * + * We flush the destination cache lines just before we write the data into the + * corresponding address. Since the Dcache is read-allocate, this removes the + * Dcache aliasing issue. The writes will be forwarded to the write buffer, + * and merged as appropriate. + * + * Note: We rely on all ARMv4 processors implementing the "invalidate D line" + * instruction. If your processor does not supply this, you have to write your + * own copy_user_page that does the right thing. + */ +ENTRY(v4wb_copy_user_page) + stmfd sp!, {r4, lr} @ 2 + mov r2, #PAGE_SZ/64 @ 1 + ldmia r1!, {r3, r4, ip, lr} @ 4 +1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4+1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4 + mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4 + subs r2, r2, #1 @ 1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmneia r1!, {r3, r4, ip, lr} @ 4 + bne 1b @ 1 + mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB + ldmfd sp!, {r4, pc} @ 3 + + .align 5 +/* + * ARMv4 optimised clear_user_page + * + * Same story as above. + */ +ENTRY(v4wb_clear_user_page) + str lr, [sp, #-4]! + mov r1, #PAGE_SZ/64 @ 1 + mov r2, #0 @ 1 + mov r3, #0 @ 1 + mov ip, #0 @ 1 + mov lr, #0 @ 1 +1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line + stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line + stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + subs r1, r1, #1 @ 1 + bne 1b @ 1 + mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB + ldr pc, [sp], #4 + + __INITDATA + + .type v4wb_user_fns, #object +ENTRY(v4wb_user_fns) + .long v4wb_clear_user_page + .long v4wb_copy_user_page + .size v4wb_user_fns, . - v4wb_user_fns diff --git a/arch/arm/mm/copypage-v4wt.S b/arch/arm/mm/copypage-v4wt.S new file mode 100644 index 0000000..9767939 --- /dev/null +++ b/arch/arm/mm/copypage-v4wt.S @@ -0,0 +1,73 @@ +/* + * linux/arch/arm/lib/copypage-v4.S + * + * Copyright (C) 1995-1999 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. + * + * ASM optimised string functions + * + * This is for CPUs with a writethrough cache and 'flush ID cache' is + * the only supported cache operation. + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> + + .text + .align 5 +/* + * ARMv4 optimised copy_user_page + * + * Since we have writethrough caches, we don't have to worry about + * dirty data in the cache. However, we do have to ensure that + * subsequent reads are up to date. + */ +ENTRY(v4wt_copy_user_page) + stmfd sp!, {r4, lr} @ 2 + mov r2, #PAGE_SZ/64 @ 1 + ldmia r1!, {r3, r4, ip, lr} @ 4 +1: stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4+1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4 + subs r2, r2, #1 @ 1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmneia r1!, {r3, r4, ip, lr} @ 4 + bne 1b @ 1 + mcr p15, 0, r2, c7, c7, 0 @ flush ID cache + ldmfd sp!, {r4, pc} @ 3 + + .align 5 +/* + * ARMv4 optimised clear_user_page + * + * Same story as above. + */ +ENTRY(v4wt_clear_user_page) + str lr, [sp, #-4]! + mov r1, #PAGE_SZ/64 @ 1 + mov r2, #0 @ 1 + mov r3, #0 @ 1 + mov ip, #0 @ 1 + mov lr, #0 @ 1 +1: stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + stmia r0!, {r2, r3, ip, lr} @ 4 + subs r1, r1, #1 @ 1 + bne 1b @ 1 + mcr p15, 0, r2, c7, c7, 0 @ flush ID cache + ldr pc, [sp], #4 + + __INITDATA + + .type v4wt_user_fns, #object +ENTRY(v4wt_user_fns) + .long v4wt_clear_user_page + .long v4wt_copy_user_page + .size v4wt_user_fns, . - v4wt_user_fns diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c new file mode 100644 index 0000000..694ac82 --- /dev/null +++ b/arch/arm/mm/copypage-v6.c @@ -0,0 +1,155 @@ +/* + * linux/arch/arm/mm/copypage-v6.c + * + * Copyright (C) 2002 Deep Blue Solutions Ltd, All Rights Reserved. + * + * 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/init.h> +#include <linux/spinlock.h> +#include <linux/mm.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/shmparam.h> +#include <asm/tlbflush.h> +#include <asm/cacheflush.h> + +#if SHMLBA > 16384 +#error FIX ME +#endif + +#define from_address (0xffff8000) +#define from_pgprot PAGE_KERNEL +#define to_address (0xffffc000) +#define to_pgprot PAGE_KERNEL + +static pte_t *from_pte; +static pte_t *to_pte; +static DEFINE_SPINLOCK(v6_lock); + +#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) + +/* + * Copy the user page. No aliasing to deal with so we can just + * attack the kernel's existing mapping of these pages. + */ +void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr) +{ + copy_page(kto, kfrom); +} + +/* + * Clear the user page. No aliasing to deal with so we can just + * attack the kernel's existing mapping of this page. + */ +void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr) +{ + clear_page(kaddr); +} + +/* + * Copy the page, taking account of the cache colour. + */ +void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr) +{ + unsigned int offset = DCACHE_COLOUR(vaddr); + unsigned long from, to; + + /* + * Discard data in the kernel mapping for the new page. + * FIXME: needs this MCRR to be supported. + */ + __asm__("mcrr p15, 0, %1, %0, c6 @ 0xec401f06" + : + : "r" (kto), + "r" ((unsigned long)kto + PAGE_SIZE - L1_CACHE_BYTES) + : "cc"); + + /* + * Now copy the page using the same cache colour as the + * pages ultimate destination. + */ + spin_lock(&v6_lock); + + set_pte(from_pte + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot)); + set_pte(to_pte + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot)); + + from = from_address + (offset << PAGE_SHIFT); + to = to_address + (offset << PAGE_SHIFT); + + flush_tlb_kernel_page(from); + flush_tlb_kernel_page(to); + + copy_page((void *)to, (void *)from); + + spin_unlock(&v6_lock); +} + +/* + * Clear the user page. We need to deal with the aliasing issues, + * so remap the kernel page into the same cache colour as the user + * page. + */ +void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr) +{ + unsigned int offset = DCACHE_COLOUR(vaddr); + unsigned long to = to_address + (offset << PAGE_SHIFT); + + /* + * Discard data in the kernel mapping for the new page + * FIXME: needs this MCRR to be supported. + */ + __asm__("mcrr p15, 0, %1, %0, c6 @ 0xec401f06" + : + : "r" (kaddr), + "r" ((unsigned long)kaddr + PAGE_SIZE - L1_CACHE_BYTES) + : "cc"); + + /* + * Now clear the page using the same cache colour as + * the pages ultimate destination. + */ + spin_lock(&v6_lock); + + set_pte(to_pte + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot)); + flush_tlb_kernel_page(to); + clear_page((void *)to); + + spin_unlock(&v6_lock); +} + +struct cpu_user_fns v6_user_fns __initdata = { + .cpu_clear_user_page = v6_clear_user_page_nonaliasing, + .cpu_copy_user_page = v6_copy_user_page_nonaliasing, +}; + +static int __init v6_userpage_init(void) +{ + if (cache_is_vipt_aliasing()) { + pgd_t *pgd; + pmd_t *pmd; + + pgd = pgd_offset_k(from_address); + pmd = pmd_alloc(&init_mm, pgd, from_address); + if (!pmd) + BUG(); + from_pte = pte_alloc_kernel(&init_mm, pmd, from_address); + if (!from_pte) + BUG(); + + to_pte = pte_alloc_kernel(&init_mm, pmd, to_address); + if (!to_pte) + BUG(); + + cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing; + cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing; + } + + return 0; +} + +__initcall(v6_userpage_init); + diff --git a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S new file mode 100644 index 0000000..bb27731 --- /dev/null +++ b/arch/arm/mm/copypage-xscale.S @@ -0,0 +1,113 @@ +/* + * linux/arch/arm/lib/copypage-xscale.S + * + * Copyright (C) 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/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> + +/* + * General note: + * We don't really want write-allocate cache behaviour for these functions + * since that will just eat through 8K of the cache. + */ + + .text + .align 5 +/* + * XScale optimised copy_user_page + * r0 = destination + * r1 = source + * r2 = virtual user address of ultimate destination page + * + * The source page may have some clean entries in the cache already, but we + * can safely ignore them - break_cow() will flush them out of the cache + * if we eventually end up using our copied page. + * + * What we could do is use the mini-cache to buffer reads from the source + * page. We rely on the mini-cache being smaller than one page, so we'll + * cycle through the complete cache anyway. + */ +ENTRY(xscale_mc_copy_user_page) + stmfd sp!, {r4, r5, lr} + mov r5, r0 + mov r0, r1 + bl map_page_minicache + mov r1, r5 + mov lr, #PAGE_SZ/64-1 + + /* + * Strangely enough, best performance is achieved + * when prefetching destination as well. (NP) + */ + pld [r0, #0] + pld [r0, #32] + pld [r1, #0] + pld [r1, #32] + +1: pld [r0, #64] + pld [r0, #96] + pld [r1, #64] + pld [r1, #96] + +2: ldrd r2, [r0], #8 + ldrd r4, [r0], #8 + mov ip, r1 + strd r2, [r1], #8 + ldrd r2, [r0], #8 + strd r4, [r1], #8 + ldrd r4, [r0], #8 + strd r2, [r1], #8 + strd r4, [r1], #8 + mcr p15, 0, ip, c7, c10, 1 @ clean D line + ldrd r2, [r0], #8 + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line + ldrd r4, [r0], #8 + mov ip, r1 + strd r2, [r1], #8 + ldrd r2, [r0], #8 + strd r4, [r1], #8 + ldrd r4, [r0], #8 + strd r2, [r1], #8 + strd r4, [r1], #8 + mcr p15, 0, ip, c7, c10, 1 @ clean D line + subs lr, lr, #1 + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line + bgt 1b + beq 2b + + ldmfd sp!, {r4, r5, pc} + + .align 5 +/* + * XScale optimised clear_user_page + * r0 = destination + * r1 = virtual user address of ultimate destination page + */ +ENTRY(xscale_mc_clear_user_page) + mov r1, #PAGE_SZ/32 + mov r2, #0 + mov r3, #0 +1: mov ip, r0 + strd r2, [r0], #8 + strd r2, [r0], #8 + strd r2, [r0], #8 + strd r2, [r0], #8 + mcr p15, 0, ip, c7, c10, 1 @ clean D line + subs r1, r1, #1 + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line + bne 1b + mov pc, lr + + __INITDATA + + .type xscale_mc_user_fns, #object +ENTRY(xscale_mc_user_fns) + .long xscale_mc_clear_user_page + .long xscale_mc_copy_user_page + .size xscale_mc_user_fns, . - xscale_mc_user_fns diff --git a/arch/arm/mm/discontig.c b/arch/arm/mm/discontig.c new file mode 100644 index 0000000..0d097bb --- /dev/null +++ b/arch/arm/mm/discontig.c @@ -0,0 +1,49 @@ +/* + * linux/arch/arm/mm/discontig.c + * + * Discontiguous memory support. + * + * Initial code: Copyright (C) 1999-2000 Nicolas Pitre + * + * 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/module.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/bootmem.h> + +#if MAX_NUMNODES != 4 && MAX_NUMNODES != 16 +# error Fix Me Please +#endif + +/* + * Our node_data structure for discontiguous memory. + */ + +static bootmem_data_t node_bootmem_data[MAX_NUMNODES]; + +pg_data_t discontig_node_data[MAX_NUMNODES] = { + { .bdata = &node_bootmem_data[0] }, + { .bdata = &node_bootmem_data[1] }, + { .bdata = &node_bootmem_data[2] }, + { .bdata = &node_bootmem_data[3] }, +#if MAX_NUMNODES == 16 + { .bdata = &node_bootmem_data[4] }, + { .bdata = &node_bootmem_data[5] }, + { .bdata = &node_bootmem_data[6] }, + { .bdata = &node_bootmem_data[7] }, + { .bdata = &node_bootmem_data[8] }, + { .bdata = &node_bootmem_data[9] }, + { .bdata = &node_bootmem_data[10] }, + { .bdata = &node_bootmem_data[11] }, + { .bdata = &node_bootmem_data[12] }, + { .bdata = &node_bootmem_data[13] }, + { .bdata = &node_bootmem_data[14] }, + { .bdata = &node_bootmem_data[15] }, +#endif +}; + +EXPORT_SYMBOL(discontig_node_data); diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c new file mode 100644 index 0000000..9592c3e --- /dev/null +++ b/arch/arm/mm/extable.c @@ -0,0 +1,16 @@ +/* + * linux/arch/arm/mm/extable.c + */ +#include <linux/module.h> +#include <asm/uaccess.h> + +int fixup_exception(struct pt_regs *regs) +{ + const struct exception_table_entry *fixup; + + fixup = search_exception_tables(instruction_pointer(regs)); + if (fixup) + regs->ARM_pc = fixup->fixup; + + return fixup != NULL; +} diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c new file mode 100644 index 0000000..01967dd --- /dev/null +++ b/arch/arm/mm/fault-armv.c @@ -0,0 +1,223 @@ +/* + * linux/arch/arm/mm/fault-armv.c + * + * Copyright (C) 1995 Linus Torvalds + * Modifications for ARM processor (c) 1995-2002 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/module.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/bitops.h> +#include <linux/vmalloc.h> +#include <linux/init.h> +#include <linux/pagemap.h> + +#include <asm/cacheflush.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> + +static unsigned long shared_pte_mask = L_PTE_CACHEABLE; + +/* + * We take the easy way out of this problem - we make the + * PTE uncacheable. However, we leave the write buffer on. + */ +static int adjust_pte(struct vm_area_struct *vma, unsigned long address) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte, entry; + int ret = 0; + + pgd = pgd_offset(vma->vm_mm, address); + if (pgd_none(*pgd)) + goto no_pgd; + if (pgd_bad(*pgd)) + goto bad_pgd; + + pmd = pmd_offset(pgd, address); + if (pmd_none(*pmd)) + goto no_pmd; + if (pmd_bad(*pmd)) + goto bad_pmd; + + pte = pte_offset_map(pmd, address); + entry = *pte; + + /* + * If this page isn't present, or is already setup to + * fault (ie, is old), we can safely ignore any issues. + */ + if (pte_present(entry) && pte_val(entry) & shared_pte_mask) { + flush_cache_page(vma, address, pte_pfn(entry)); + pte_val(entry) &= ~shared_pte_mask; + set_pte(pte, entry); + flush_tlb_page(vma, address); + ret = 1; + } + pte_unmap(pte); + return ret; + +bad_pgd: + pgd_ERROR(*pgd); + pgd_clear(pgd); +no_pgd: + return 0; + +bad_pmd: + pmd_ERROR(*pmd); + pmd_clear(pmd); +no_pmd: + return 0; +} + +static void +make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty) +{ + struct address_space *mapping = page_mapping(page); + struct mm_struct *mm = vma->vm_mm; + struct vm_area_struct *mpnt; + struct prio_tree_iter iter; + unsigned long offset; + pgoff_t pgoff; + int aliases = 0; + + if (!mapping) + return; + + pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT); + + /* + * If we have any shared mappings that are in the same mm + * space, then we need to handle them specially to maintain + * cache coherency. + */ + flush_dcache_mmap_lock(mapping); + vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) { + /* + * If this VMA is not in our MM, we can ignore it. + * Note that we intentionally mask out the VMA + * that we are fixing up. + */ + if (mpnt->vm_mm != mm || mpnt == vma) + continue; + if (!(mpnt->vm_flags & VM_MAYSHARE)) + continue; + offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; + aliases += adjust_pte(mpnt, mpnt->vm_start + offset); + } + flush_dcache_mmap_unlock(mapping); + if (aliases) + adjust_pte(vma, addr); + else + flush_cache_page(vma, addr, page_to_pfn(page)); +} + +/* + * Take care of architecture specific things when placing a new PTE into + * a page table, or changing an existing PTE. Basically, there are two + * things that we need to take care of: + * + * 1. If PG_dcache_dirty is set for the page, we need to ensure + * that any cache entries for the kernels virtual memory + * range are written back to the page. + * 2. If we have multiple shared mappings of the same space in + * an object, we need to deal with the cache aliasing issues. + * + * Note that the page_table_lock will be held. + */ +void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) +{ + unsigned long pfn = pte_pfn(pte); + struct page *page; + + if (!pfn_valid(pfn)) + return; + page = pfn_to_page(pfn); + if (page_mapping(page)) { + int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); + + if (dirty) { + /* + * This is our first userspace mapping of this page. + * Ensure that the physical page is coherent with + * the kernel mapping. + * + * FIXME: only need to do this on VIVT and aliasing + * VIPT cache architectures. We can do that + * by choosing whether to set this bit... + */ + __cpuc_flush_dcache_page(page_address(page)); + } + + if (cache_is_vivt()) + make_coherent(vma, addr, page, dirty); + } +} + +/* + * Check whether the write buffer has physical address aliasing + * issues. If it has, we need to avoid them for the case where + * we have several shared mappings of the same object in user + * space. + */ +static int __init check_writebuffer(unsigned long *p1, unsigned long *p2) +{ + register unsigned long zero = 0, one = 1, val; + + local_irq_disable(); + mb(); + *p1 = one; + mb(); + *p2 = zero; + mb(); + val = *p1; + mb(); + local_irq_enable(); + return val != zero; +} + +void __init check_writebuffer_bugs(void) +{ + struct page *page; + const char *reason; + unsigned long v = 1; + + printk(KERN_INFO "CPU: Testing write buffer coherency: "); + + page = alloc_page(GFP_KERNEL); + if (page) { + unsigned long *p1, *p2; + pgprot_t prot = __pgprot(L_PTE_PRESENT|L_PTE_YOUNG| + L_PTE_DIRTY|L_PTE_WRITE| + L_PTE_BUFFERABLE); + + p1 = vmap(&page, 1, VM_IOREMAP, prot); + p2 = vmap(&page, 1, VM_IOREMAP, prot); + + if (p1 && p2) { + v = check_writebuffer(p1, p2); + reason = "enabling work-around"; + } else { + reason = "unable to map memory\n"; + } + + vunmap(p1); + vunmap(p2); + put_page(page); + } else { + reason = "unable to grab page\n"; + } + + if (v) { + printk("failed, %s\n", reason); + shared_pte_mask |= L_PTE_BUFFERABLE; + } else { + printk("ok\n"); + } +} diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c new file mode 100644 index 0000000..29be1c0 --- /dev/null +++ b/arch/arm/mm/fault.c @@ -0,0 +1,462 @@ +/* + * linux/arch/arm/mm/fault.c + * + * Copyright (C) 1995 Linus Torvalds + * Modifications for ARM processor (c) 1995-2004 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/module.h> +#include <linux/signal.h> +#include <linux/ptrace.h> +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> +#include <asm/uaccess.h> + +#include "fault.h" + +/* + * This is useful to dump out the page tables associated with + * 'addr' in mm 'mm'. + */ +void show_pte(struct mm_struct *mm, unsigned long addr) +{ + pgd_t *pgd; + + if (!mm) + mm = &init_mm; + + printk(KERN_ALERT "pgd = %p\n", mm->pgd); + pgd = pgd_offset(mm, addr); + printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd)); + + do { + pmd_t *pmd; + pte_t *pte; + + if (pgd_none(*pgd)) + break; + + if (pgd_bad(*pgd)) { + printk("(bad)"); + break; + } + + pmd = pmd_offset(pgd, addr); +#if PTRS_PER_PMD != 1 + printk(", *pmd=%08lx", pmd_val(*pmd)); +#endif + + if (pmd_none(*pmd)) + break; + + if (pmd_bad(*pmd)) { + printk("(bad)"); + break; + } + +#ifndef CONFIG_HIGHMEM + /* We must not map this if we have highmem enabled */ + pte = pte_offset_map(pmd, addr); + printk(", *pte=%08lx", pte_val(*pte)); + printk(", *ppte=%08lx", pte_val(pte[-PTRS_PER_PTE])); + pte_unmap(pte); +#endif + } while(0); + + printk("\n"); +} + +/* + * Oops. The kernel tried to access some page that wasn't present. + */ +static void +__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, + struct pt_regs *regs) +{ + /* + * Are we prepared to handle this kernel fault? + */ + if (fixup_exception(regs)) + return; + + /* + * No handler, we'll have to terminate things with extreme prejudice. + */ + bust_spinlocks(1); + printk(KERN_ALERT + "Unable to handle kernel %s at virtual address %08lx\n", + (addr < PAGE_SIZE) ? "NULL pointer dereference" : + "paging request", addr); + + show_pte(mm, addr); + die("Oops", regs, fsr); + bust_spinlocks(0); + do_exit(SIGKILL); +} + +/* + * Something tried to access memory that isn't in our memory map.. + * User mode accesses just cause a SIGSEGV + */ +static void +__do_user_fault(struct task_struct *tsk, unsigned long addr, + unsigned int fsr, int code, struct pt_regs *regs) +{ + struct siginfo si; + +#ifdef CONFIG_DEBUG_USER + if (user_debug & UDBG_SEGV) { + printk(KERN_DEBUG "%s: unhandled page fault at 0x%08lx, code 0x%03x\n", + tsk->comm, addr, fsr); + show_pte(tsk->mm, addr); + show_regs(regs); + } +#endif + + tsk->thread.address = addr; + tsk->thread.error_code = fsr; + tsk->thread.trap_no = 14; + si.si_signo = SIGSEGV; + si.si_errno = 0; + si.si_code = code; + si.si_addr = (void __user *)addr; + force_sig_info(SIGSEGV, &si, tsk); +} + +void +do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr, + unsigned int fsr, struct pt_regs *regs) +{ + /* + * If we are in kernel mode at this point, we + * have no context to handle this fault with. + */ + if (user_mode(regs)) + __do_user_fault(tsk, addr, fsr, SEGV_MAPERR, regs); + else + __do_kernel_fault(mm, addr, fsr, regs); +} + +#define VM_FAULT_BADMAP (-20) +#define VM_FAULT_BADACCESS (-21) + +static int +__do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, + struct task_struct *tsk) +{ + struct vm_area_struct *vma; + int fault, mask; + + vma = find_vma(mm, addr); + fault = VM_FAULT_BADMAP; + if (!vma) + goto out; + if (vma->vm_start > addr) + goto check_stack; + + /* + * Ok, we have a good vm_area for this + * memory access, so we can handle it. + */ +good_area: + if (fsr & (1 << 11)) /* write? */ + mask = VM_WRITE; + else + mask = VM_READ|VM_EXEC; + + fault = VM_FAULT_BADACCESS; + if (!(vma->vm_flags & mask)) + goto out; + + /* + * If for any reason at all we couldn't handle + * the fault, make sure we exit gracefully rather + * than endlessly redo the fault. + */ +survive: + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, fsr & (1 << 11)); + + /* + * Handle the "normal" cases first - successful and sigbus + */ + switch (fault) { + case VM_FAULT_MAJOR: + tsk->maj_flt++; + return fault; + case VM_FAULT_MINOR: + tsk->min_flt++; + case VM_FAULT_SIGBUS: + return fault; + } + + if (tsk->pid != 1) + goto out; + + /* + * If we are out of memory for pid1, + * sleep for a while and retry + */ + yield(); + goto survive; + +check_stack: + if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) + goto good_area; +out: + return fault; +} + +static int +do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + struct task_struct *tsk; + struct mm_struct *mm; + int fault; + + tsk = current; + mm = tsk->mm; + + /* + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ + if (in_interrupt() || !mm) + goto no_context; + + down_read(&mm->mmap_sem); + fault = __do_page_fault(mm, addr, fsr, tsk); + up_read(&mm->mmap_sem); + + /* + * Handle the "normal" case first + */ + if (fault > 0) + return 0; + + /* + * We had some memory, but were unable to + * successfully fix up this page fault. + */ + if (fault == 0) + goto do_sigbus; + + /* + * If we are in kernel mode at this point, we + * have no context to handle this fault with. + */ + if (!user_mode(regs)) + goto no_context; + + if (fault == VM_FAULT_OOM) { + /* + * We ran out of memory, or some other thing happened to + * us that made us unable to handle the page fault gracefully. + */ + printk("VM: killing process %s\n", tsk->comm); + do_exit(SIGKILL); + } else + __do_user_fault(tsk, addr, fsr, fault == VM_FAULT_BADACCESS ? + SEGV_ACCERR : SEGV_MAPERR, regs); + return 0; + + +/* + * We ran out of memory, or some other thing happened to us that made + * us unable to handle the page fault gracefully. + */ +do_sigbus: + /* + * Send a sigbus, regardless of whether we were in kernel + * or user mode. + */ + tsk->thread.address = addr; + tsk->thread.error_code = fsr; + tsk->thread.trap_no = 14; + force_sig(SIGBUS, tsk); +#ifdef CONFIG_DEBUG_USER + if (user_debug & UDBG_BUS) { + printk(KERN_DEBUG "%s: sigbus at 0x%08lx, pc=0x%08lx\n", + current->comm, addr, instruction_pointer(regs)); + } +#endif + + /* Kernel mode? Handle exceptions or die */ + if (user_mode(regs)) + return 0; + +no_context: + __do_kernel_fault(mm, addr, fsr, regs); + return 0; +} + +/* + * First Level Translation Fault Handler + * + * We enter here because the first level page table doesn't contain + * a valid entry for the address. + * + * If the address is in kernel space (>= TASK_SIZE), then we are + * probably faulting in the vmalloc() area. + * + * If the init_task's first level page tables contains the relevant + * entry, we copy the it to this task. If not, we send the process + * a signal, fixup the exception, or oops the kernel. + * + * NOTE! We MUST NOT take any locks for this case. We may be in an + * interrupt or a critical region, and should only copy the information + * from the master page table, nothing more. + */ +static int +do_translation_fault(unsigned long addr, unsigned int fsr, + struct pt_regs *regs) +{ + struct task_struct *tsk; + unsigned int index; + pgd_t *pgd, *pgd_k; + pmd_t *pmd, *pmd_k; + + if (addr < TASK_SIZE) + return do_page_fault(addr, fsr, regs); + + index = pgd_index(addr); + + /* + * FIXME: CP15 C1 is write only on ARMv3 architectures. + */ + pgd = cpu_get_pgd() + index; + pgd_k = init_mm.pgd + index; + + if (pgd_none(*pgd_k)) + goto bad_area; + + if (!pgd_present(*pgd)) + set_pgd(pgd, *pgd_k); + + pmd_k = pmd_offset(pgd_k, addr); + pmd = pmd_offset(pgd, addr); + + if (pmd_none(*pmd_k)) + goto bad_area; + + copy_pmd(pmd, pmd_k); + return 0; + +bad_area: + tsk = current; + + do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); + return 0; +} + +/* + * Some section permission faults need to be handled gracefully. + * They can happen due to a __{get,put}_user during an oops. + */ +static int +do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + struct task_struct *tsk = current; + do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); + return 0; +} + +/* + * This abort handler always returns "fault". + */ +static int +do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + return 1; +} + +static struct fsr_info { + int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs); + int sig; + const char *name; +} fsr_info[] = { + /* + * The following are the standard ARMv3 and ARMv4 aborts. ARMv5 + * defines these to be "precise" aborts. + */ + { do_bad, SIGSEGV, "vector exception" }, + { do_bad, SIGILL, "alignment exception" }, + { do_bad, SIGKILL, "terminal exception" }, + { do_bad, SIGILL, "alignment exception" }, + { do_bad, SIGBUS, "external abort on linefetch" }, + { do_translation_fault, SIGSEGV, "section translation fault" }, + { do_bad, SIGBUS, "external abort on linefetch" }, + { do_page_fault, SIGSEGV, "page translation fault" }, + { do_bad, SIGBUS, "external abort on non-linefetch" }, + { do_bad, SIGSEGV, "section domain fault" }, + { do_bad, SIGBUS, "external abort on non-linefetch" }, + { do_bad, SIGSEGV, "page domain fault" }, + { do_bad, SIGBUS, "external abort on translation" }, + { do_sect_fault, SIGSEGV, "section permission fault" }, + { do_bad, SIGBUS, "external abort on translation" }, + { do_page_fault, SIGSEGV, "page permission fault" }, + /* + * The following are "imprecise" aborts, which are signalled by bit + * 10 of the FSR, and may not be recoverable. These are only + * supported if the CPU abort handler supports bit 10. + */ + { do_bad, SIGBUS, "unknown 16" }, + { do_bad, SIGBUS, "unknown 17" }, + { do_bad, SIGBUS, "unknown 18" }, + { do_bad, SIGBUS, "unknown 19" }, + { do_bad, SIGBUS, "lock abort" }, /* xscale */ + { do_bad, SIGBUS, "unknown 21" }, + { do_bad, SIGBUS, "imprecise external abort" }, /* xscale */ + { do_bad, SIGBUS, "unknown 23" }, + { do_bad, SIGBUS, "dcache parity error" }, /* xscale */ + { do_bad, SIGBUS, "unknown 25" }, + { do_bad, SIGBUS, "unknown 26" }, + { do_bad, SIGBUS, "unknown 27" }, + { do_bad, SIGBUS, "unknown 28" }, + { do_bad, SIGBUS, "unknown 29" }, + { do_bad, SIGBUS, "unknown 30" }, + { do_bad, SIGBUS, "unknown 31" } +}; + +void __init +hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), + int sig, const char *name) +{ + if (nr >= 0 && nr < ARRAY_SIZE(fsr_info)) { + fsr_info[nr].fn = fn; + fsr_info[nr].sig = sig; + fsr_info[nr].name = name; + } +} + +/* + * Dispatch a data abort to the relevant handler. + */ +asmlinkage void +do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); + + if (!inf->fn(addr, fsr, regs)) + return; + + printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", + inf->name, fsr, addr); + force_sig(inf->sig, current); + show_pte(current->mm, addr); + die_if_kernel("Oops", regs, 0); +} + +asmlinkage void +do_PrefetchAbort(unsigned long addr, struct pt_regs *regs) +{ + do_translation_fault(addr, 0, regs); +} + diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h new file mode 100644 index 0000000..73b59e8 --- /dev/null +++ b/arch/arm/mm/fault.h @@ -0,0 +1,6 @@ +void do_bad_area(struct task_struct *tsk, struct mm_struct *mm, + unsigned long addr, unsigned int fsr, struct pt_regs *regs); + +void show_pte(struct mm_struct *mm, unsigned long addr); + +unsigned long search_exception_table(unsigned long addr); diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c new file mode 100644 index 0000000..c6de48d --- /dev/null +++ b/arch/arm/mm/flush.c @@ -0,0 +1,94 @@ +/* + * linux/arch/arm/mm/flush.c + * + * Copyright (C) 1995-2002 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/module.h> +#include <linux/mm.h> +#include <linux/pagemap.h> + +#include <asm/cacheflush.h> +#include <asm/system.h> + +static void __flush_dcache_page(struct address_space *mapping, struct page *page) +{ + struct mm_struct *mm = current->active_mm; + struct vm_area_struct *mpnt; + struct prio_tree_iter iter; + pgoff_t pgoff; + + /* + * Writeback any data associated with the kernel mapping of this + * page. This ensures that data in the physical page is mutually + * coherent with the kernels mapping. + */ + __cpuc_flush_dcache_page(page_address(page)); + + /* + * If there's no mapping pointer here, then this page isn't + * visible to userspace yet, so there are no cache lines + * associated with any other aliases. + */ + if (!mapping) + return; + + /* + * There are possible user space mappings of this page: + * - VIVT cache: we need to also write back and invalidate all user + * data in the current VM view associated with this page. + * - aliasing VIPT: we only need to find one mapping of this page. + */ + pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); + + flush_dcache_mmap_lock(mapping); + vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) { + unsigned long offset; + + /* + * If this VMA is not in our MM, we can ignore it. + */ + if (mpnt->vm_mm != mm) + continue; + if (!(mpnt->vm_flags & VM_MAYSHARE)) + continue; + offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; + flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page)); + if (cache_is_vipt()) + break; + } + flush_dcache_mmap_unlock(mapping); +} + +/* + * Ensure cache coherency between kernel mapping and userspace mapping + * of this page. + * + * We have three cases to consider: + * - VIPT non-aliasing cache: fully coherent so nothing required. + * - VIVT: fully aliasing, so we need to handle every alias in our + * current VM view. + * - VIPT aliasing: need to handle one alias in our current VM view. + * + * If we need to handle aliasing: + * If the page only exists in the page cache and there are no user + * space mappings, we can be lazy and remember that we may have dirty + * kernel cache lines for later. Otherwise, we assume we have + * aliasing mappings. + */ +void flush_dcache_page(struct page *page) +{ + struct address_space *mapping = page_mapping(page); + + if (cache_is_vipt_nonaliasing()) + return; + + if (mapping && !mapping_mapped(mapping)) + set_bit(PG_dcache_dirty, &page->flags); + else + __flush_dcache_page(mapping, page); +} +EXPORT_SYMBOL(flush_dcache_page); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c new file mode 100644 index 0000000..41156c5 --- /dev/null +++ b/arch/arm/mm/init.c @@ -0,0 +1,621 @@ +/* + * linux/arch/arm/mm/init.c + * + * Copyright (C) 1995-2002 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/kernel.h> +#include <linux/errno.h> +#include <linux/ptrace.h> +#include <linux/swap.h> +#include <linux/init.h> +#include <linux/bootmem.h> +#include <linux/mman.h> +#include <linux/nodemask.h> +#include <linux/initrd.h> + +#include <asm/mach-types.h> +#include <asm/hardware.h> +#include <asm/setup.h> +#include <asm/tlb.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#define TABLE_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t)) + +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern void _stext, _text, _etext, __data_start, _end, __init_begin, __init_end; +extern unsigned long phys_initrd_start; +extern unsigned long phys_initrd_size; + +/* + * The sole use of this is to pass memory configuration + * data from paging_init to mem_init. + */ +static struct meminfo meminfo __initdata = { 0, }; + +/* + * empty_zero_page is a special page that is used for + * zero-initialized data and COW. + */ +struct page *empty_zero_page; + +void show_mem(void) +{ + int free = 0, total = 0, reserved = 0; + int shared = 0, cached = 0, slab = 0, node; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + + for_each_online_node(node) { + struct page *page, *end; + + page = NODE_MEM_MAP(node); + end = page + NODE_DATA(node)->node_spanned_pages; + + do { + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (PageSlab(page)) + slab++; + else if (!page_count(page)) + free++; + else + shared += page_count(page) - 1; + page++; + } while (page < end); + } + + printk("%d pages of RAM\n", total); + printk("%d free pages\n", free); + printk("%d reserved pages\n", reserved); + printk("%d slab pages\n", slab); + printk("%d pages shared\n", shared); + printk("%d pages swap cached\n", cached); +} + +struct node_info { + unsigned int start; + unsigned int end; + int bootmap_pages; +}; + +#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x)) + +#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT) +#define V_PFN_UP(x) O_PFN_UP(__pa(x)) + +#define PFN_SIZE(x) ((x) >> PAGE_SHIFT) +#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \ + (((unsigned long)(s)) & PAGE_MASK)) + +/* + * FIXME: We really want to avoid allocating the bootmap bitmap + * over the top of the initrd. Hopefully, this is located towards + * the start of a bank, so if we allocate the bootmap bitmap at + * the end, we won't clash. + */ +static unsigned int __init +find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages) +{ + unsigned int start_pfn, bank, bootmap_pfn; + + start_pfn = V_PFN_UP(&_end); + bootmap_pfn = 0; + + for (bank = 0; bank < mi->nr_banks; bank ++) { + unsigned int start, end; + + if (mi->bank[bank].node != node) + continue; + + start = O_PFN_UP(mi->bank[bank].start); + end = O_PFN_DOWN(mi->bank[bank].size + + mi->bank[bank].start); + + if (end < start_pfn) + continue; + + if (start < start_pfn) + start = start_pfn; + + if (end <= start) + continue; + + if (end - start >= bootmap_pages) { + bootmap_pfn = start; + break; + } + } + + if (bootmap_pfn == 0) + BUG(); + + return bootmap_pfn; +} + +/* + * Scan the memory info structure and pull out: + * - the end of memory + * - the number of nodes + * - the pfn range of each node + * - the number of bootmem bitmap pages + */ +static unsigned int __init +find_memend_and_nodes(struct meminfo *mi, struct node_info *np) +{ + unsigned int i, bootmem_pages = 0, memend_pfn = 0; + + for (i = 0; i < MAX_NUMNODES; i++) { + np[i].start = -1U; + np[i].end = 0; + np[i].bootmap_pages = 0; + } + + for (i = 0; i < mi->nr_banks; i++) { + unsigned long start, end; + int node; + + if (mi->bank[i].size == 0) { + /* + * Mark this bank with an invalid node number + */ + mi->bank[i].node = -1; + continue; + } + + node = mi->bank[i].node; + + /* + * Make sure we haven't exceeded the maximum number of nodes + * that we have in this configuration. If we have, we're in + * trouble. (maybe we ought to limit, instead of bugging?) + */ + if (node >= MAX_NUMNODES) + BUG(); + node_set_online(node); + + /* + * Get the start and end pfns for this bank + */ + start = O_PFN_UP(mi->bank[i].start); + end = O_PFN_DOWN(mi->bank[i].start + mi->bank[i].size); + + if (np[node].start > start) + np[node].start = start; + + if (np[node].end < end) + np[node].end = end; + + if (memend_pfn < end) + memend_pfn = end; + } + + /* + * Calculate the number of pages we require to + * store the bootmem bitmaps. + */ + for_each_online_node(i) { + if (np[i].end == 0) + continue; + + np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end - + np[i].start); + bootmem_pages += np[i].bootmap_pages; + } + + high_memory = __va(memend_pfn << PAGE_SHIFT); + + /* + * This doesn't seem to be used by the Linux memory + * manager any more. If we can get rid of it, we + * also get rid of some of the stuff above as well. + */ + max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET); + max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET); + + return bootmem_pages; +} + +static int __init check_initrd(struct meminfo *mi) +{ + int initrd_node = -2; +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long end = phys_initrd_start + phys_initrd_size; + + /* + * Make sure that the initrd is within a valid area of + * memory. + */ + if (phys_initrd_size) { + unsigned int i; + + initrd_node = -1; + + for (i = 0; i < mi->nr_banks; i++) { + unsigned long bank_end; + + bank_end = mi->bank[i].start + mi->bank[i].size; + + if (mi->bank[i].start <= phys_initrd_start && + end <= bank_end) + initrd_node = mi->bank[i].node; + } + } + + if (initrd_node == -1) { + printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond " + "physical memory - disabling initrd\n", + phys_initrd_start, end); + phys_initrd_start = phys_initrd_size = 0; + } +#endif + + return initrd_node; +} + +/* + * Reserve the various regions of node 0 + */ +static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages) +{ + pg_data_t *pgdat = NODE_DATA(0); + unsigned long res_size = 0; + + /* + * Register the kernel text and data with bootmem. + * Note that this can only be in node 0. + */ +#ifdef CONFIG_XIP_KERNEL + reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); +#else + reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); +#endif + + /* + * Reserve the page tables. These are already in use, + * and can only be in node 0. + */ + reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), + PTRS_PER_PGD * sizeof(pgd_t)); + + /* + * And don't forget to reserve the allocator bitmap, + * which will be freed later. + */ + reserve_bootmem_node(pgdat, bootmap_pfn << PAGE_SHIFT, + bootmap_pages << PAGE_SHIFT); + + /* + * Hmm... This should go elsewhere, but we really really need to + * stop things allocating the low memory; ideally we need a better + * implementation of GFP_DMA which does not assume that DMA-able + * memory starts at zero. + */ + if (machine_is_integrator() || machine_is_cintegrator()) + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + + /* + * These should likewise go elsewhere. They pre-reserve the + * screen memory region at the start of main system memory. + */ + if (machine_is_edb7211()) + res_size = 0x00020000; + if (machine_is_p720t()) + res_size = 0x00014000; + +#ifdef CONFIG_SA1111 + /* + * Because of the SA1111 DMA bug, we want to preserve our + * precious DMA-able memory... + */ + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; +#endif + if (res_size) + reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); +} + +/* + * Register all available RAM in this node with the bootmem allocator. + */ +static inline void free_bootmem_node_bank(int node, struct meminfo *mi) +{ + pg_data_t *pgdat = NODE_DATA(node); + int bank; + + for (bank = 0; bank < mi->nr_banks; bank++) + if (mi->bank[bank].node == node) + free_bootmem_node(pgdat, mi->bank[bank].start, + mi->bank[bank].size); +} + +/* + * Initialise the bootmem allocator for all nodes. This is called + * early during the architecture specific initialisation. + */ +static void __init bootmem_init(struct meminfo *mi) +{ + struct node_info node_info[MAX_NUMNODES], *np = node_info; + unsigned int bootmap_pages, bootmap_pfn, map_pg; + int node, initrd_node; + + bootmap_pages = find_memend_and_nodes(mi, np); + bootmap_pfn = find_bootmap_pfn(0, mi, bootmap_pages); + initrd_node = check_initrd(mi); + + map_pg = bootmap_pfn; + + /* + * Initialise the bootmem nodes. + * + * What we really want to do is: + * + * unmap_all_regions_except_kernel(); + * for_each_node_in_reverse_order(node) { + * map_node(node); + * allocate_bootmem_map(node); + * init_bootmem_node(node); + * free_bootmem_node(node); + * } + * + * but this is a 2.5-type change. For now, we just set + * the nodes up in reverse order. + * + * (we could also do with rolling bootmem_init and paging_init + * into one generic "memory_init" type function). + */ + np += num_online_nodes() - 1; + for (node = num_online_nodes() - 1; node >= 0; node--, np--) { + /* + * If there are no pages in this node, ignore it. + * Note that node 0 must always have some pages. + */ + if (np->end == 0 || !node_online(node)) { + if (node == 0) + BUG(); + continue; + } + + /* + * Initialise the bootmem allocator. + */ + init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end); + free_bootmem_node_bank(node, mi); + map_pg += np->bootmap_pages; + + /* + * If this is node 0, we need to reserve some areas ASAP - + * we may use bootmem on node 0 to setup the other nodes. + */ + if (node == 0) + reserve_node_zero(bootmap_pfn, bootmap_pages); + } + + +#ifdef CONFIG_BLK_DEV_INITRD + if (phys_initrd_size && initrd_node >= 0) { + reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start, + phys_initrd_size); + initrd_start = __phys_to_virt(phys_initrd_start); + initrd_end = initrd_start + phys_initrd_size; + } +#endif + + BUG_ON(map_pg != bootmap_pfn + bootmap_pages); +} + +/* + * paging_init() sets up the page tables, initialises the zone memory + * maps, and sets up the zero page, bad page and bad page tables. + */ +void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) +{ + void *zero_page; + int node; + + bootmem_init(mi); + + memcpy(&meminfo, mi, sizeof(meminfo)); + + /* + * allocate the zero page. Note that we count on this going ok. + */ + zero_page = alloc_bootmem_low_pages(PAGE_SIZE); + + /* + * initialise the page tables. + */ + memtable_init(mi); + if (mdesc->map_io) + mdesc->map_io(); + flush_tlb_all(); + + /* + * initialise the zones within each node + */ + for_each_online_node(node) { + unsigned long zone_size[MAX_NR_ZONES]; + unsigned long zhole_size[MAX_NR_ZONES]; + struct bootmem_data *bdata; + pg_data_t *pgdat; + int i; + + /* + * Initialise the zone size information. + */ + for (i = 0; i < MAX_NR_ZONES; i++) { + zone_size[i] = 0; + zhole_size[i] = 0; + } + + pgdat = NODE_DATA(node); + bdata = pgdat->bdata; + + /* + * The size of this node has already been determined. + * If we need to do anything fancy with the allocation + * of this memory to the zones, now is the time to do + * it. + */ + zone_size[0] = bdata->node_low_pfn - + (bdata->node_boot_start >> PAGE_SHIFT); + + /* + * If this zone has zero size, skip it. + */ + if (!zone_size[0]) + continue; + + /* + * For each bank in this node, calculate the size of the + * holes. holes = node_size - sum(bank_sizes_in_node) + */ + zhole_size[0] = zone_size[0]; + for (i = 0; i < mi->nr_banks; i++) { + if (mi->bank[i].node != node) + continue; + + zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT; + } + + /* + * Adjust the sizes according to any special + * requirements for this machine type. + */ + arch_adjust_zones(node, zone_size, zhole_size); + + free_area_init_node(node, pgdat, zone_size, + bdata->node_boot_start >> PAGE_SHIFT, zhole_size); + } + + /* + * finish off the bad pages once + * the mem_map is initialised + */ + memzero(zero_page, PAGE_SIZE); + empty_zero_page = virt_to_page(zero_page); + flush_dcache_page(empty_zero_page); +} + +static inline void free_area(unsigned long addr, unsigned long end, char *s) +{ + unsigned int size = (end - addr) >> 10; + + for (; addr < end; addr += PAGE_SIZE) { + struct page *page = virt_to_page(addr); + ClearPageReserved(page); + set_page_count(page, 1); + free_page(addr); + totalram_pages++; + } + + if (size && s) + printk(KERN_INFO "Freeing %s memory: %dK\n", s, size); +} + +/* + * mem_init() marks the free areas in the mem_map and tells us how much + * memory is free. This is done after various parts of the system have + * claimed their memory after the kernel image. + */ +void __init mem_init(void) +{ + unsigned int codepages, datapages, initpages; + int i, node; + + codepages = &_etext - &_text; + datapages = &_end - &__data_start; + initpages = &__init_end - &__init_begin; + +#ifndef CONFIG_DISCONTIGMEM + max_mapnr = virt_to_page(high_memory) - mem_map; +#endif + + /* + * We may have non-contiguous memory. + */ + if (meminfo.nr_banks != 1) + create_memmap_holes(&meminfo); + + /* this will put all unused low memory onto the freelists */ + for_each_online_node(node) { + pg_data_t *pgdat = NODE_DATA(node); + + if (pgdat->node_spanned_pages != 0) + totalram_pages += free_all_bootmem_node(pgdat); + } + +#ifdef CONFIG_SA1111 + /* now that our DMA memory is actually so designated, we can free it */ + free_area(PAGE_OFFSET, (unsigned long)swapper_pg_dir, NULL); +#endif + + /* + * Since our memory may not be contiguous, calculate the + * real number of pages we have in this system + */ + printk(KERN_INFO "Memory:"); + + num_physpages = 0; + for (i = 0; i < meminfo.nr_banks; i++) { + num_physpages += meminfo.bank[i].size >> PAGE_SHIFT; + printk(" %ldMB", meminfo.bank[i].size >> 20); + } + + printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); + printk(KERN_NOTICE "Memory: %luKB available (%dK code, " + "%dK data, %dK init)\n", + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), + codepages >> 10, datapages >> 10, initpages >> 10); + + if (PAGE_SIZE >= 16384 && num_physpages <= 128) { + extern int sysctl_overcommit_memory; + /* + * On a machine this small we won't get + * anywhere without overcommit, so turn + * it on by default. + */ + sysctl_overcommit_memory = OVERCOMMIT_ALWAYS; + } +} + +void free_initmem(void) +{ + if (!machine_is_integrator() && !machine_is_cintegrator()) { + free_area((unsigned long)(&__init_begin), + (unsigned long)(&__init_end), + "init"); + } +} + +#ifdef CONFIG_BLK_DEV_INITRD + +static int keep_initrd; + +void free_initrd_mem(unsigned long start, unsigned long end) +{ + if (!keep_initrd) + free_area(start, end, "initrd"); +} + +static int __init keepinitrd_setup(char *__unused) +{ + keep_initrd = 1; + return 1; +} + +__setup("keepinitrd", keepinitrd_setup); +#endif diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c new file mode 100644 index 0000000..00bb8fd --- /dev/null +++ b/arch/arm/mm/ioremap.c @@ -0,0 +1,172 @@ +/* + * linux/arch/arm/mm/ioremap.c + * + * Re-map IO memory to kernel address space so that we can access it. + * + * (C) Copyright 1995 1996 Linus Torvalds + * + * Hacked for ARM by Phil Blundell <philb@gnu.org> + * Hacked to allow all architectures to build, and various cleanups + * by Russell King + * + * This allows a driver to remap an arbitrary region of bus memory into + * virtual space. One should *only* use readl, writel, memcpy_toio and + * so on with such remapped areas. + * + * Because the ARM only has a 32-bit address space we can't address the + * whole of the (physical) PCI space at once. PCI huge-mode addressing + * allows us to circumvent this restriction by splitting PCI space into + * two 2GB chunks and mapping only one at a time into processor memory. + * We use MMU protection domains to trap any attempt to access the bank + * that is not currently mapped. (This isn't fully implemented yet.) + */ +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> + +#include <asm/cacheflush.h> +#include <asm/io.h> +#include <asm/tlbflush.h> + +static inline void +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, pgprot_t pgprot) +{ + unsigned long end; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + BUG_ON(address >= end); + do { + if (!pte_none(*pte)) + goto bad; + + set_pte(pte, pfn_pte(phys_addr >> PAGE_SHIFT, pgprot)); + address += PAGE_SIZE; + phys_addr += PAGE_SIZE; + pte++; + } while (address && (address < end)); + return; + + bad: + printk("remap_area_pte: page already exists\n"); + BUG(); +} + +static inline int +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + pgprot_t pgprot; + + address &= ~PGDIR_MASK; + end = address + size; + + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + + phys_addr -= address; + BUG_ON(address >= end); + + pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags); + do { + pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, pgprot); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int +remap_area_pages(unsigned long start, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + unsigned long address = start; + unsigned long end = start + size; + int err = 0; + pgd_t * dir; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + BUG_ON(address >= end); + spin_lock(&init_mm.page_table_lock); + do { + pmd_t *pmd = pmd_alloc(&init_mm, dir, address); + if (!pmd) { + err = -ENOMEM; + break; + } + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) { + err = -ENOMEM; + break; + } + + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + + spin_unlock(&init_mm.page_table_lock); + flush_cache_vmap(start, end); + return err; +} + +/* + * Remap an arbitrary physical address space into the kernel virtual + * address space. Needed when the kernel wants to access high addresses + * directly. + * + * NOTE! We need to allow non-page-aligned mappings too: we will obviously + * have to convert them into an offset in a page-aligned mapping, but the + * caller shouldn't need to know that small detail. + * + * 'flags' are the extra L_PTE_ flags that you want to specify for this + * mapping. See include/asm-arm/proc-armv/pgtable.h for more information. + */ +void __iomem * +__ioremap(unsigned long phys_addr, size_t size, unsigned long flags, + unsigned long align) +{ + void * addr; + struct vm_struct * area; + unsigned long offset, last_addr; + + /* Don't allow wraparound or zero size */ + last_addr = phys_addr + size - 1; + if (!size || last_addr < phys_addr) + return NULL; + + /* + * Mappings have to be page-aligned + */ + offset = phys_addr & ~PAGE_MASK; + phys_addr &= PAGE_MASK; + size = PAGE_ALIGN(last_addr + 1) - phys_addr; + + /* + * Ok, go for it.. + */ + area = get_vm_area(size, VM_IOREMAP); + if (!area) + return NULL; + addr = area->addr; + if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { + vfree(addr); + return NULL; + } + return (void __iomem *) (offset + (char *)addr); +} +EXPORT_SYMBOL(__ioremap); + +void __iounmap(void __iomem *addr) +{ + vfree((void *) (PAGE_MASK & (unsigned long) addr)); +} +EXPORT_SYMBOL(__iounmap); diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c new file mode 100644 index 0000000..dedf2ab --- /dev/null +++ b/arch/arm/mm/minicache.c @@ -0,0 +1,73 @@ +/* + * linux/arch/arm/mm/minicache.c + * + * Copyright (C) 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. + * + * This handles the mini data cache, as found on SA11x0 and XScale + * processors. When we copy a user page page, we map it in such a way + * that accesses to this page will not touch the main data cache, but + * will be cached in the mini data cache. This prevents us thrashing + * the main data cache on page faults. + */ +#include <linux/init.h> +#include <linux/mm.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> + +/* + * 0xffff8000 to 0xffffffff is reserved for any ARM architecture + * specific hacks for copying pages efficiently. + */ +#define minicache_address (0xffff8000) +#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ + L_PTE_CACHEABLE) + +static pte_t *minicache_pte; + +/* + * Note that this is intended to be called only from the copy_user_page + * asm code; anything else will require special locking to prevent the + * mini-cache space being re-used. (Note: probably preempt unsafe). + * + * We rely on the fact that the minicache is 2K, and we'll be pushing + * 4K of data through it, so we don't actually have to specifically + * flush the minicache when we change the mapping. + * + * Note also: assert(PAGE_OFFSET <= virt < high_memory). + * Unsafe: preempt, kmap. + */ +unsigned long map_page_minicache(unsigned long virt) +{ + set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot)); + flush_tlb_kernel_page(minicache_address); + + return minicache_address; +} + +static int __init minicache_init(void) +{ + pgd_t *pgd; + pmd_t *pmd; + + spin_lock(&init_mm.page_table_lock); + + pgd = pgd_offset_k(minicache_address); + pmd = pmd_alloc(&init_mm, pgd, minicache_address); + if (!pmd) + BUG(); + minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address); + if (!minicache_pte) + BUG(); + + spin_unlock(&init_mm.page_table_lock); + + return 0; +} + +core_initcall(minicache_init); diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c new file mode 100644 index 0000000..f5a87db8 --- /dev/null +++ b/arch/arm/mm/mm-armv.c @@ -0,0 +1,760 @@ +/* + * linux/arch/arm/mm/mm-armv.c + * + * Copyright (C) 1998-2002 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. + * + * Page table sludge for ARM v3 and v4 processor architectures. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/bootmem.h> +#include <linux/highmem.h> +#include <linux/nodemask.h> + +#include <asm/pgalloc.h> +#include <asm/page.h> +#include <asm/io.h> +#include <asm/setup.h> +#include <asm/tlbflush.h> + +#include <asm/mach/map.h> + +#define CPOLICY_UNCACHED 0 +#define CPOLICY_BUFFERED 1 +#define CPOLICY_WRITETHROUGH 2 +#define CPOLICY_WRITEBACK 3 +#define CPOLICY_WRITEALLOC 4 + +static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; +static unsigned int ecc_mask __initdata = 0; +pgprot_t pgprot_kernel; + +EXPORT_SYMBOL(pgprot_kernel); + +struct cachepolicy { + const char policy[16]; + unsigned int cr_mask; + unsigned int pmd; + unsigned int pte; +}; + +static struct cachepolicy cache_policies[] __initdata = { + { + .policy = "uncached", + .cr_mask = CR_W|CR_C, + .pmd = PMD_SECT_UNCACHED, + .pte = 0, + }, { + .policy = "buffered", + .cr_mask = CR_C, + .pmd = PMD_SECT_BUFFERED, + .pte = PTE_BUFFERABLE, + }, { + .policy = "writethrough", + .cr_mask = 0, + .pmd = PMD_SECT_WT, + .pte = PTE_CACHEABLE, + }, { + .policy = "writeback", + .cr_mask = 0, + .pmd = PMD_SECT_WB, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + }, { + .policy = "writealloc", + .cr_mask = 0, + .pmd = PMD_SECT_WBWA, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + } +}; + +/* + * These are useful for identifing cache coherency + * problems by allowing the cache or the cache and + * writebuffer to be turned off. (Note: the write + * buffer should not be on and the cache off). + */ +static void __init early_cachepolicy(char **p) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cache_policies); i++) { + int len = strlen(cache_policies[i].policy); + + if (memcmp(*p, cache_policies[i].policy, len) == 0) { + cachepolicy = i; + cr_alignment &= ~cache_policies[i].cr_mask; + cr_no_alignment &= ~cache_policies[i].cr_mask; + *p += len; + break; + } + } + if (i == ARRAY_SIZE(cache_policies)) + printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); + flush_cache_all(); + set_cr(cr_alignment); +} + +static void __init early_nocache(char **__unused) +{ + char *p = "buffered"; + printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); + early_cachepolicy(&p); +} + +static void __init early_nowrite(char **__unused) +{ + char *p = "uncached"; + printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); + early_cachepolicy(&p); +} + +static void __init early_ecc(char **p) +{ + if (memcmp(*p, "on", 2) == 0) { + ecc_mask = PMD_PROTECTION; + *p += 2; + } else if (memcmp(*p, "off", 3) == 0) { + ecc_mask = 0; + *p += 3; + } +} + +__early_param("nocache", early_nocache); +__early_param("nowb", early_nowrite); +__early_param("cachepolicy=", early_cachepolicy); +__early_param("ecc=", early_ecc); + +static int __init noalign_setup(char *__unused) +{ + cr_alignment &= ~CR_A; + cr_no_alignment &= ~CR_A; + set_cr(cr_alignment); + return 1; +} + +__setup("noalign", noalign_setup); + +#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) + +/* + * need to get a 16k page for level 1 + */ +pgd_t *get_pgd_slow(struct mm_struct *mm) +{ + pgd_t *new_pgd, *init_pgd; + pmd_t *new_pmd, *init_pmd; + pte_t *new_pte, *init_pte; + + new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); + if (!new_pgd) + goto no_pgd; + + memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); + + init_pgd = pgd_offset_k(0); + + if (!vectors_high()) { + /* + * This lock is here just to satisfy pmd_alloc and pte_lock + */ + spin_lock(&mm->page_table_lock); + + /* + * On ARM, first page must always be allocated since it + * contains the machine vectors. + */ + new_pmd = pmd_alloc(mm, new_pgd, 0); + if (!new_pmd) + goto no_pmd; + + new_pte = pte_alloc_map(mm, new_pmd, 0); + if (!new_pte) + goto no_pte; + + init_pmd = pmd_offset(init_pgd, 0); + init_pte = pte_offset_map_nested(init_pmd, 0); + set_pte(new_pte, *init_pte); + pte_unmap_nested(init_pte); + pte_unmap(new_pte); + + spin_unlock(&mm->page_table_lock); + } + + /* + * Copy over the kernel and IO PGD entries + */ + memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, + (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + + clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); + + return new_pgd; + +no_pte: + spin_unlock(&mm->page_table_lock); + pmd_free(new_pmd); + free_pages((unsigned long)new_pgd, 2); + return NULL; + +no_pmd: + spin_unlock(&mm->page_table_lock); + free_pages((unsigned long)new_pgd, 2); + return NULL; + +no_pgd: + return NULL; +} + +void free_pgd_slow(pgd_t *pgd) +{ + pmd_t *pmd; + struct page *pte; + + if (!pgd) + return; + + /* pgd is always present and good */ + pmd = (pmd_t *)pgd; + if (pmd_none(*pmd)) + goto free; + if (pmd_bad(*pmd)) { + pmd_ERROR(*pmd); + pmd_clear(pmd); + goto free; + } + + pte = pmd_page(*pmd); + pmd_clear(pmd); + dec_page_state(nr_page_table_pages); + pte_free(pte); + pmd_free(pmd); +free: + free_pages((unsigned long) pgd, 2); +} + +/* + * Create a SECTION PGD between VIRT and PHYS in domain + * DOMAIN with protection PROT. This operates on half- + * pgdir entry increments. + */ +static inline void +alloc_init_section(unsigned long virt, unsigned long phys, int prot) +{ + pmd_t *pmdp; + + pmdp = pmd_offset(pgd_offset_k(virt), virt); + if (virt & (1 << 20)) + pmdp++; + + *pmdp = __pmd(phys | prot); + flush_pmd_entry(pmdp); +} + +/* + * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT + */ +static inline void +alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) +{ + int i; + + for (i = 0; i < 16; i += 1) { + alloc_init_section(virt, phys & SUPERSECTION_MASK, + prot | PMD_SECT_SUPER); + + virt += (PGDIR_SIZE / 2); + phys += (PGDIR_SIZE / 2); + } +} + +/* + * Add a PAGE mapping between VIRT and PHYS in domain + * DOMAIN with protection PROT. Note that due to the + * way we map the PTEs, we must allocate two PTE_SIZE'd + * blocks - one for the Linux pte table, and one for + * the hardware pte table. + */ +static inline void +alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) +{ + pmd_t *pmdp; + pte_t *ptep; + + pmdp = pmd_offset(pgd_offset_k(virt), virt); + + if (pmd_none(*pmdp)) { + unsigned long pmdval; + ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * + sizeof(pte_t)); + + pmdval = __pa(ptep) | prot_l1; + pmdp[0] = __pmd(pmdval); + pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); + flush_pmd_entry(pmdp); + } + ptep = pte_offset_kernel(pmdp, virt); + + set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); +} + +/* + * Clear any PGD mapping. On a two-level page table system, + * the clearance is done by the middle-level functions (pmd) + * rather than the top-level (pgd) functions. + */ +static inline void clear_mapping(unsigned long virt) +{ + pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); +} + +struct mem_types { + unsigned int prot_pte; + unsigned int prot_l1; + unsigned int prot_sect; + unsigned int domain; +}; + +static struct mem_types mem_types[] __initdata = { + [MT_DEVICE] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, + }, + [MT_CACHECLEAN] = { + .prot_sect = PMD_TYPE_SECT, + .domain = DOMAIN_KERNEL, + }, + [MT_MINICLEAN] = { + .prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE, + .domain = DOMAIN_KERNEL, + }, + [MT_LOW_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, + [MT_HIGH_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_USER | L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, + [MT_MEMORY] = { + .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, + .domain = DOMAIN_KERNEL, + }, + [MT_ROM] = { + .prot_sect = PMD_TYPE_SECT, + .domain = DOMAIN_KERNEL, + }, + [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | + PMD_SECT_TEX(1), + .domain = DOMAIN_IO, + } +}; + +/* + * Adjust the PMD section entries according to the CPU in use. + */ +static void __init build_mem_type_table(void) +{ + struct cachepolicy *cp; + unsigned int cr = get_cr(); + int cpu_arch = cpu_architecture(); + int i; + +#if defined(CONFIG_CPU_DCACHE_DISABLE) + if (cachepolicy > CPOLICY_BUFFERED) + cachepolicy = CPOLICY_BUFFERED; +#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) + if (cachepolicy > CPOLICY_WRITETHROUGH) + cachepolicy = CPOLICY_WRITETHROUGH; +#endif + if (cpu_arch < CPU_ARCH_ARMv5) { + if (cachepolicy >= CPOLICY_WRITEALLOC) + cachepolicy = CPOLICY_WRITEBACK; + ecc_mask = 0; + } + + if (cpu_arch <= CPU_ARCH_ARMv5) { + for (i = 0; i < ARRAY_SIZE(mem_types); i++) { + if (mem_types[i].prot_l1) + mem_types[i].prot_l1 |= PMD_BIT4; + if (mem_types[i].prot_sect) + mem_types[i].prot_sect |= PMD_BIT4; + } + } + + /* + * ARMv6 and above have extended page tables. + */ + if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { + /* + * bit 4 becomes XN which we must clear for the + * kernel memory mapping. + */ + mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; + mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; + /* + * Mark cache clean areas read only from SVC mode + * and no access from userspace. + */ + mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + } + + cp = &cache_policies[cachepolicy]; + + if (cpu_arch >= CPU_ARCH_ARMv5) { + mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; + mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; + } else { + mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte; + mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte; + mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); + } + + mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; + mem_types[MT_ROM].prot_sect |= cp->pmd; + + for (i = 0; i < 16; i++) { + unsigned long v = pgprot_val(protection_map[i]); + v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte; + protection_map[i] = __pgprot(v); + } + + pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | + L_PTE_DIRTY | L_PTE_WRITE | + L_PTE_EXEC | cp->pte); + + switch (cp->pmd) { + case PMD_SECT_WT: + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; + break; + case PMD_SECT_WB: + case PMD_SECT_WBWA: + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; + break; + } + printk("Memory policy: ECC %sabled, Data cache %s\n", + ecc_mask ? "en" : "dis", cp->policy); +} + +#define vectors_base() (vectors_high() ? 0xffff0000 : 0) + +/* + * Create the page directory entries and any necessary + * page tables for the mapping specified by `md'. We + * are able to cope here with varying sizes and address + * offsets, and we take full advantage of sections and + * supersections. + */ +static void __init create_mapping(struct map_desc *md) +{ + unsigned long virt, length; + int prot_sect, prot_l1, domain; + pgprot_t prot_pte; + long off; + + if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { + printk(KERN_WARNING "BUG: not creating mapping for " + "0x%08lx at 0x%08lx in user region\n", + md->physical, md->virtual); + return; + } + + if ((md->type == MT_DEVICE || md->type == MT_ROM) && + md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { + printk(KERN_WARNING "BUG: mapping for 0x%08lx at 0x%08lx " + "overlaps vmalloc space\n", + md->physical, md->virtual); + } + + domain = mem_types[md->type].domain; + prot_pte = __pgprot(mem_types[md->type].prot_pte); + prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); + prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); + + virt = md->virtual; + off = md->physical - virt; + length = md->length; + + if (mem_types[md->type].prot_l1 == 0 && + (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { + printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " + "be mapped using pages, ignoring.\n", + md->physical, md->virtual); + return; + } + + while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } + + /* N.B. ARMv6 supersections are only defined to work with domain 0. + * Since domain assignments can in fact be arbitrary, the + * 'domain == 0' check below is required to insure that ARMv6 + * supersections are only allocated for domain 0 regardless + * of the actual domain assignments in use. + */ + if (cpu_architecture() >= CPU_ARCH_ARMv6 && domain == 0) { + /* Align to supersection boundary */ + while ((virt & ~SUPERSECTION_MASK || (virt + off) & + ~SUPERSECTION_MASK) && length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + + while (length >= SUPERSECTION_SIZE) { + alloc_init_supersection(virt, virt + off, prot_sect); + + virt += SUPERSECTION_SIZE; + length -= SUPERSECTION_SIZE; + } + } + + /* + * A section mapping covers half a "pgdir" entry. + */ + while (length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + + while (length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } +} + +/* + * In order to soft-boot, we need to insert a 1:1 mapping in place of + * the user-mode pages. This will then ensure that we have predictable + * results when turning the mmu off + */ +void setup_mm_for_reboot(char mode) +{ + unsigned long pmdval; + pgd_t *pgd; + pmd_t *pmd; + int i; + int cpu_arch = cpu_architecture(); + + if (current->mm && current->mm->pgd) + pgd = current->mm->pgd; + else + pgd = init_mm.pgd; + + for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++) { + pmdval = (i << PGDIR_SHIFT) | + PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | + PMD_TYPE_SECT; + if (cpu_arch <= CPU_ARCH_ARMv5) + pmdval |= PMD_BIT4; + pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT); + pmd[0] = __pmd(pmdval); + pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); + flush_pmd_entry(pmd); + } +} + +extern void _stext, _etext; + +/* + * Setup initial mappings. We use the page we allocated for zero page to hold + * the mappings, which will get overwritten by the vectors in traps_init(). + * The mappings must be in virtual address order. + */ +void __init memtable_init(struct meminfo *mi) +{ + struct map_desc *init_maps, *p, *q; + unsigned long address = 0; + int i; + + build_mem_type_table(); + + init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE); + +#ifdef CONFIG_XIP_KERNEL + p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK; + p->virtual = (unsigned long)&_stext & PMD_MASK; + p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK; + p->type = MT_ROM; + p ++; +#endif + + for (i = 0; i < mi->nr_banks; i++) { + if (mi->bank[i].size == 0) + continue; + + p->physical = mi->bank[i].start; + p->virtual = __phys_to_virt(p->physical); + p->length = mi->bank[i].size; + p->type = MT_MEMORY; + p ++; + } + +#ifdef FLUSH_BASE + p->physical = FLUSH_BASE_PHYS; + p->virtual = FLUSH_BASE; + p->length = PGDIR_SIZE; + p->type = MT_CACHECLEAN; + p ++; +#endif + +#ifdef FLUSH_BASE_MINICACHE + p->physical = FLUSH_BASE_PHYS + PGDIR_SIZE; + p->virtual = FLUSH_BASE_MINICACHE; + p->length = PGDIR_SIZE; + p->type = MT_MINICLEAN; + p ++; +#endif + + /* + * Go through the initial mappings, but clear out any + * pgdir entries that are not in the description. + */ + q = init_maps; + do { + if (address < q->virtual || q == p) { + clear_mapping(address); + address += PGDIR_SIZE; + } else { + create_mapping(q); + + address = q->virtual + q->length; + address = (address + PGDIR_SIZE - 1) & PGDIR_MASK; + + q ++; + } + } while (address != 0); + + /* + * Create a mapping for the machine vectors at the high-vectors + * location (0xffff0000). If we aren't using high-vectors, also + * create a mapping at the low-vectors virtual address. + */ + init_maps->physical = virt_to_phys(init_maps); + init_maps->virtual = 0xffff0000; + init_maps->length = PAGE_SIZE; + init_maps->type = MT_HIGH_VECTORS; + create_mapping(init_maps); + + if (!vectors_high()) { + init_maps->virtual = 0; + init_maps->type = MT_LOW_VECTORS; + create_mapping(init_maps); + } + + flush_cache_all(); + flush_tlb_all(); +} + +/* + * Create the architecture specific mappings + */ +void __init iotable_init(struct map_desc *io_desc, int nr) +{ + int i; + + for (i = 0; i < nr; i++) + create_mapping(io_desc + i); +} + +static inline void +free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn) +{ + struct page *start_pg, *end_pg; + unsigned long pg, pgend; + + /* + * Convert start_pfn/end_pfn to a struct page pointer. + */ + start_pg = pfn_to_page(start_pfn); + end_pg = pfn_to_page(end_pfn); + + /* + * Convert to physical addresses, and + * round start upwards and end downwards. + */ + pg = PAGE_ALIGN(__pa(start_pg)); + pgend = __pa(end_pg) & PAGE_MASK; + + /* + * If there are free pages between these, + * free the section of the memmap array. + */ + if (pg < pgend) + free_bootmem_node(NODE_DATA(node), pg, pgend - pg); +} + +static inline void free_unused_memmap_node(int node, struct meminfo *mi) +{ + unsigned long bank_start, prev_bank_end = 0; + unsigned int i; + + /* + * [FIXME] This relies on each bank being in address order. This + * may not be the case, especially if the user has provided the + * information on the command line. + */ + for (i = 0; i < mi->nr_banks; i++) { + if (mi->bank[i].size == 0 || mi->bank[i].node != node) + continue; + + bank_start = mi->bank[i].start >> PAGE_SHIFT; + if (bank_start < prev_bank_end) { + printk(KERN_ERR "MEM: unordered memory banks. " + "Not freeing memmap.\n"); + break; + } + + /* + * If we had a previous bank, and there is a space + * between the current bank and the previous, free it. + */ + if (prev_bank_end && prev_bank_end != bank_start) + free_memmap(node, prev_bank_end, bank_start); + + prev_bank_end = PAGE_ALIGN(mi->bank[i].start + + mi->bank[i].size) >> PAGE_SHIFT; + } +} + +/* + * The mem_map array can get very big. Free + * the unused area of the memory map. + */ +void __init create_memmap_holes(struct meminfo *mi) +{ + int node; + + for_each_online_node(node) + free_unused_memmap_node(node, mi); +} diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c new file mode 100644 index 0000000..32c4b0e --- /dev/null +++ b/arch/arm/mm/mmap.c @@ -0,0 +1,109 @@ +/* + * linux/arch/arm/mm/mmap.c + */ +#include <linux/config.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/shm.h> + +#include <asm/system.h> + +#define COLOUR_ALIGN(addr,pgoff) \ + ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \ + (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1))) + +/* + * We need to ensure that shared mappings are correctly aligned to + * avoid aliasing issues with VIPT caches. We need to ensure that + * a specific page of an object is always mapped at a multiple of + * SHMLBA bytes. + * + * We unconditionally provide this function for all cases, however + * in the VIVT case, we optimise out the alignment rules. + */ +unsigned long +arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long start_addr; +#ifdef CONFIG_CPU_V6 + unsigned int cache_type; + int do_align = 0, aliasing = 0; + + /* + * We only need to do colour alignment if either the I or D + * caches alias. This is indicated by bits 9 and 21 of the + * cache type register. + */ + cache_type = read_cpuid(CPUID_CACHETYPE); + if (cache_type != read_cpuid(CPUID_ID)) { + aliasing = (cache_type | cache_type >> 12) & (1 << 11); + if (aliasing) + do_align = filp || flags & MAP_SHARED; + } +#else +#define do_align 0 +#define aliasing 0 +#endif + + /* + * We should enforce the MAP_FIXED case. However, currently + * the generic kernel code doesn't allow us to handle this. + */ + if (flags & MAP_FIXED) { + if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1)) + return -EINVAL; + return addr; + } + + if (len > TASK_SIZE) + return -ENOMEM; + + if (addr) { + if (do_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && + (!vma || addr + len <= vma->vm_start)) + return addr; + } + start_addr = addr = mm->free_area_cache; + +full_search: + if (do_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { + /* At this point: (!vma || addr < vma->vm_end). */ + if (TASK_SIZE - len < addr) { + /* + * Start a new search - just in case we missed + * some holes. + */ + if (start_addr != TASK_UNMAPPED_BASE) { + start_addr = addr = TASK_UNMAPPED_BASE; + goto full_search; + } + return -ENOMEM; + } + if (!vma || addr + len <= vma->vm_start) { + /* + * Remember the place where we stopped the search: + */ + mm->free_area_cache = addr + len; + return addr; + } + addr = vma->vm_end; + if (do_align) + addr = COLOUR_ALIGN(addr, pgoff); + } +} + diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c new file mode 100644 index 0000000..0d90227 --- /dev/null +++ b/arch/arm/mm/mmu.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mm/mmu.c + * + * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved. + * + * 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/init.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/mmu_context.h> +#include <asm/tlbflush.h> + +unsigned int cpu_last_asid = { 1 << ASID_BITS }; + +/* + * We fork()ed a process, and we need a new context for the child + * to run in. We reserve version 0 for initial tasks so we will + * always allocate an ASID. + */ +void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + mm->context.id = 0; +} + +void __new_context(struct mm_struct *mm) +{ + unsigned int asid; + + asid = ++cpu_last_asid; + if (asid == 0) + asid = cpu_last_asid = 1 << ASID_BITS; + + /* + * If we've used up all our ASIDs, we need + * to start a new version and flush the TLB. + */ + if ((asid & ~ASID_MASK) == 0) + flush_tlb_all(); + + mm->context.id = asid; +} diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S new file mode 100644 index 0000000..1f32523 --- /dev/null +++ b/arch/arm/mm/proc-arm1020.S @@ -0,0 +1,530 @@ +/* + * linux/arch/arm/mm/proc-arm1020.S: MMU functions for ARM1020 + * + * Copyright (C) 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 + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm1020. + * + * CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> +#include <asm/hardware.h> + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define MAX_AREA_SIZE 32768 + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 32 + +/* + * The number of data cache segments. + */ +#define CACHE_DSEGMENTS 16 + +/* + * The number of lines in a cache segment. + */ +#define CACHE_DENTRIES 64 + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. + */ +#define CACHE_DLIMIT 32768 + + .text +/* + * cpu_arm1020_proc_init() + */ +ENTRY(cpu_arm1020_proc_init) + mov pc, lr + +/* + * cpu_arm1020_proc_fin() + */ +ENTRY(cpu_arm1020_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm1020_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm1020_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm1020_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm1020_do_idle() + */ + .align 5 +ENTRY(cpu_arm1020_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* ================================= CACHE ================================ */ + + .align 5 +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + */ +ENTRY(arm1020_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm1020_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index + mcr p15, 0, ip, c7, c10, 4 @ drain WB + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 15 to 0 +#endif + tst r2, #VM_EXEC +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache +#endif + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags for this space + */ +ENTRY(arm1020_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, ip, c7, c10, 4 +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + mcr p15, 0, ip, c7, c10, 4 @ drain WB + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + tst r2, #VM_EXEC +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache +#endif + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1020_coherent_kern_range) + /* FALLTRHOUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1020_coherent_user_range) + mov ip, #0 + bic r0, r0, #CACHE_DLINESIZE - 1 + mcr p15, 0, ip, c7, c10, 4 +1: +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, ip, c7, c10, 4 @ drain WB +#endif +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - page - page aligned address + */ +ENTRY(arm1020_flush_kern_dcache_page) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + mcr p15, 0, ip, c7, c10, 4 @ drain WB + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm1020_dma_inv_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + tst r0, #CACHE_DLINESIZE - 1 + bic r0, r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, ip, c7, c10, 4 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, ip, c7, c10, 4 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry + mcrne p15, 0, ip, c7, c10, 4 @ drain WB +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm1020_dma_clean_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, ip, c7, c10, 4 @ drain WB + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1020_dma_flush_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CACHE_DLINESIZE - 1 + mcr p15, 0, ip, c7, c10, 4 +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + mcr p15, 0, ip, c7, c10, 4 @ drain WB + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm1020_cache_fns) + .long arm1020_flush_kern_cache_all + .long arm1020_flush_user_cache_all + .long arm1020_flush_user_cache_range + .long arm1020_coherent_kern_range + .long arm1020_coherent_user_range + .long arm1020_flush_kern_dcache_page + .long arm1020_dma_inv_range + .long arm1020_dma_clean_range + .long arm1020_dma_flush_range + + .align 5 +ENTRY(cpu_arm1020_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_DISABLE + mov ip, #0 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, ip, c7, c10, 4 @ drain WB + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm1020_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm1020_switch_mm) +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r3, c7, c10, 4 + mov r1, #0xF @ 16 segments +1: mov r3, #0x3F @ 64 entries +2: mov ip, r3, LSL #26 @ shift up entry + orr ip, ip, r1, LSL #5 @ shift in/up index + mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry + mov ip, #0 + mcr p15, 0, ip, c7, c10, 4 + subs r3, r3, #1 + cmp r3, #0 + bge 2b @ entries 3F to 0 + subs r1, r1, #1 + cmp r1, #0 + bge 1b @ segments 15 to 0 + +#endif + mov r1, #0 +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache +#endif + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm1020_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm1020_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r1, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r0, c7, c10, 4 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __arm1020_setup, #function +__arm1020_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, arm1020_cr1_clear + bic r0, r0, r5 + ldr r5, arm1020_cr1_set + orr r0, r0, r5 +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x4000 @ .R.. .... .... .... +#endif + mov pc, lr + .size __arm1020_setup, . - __arm1020_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ + */ + .type arm1020_cr1_clear, #object + .type arm1020_cr1_set, #object +arm1020_cr1_clear: + .word 0x593f +arm1020_cr1_set: + .word 0x1935 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm1020_processor_functions, #object +arm1020_processor_functions: + .word v4t_early_abort + .word cpu_arm1020_proc_init + .word cpu_arm1020_proc_fin + .word cpu_arm1020_reset + .word cpu_arm1020_do_idle + .word cpu_arm1020_dcache_clean_area + .word cpu_arm1020_switch_mm + .word cpu_arm1020_set_pte + .size arm1020_processor_functions, . - arm1020_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm1020_name, #object +cpu_arm1020_name: + .ascii "ARM1020" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif +#ifndef CONFIG_CPU_BPREDICT_DISABLE + .ascii "B" +#endif +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + .ascii "RR" +#endif + .ascii "\0" + .size cpu_arm1020_name, . - cpu_arm1020_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm1020_proc_info,#object +__arm1020_proc_info: + .long 0x4104a200 @ ARM 1020T (Architecture v5T) + .long 0xff0ffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm1020_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm1020_name + .long arm1020_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long arm1020_cache_fns + .size __arm1020_proc_info, . - __arm1020_proc_info diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S new file mode 100644 index 0000000..142a2c2 --- /dev/null +++ b/arch/arm/mm/proc-arm1020e.S @@ -0,0 +1,513 @@ +/* + * linux/arch/arm/mm/proc-arm1020e.S: MMU functions for ARM1020 + * + * Copyright (C) 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 + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm1020e. + * + * CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> +#include <asm/hardware.h> + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define MAX_AREA_SIZE 32768 + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 32 + +/* + * The number of data cache segments. + */ +#define CACHE_DSEGMENTS 16 + +/* + * The number of lines in a cache segment. + */ +#define CACHE_DENTRIES 64 + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. + */ +#define CACHE_DLIMIT 32768 + + .text +/* + * cpu_arm1020e_proc_init() + */ +ENTRY(cpu_arm1020e_proc_init) + mov pc, lr + +/* + * cpu_arm1020e_proc_fin() + */ +ENTRY(cpu_arm1020e_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm1020e_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm1020e_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm1020e_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm1020e_do_idle() + */ + .align 5 +ENTRY(cpu_arm1020e_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* ================================= CACHE ================================ */ + + .align 5 +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + */ +ENTRY(arm1020e_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm1020e_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 15 to 0 +#endif + tst r2, #VM_EXEC +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache +#endif + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags for this space + */ +ENTRY(arm1020e_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +#ifndef CONFIG_CPU_DCACHE_DISABLE +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + tst r2, #VM_EXEC +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache +#endif + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1020e_coherent_kern_range) + /* FALLTHROUGH */ +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1020e_coherent_user_range) + mov ip, #0 + bic r0, r0, #CACHE_DLINESIZE - 1 +1: +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - page - page aligned address + */ +ENTRY(arm1020e_flush_kern_dcache_page) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm1020e_dma_inv_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + tst r0, #CACHE_DLINESIZE - 1 + bic r0, r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm1020e_dma_clean_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1020e_dma_flush_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm1020e_cache_fns) + .long arm1020e_flush_kern_cache_all + .long arm1020e_flush_user_cache_all + .long arm1020e_flush_user_cache_range + .long arm1020e_coherent_kern_range + .long arm1020e_coherent_user_range + .long arm1020e_flush_kern_dcache_page + .long arm1020e_dma_inv_range + .long arm1020e_dma_clean_range + .long arm1020e_dma_flush_range + + .align 5 +ENTRY(cpu_arm1020e_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_DISABLE + mov ip, #0 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm1020e_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm1020e_switch_mm) +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r3, c7, c10, 4 + mov r1, #0xF @ 16 segments +1: mov r3, #0x3F @ 64 entries +2: mov ip, r3, LSL #26 @ shift up entry + orr ip, ip, r1, LSL #5 @ shift in/up index + mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry + mov ip, #0 + subs r3, r3, #1 + cmp r3, #0 + bge 2b @ entries 3F to 0 + subs r1, r1, #1 + cmp r1, #0 + bge 1b @ segments 15 to 0 + +#endif + mov r1, #0 +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache +#endif + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm1020e_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm1020e_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r1, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mov pc, lr + + __INIT + + .type __arm1020e_setup, #function +__arm1020e_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, arm1020e_cr1_clear + bic r0, r0, r5 + ldr r5, arm1020e_cr1_set + orr r0, r0, r5 +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x4000 @ .R.. .... .... .... +#endif + mov pc, lr + .size __arm1020e_setup, . - __arm1020e_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ + */ + .type arm1020e_cr1_clear, #object + .type arm1020e_cr1_set, #object +arm1020e_cr1_clear: + .word 0x5f3f +arm1020e_cr1_set: + .word 0x1935 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm1020e_processor_functions, #object +arm1020e_processor_functions: + .word v4t_early_abort + .word cpu_arm1020e_proc_init + .word cpu_arm1020e_proc_fin + .word cpu_arm1020e_reset + .word cpu_arm1020e_do_idle + .word cpu_arm1020e_dcache_clean_area + .word cpu_arm1020e_switch_mm + .word cpu_arm1020e_set_pte + .size arm1020e_processor_functions, . - arm1020e_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5te" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm1020e_name, #object +cpu_arm1020e_name: + .ascii "ARM1020E" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif +#ifndef CONFIG_CPU_BPREDICT_DISABLE + .ascii "B" +#endif +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + .ascii "RR" +#endif + .ascii "\0" + .size cpu_arm1020e_name, . - cpu_arm1020e_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm1020e_proc_info,#object +__arm1020e_proc_info: + .long 0x4105a200 @ ARM 1020TE (Architecture v5TE) + .long 0xff0ffff0 + .long PMD_TYPE_SECT | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm1020e_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_EDSP + .long cpu_arm1020e_name + .long arm1020e_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long arm1020e_cache_fns + .size __arm1020e_proc_info, . - __arm1020e_proc_info diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S new file mode 100644 index 0000000..747ed963 --- /dev/null +++ b/arch/arm/mm/proc-arm1022.S @@ -0,0 +1,495 @@ +/* + * linux/arch/arm/mm/proc-arm1022.S: MMU functions for ARM1022E + * + * Copyright (C) 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. + * + * + * These are the low level assembler for performing cache and TLB + * functions on the ARM1022E. + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define MAX_AREA_SIZE 32768 + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 32 + +/* + * The number of data cache segments. + */ +#define CACHE_DSEGMENTS 16 + +/* + * The number of lines in a cache segment. + */ +#define CACHE_DENTRIES 64 + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. + */ +#define CACHE_DLIMIT 32768 + + .text +/* + * cpu_arm1022_proc_init() + */ +ENTRY(cpu_arm1022_proc_init) + mov pc, lr + +/* + * cpu_arm1022_proc_fin() + */ +ENTRY(cpu_arm1022_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm1022_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm1022_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm1022_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm1022_do_idle() + */ + .align 5 +ENTRY(cpu_arm1022_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* ================================= CACHE ================================ */ + + .align 5 +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + */ +ENTRY(arm1022_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm1022_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifndef CONFIG_CPU_DCACHE_DISABLE + mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 15 to 0 +#endif + tst r2, #VM_EXEC +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache +#endif + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags for this space + */ +ENTRY(arm1022_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +#ifndef CONFIG_CPU_DCACHE_DISABLE +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + tst r2, #VM_EXEC +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache +#endif + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1022_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1022_coherent_user_range) + mov ip, #0 + bic r0, r0, #CACHE_DLINESIZE - 1 +1: +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - page - page aligned address + */ +ENTRY(arm1022_flush_kern_dcache_page) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm1022_dma_inv_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + tst r0, #CACHE_DLINESIZE - 1 + bic r0, r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm1022_dma_clean_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1022_dma_flush_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm1022_cache_fns) + .long arm1022_flush_kern_cache_all + .long arm1022_flush_user_cache_all + .long arm1022_flush_user_cache_range + .long arm1022_coherent_kern_range + .long arm1022_coherent_user_range + .long arm1022_flush_kern_dcache_page + .long arm1022_dma_inv_range + .long arm1022_dma_clean_range + .long arm1022_dma_flush_range + + .align 5 +ENTRY(cpu_arm1022_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_DISABLE + mov ip, #0 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm1022_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm1022_switch_mm) +#ifndef CONFIG_CPU_DCACHE_DISABLE + mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 15 to 0 +#endif + mov r1, #0 +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache +#endif + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm1022_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm1022_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r1, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mov pc, lr + + __INIT + + .type __arm1022_setup, #function +__arm1022_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, arm1022_cr1_clear + bic r0, r0, r5 + ldr r5, arm1022_cr1_set + orr r0, r0, r5 +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x4000 @ .R.............. +#endif + mov pc, lr + .size __arm1022_setup, . - __arm1022_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * .011 1001 ..11 0101 + * + */ + .type arm1022_cr1_clear, #object + .type arm1022_cr1_set, #object +arm1022_cr1_clear: + .word 0x7f3f +arm1022_cr1_set: + .word 0x3935 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm1022_processor_functions, #object +arm1022_processor_functions: + .word v4t_early_abort + .word cpu_arm1022_proc_init + .word cpu_arm1022_proc_fin + .word cpu_arm1022_reset + .word cpu_arm1022_do_idle + .word cpu_arm1022_dcache_clean_area + .word cpu_arm1022_switch_mm + .word cpu_arm1022_set_pte + .size arm1022_processor_functions, . - arm1022_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5te" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm1022_name, #object +cpu_arm1022_name: + .ascii "arm1022" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif +#ifndef CONFIG_CPU_BPREDICT_DISABLE + .ascii "B" +#endif +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + .ascii "RR" +#endif + .ascii "\0" + .size cpu_arm1022_name, . - cpu_arm1022_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm1022_proc_info,#object +__arm1022_proc_info: + .long 0x4105a220 @ ARM 1022E (v5TE) + .long 0xff0ffff0 + .long PMD_TYPE_SECT | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm1022_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_EDSP + .long cpu_arm1022_name + .long arm1022_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long arm1022_cache_fns + .size __arm1022_proc_info, . - __arm1022_proc_info diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S new file mode 100644 index 0000000..248110c --- /dev/null +++ b/arch/arm/mm/proc-arm1026.S @@ -0,0 +1,491 @@ +/* + * linux/arch/arm/mm/proc-arm1026.S: MMU functions for ARM1026EJ-S + * + * Copyright (C) 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. + * + * + * These are the low level assembler for performing cache and TLB + * functions on the ARM1026EJ-S. + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define MAX_AREA_SIZE 32768 + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 32 + +/* + * The number of data cache segments. + */ +#define CACHE_DSEGMENTS 16 + +/* + * The number of lines in a cache segment. + */ +#define CACHE_DENTRIES 64 + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. + */ +#define CACHE_DLIMIT 32768 + + .text +/* + * cpu_arm1026_proc_init() + */ +ENTRY(cpu_arm1026_proc_init) + mov pc, lr + +/* + * cpu_arm1026_proc_fin() + */ +ENTRY(cpu_arm1026_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm1026_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm1026_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm1026_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm1026_do_idle() + */ + .align 5 +ENTRY(cpu_arm1026_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* ================================= CACHE ================================ */ + + .align 5 +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + */ +ENTRY(arm1026_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm1026_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifndef CONFIG_CPU_DCACHE_DISABLE +1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate + bne 1b +#endif + tst r2, #VM_EXEC +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache +#endif + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags for this space + */ +ENTRY(arm1026_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +#ifndef CONFIG_CPU_DCACHE_DISABLE +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + tst r2, #VM_EXEC +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache +#endif + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1026_coherent_kern_range) + /* FALLTHROUGH */ +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1026_coherent_user_range) + mov ip, #0 + bic r0, r0, #CACHE_DLINESIZE - 1 +1: +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - page - page aligned address + */ +ENTRY(arm1026_flush_kern_dcache_page) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm1026_dma_inv_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + tst r0, #CACHE_DLINESIZE - 1 + bic r0, r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm1026_dma_clean_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm1026_dma_flush_range) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm1026_cache_fns) + .long arm1026_flush_kern_cache_all + .long arm1026_flush_user_cache_all + .long arm1026_flush_user_cache_range + .long arm1026_coherent_kern_range + .long arm1026_coherent_user_range + .long arm1026_flush_kern_dcache_page + .long arm1026_dma_inv_range + .long arm1026_dma_clean_range + .long arm1026_dma_flush_range + + .align 5 +ENTRY(cpu_arm1026_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_DISABLE + mov ip, #0 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm1026_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm1026_switch_mm) + mov r1, #0 +#ifndef CONFIG_CPU_DCACHE_DISABLE +1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate + bne 1b +#endif +#ifndef CONFIG_CPU_ICACHE_DISABLE + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache +#endif + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm1026_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm1026_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r1, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 +#ifndef CONFIG_CPU_DCACHE_DISABLE + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mov pc, lr + + + __INIT + + .type __arm1026_setup, #function +__arm1026_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mcr p15, 0, r4, c2, c0 @ load page table pointer +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #4 @ explicitly disable writeback + mcr p15, 7, r0, c15, c0, 0 +#endif + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, arm1026_cr1_clear + bic r0, r0, r5 + ldr r5, arm1026_cr1_set + orr r0, r0, r5 +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x4000 @ .R.. .... .... .... +#endif + mov pc, lr + .size __arm1026_setup, . - __arm1026_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * .011 1001 ..11 0101 + * + */ + .type arm1026_cr1_clear, #object + .type arm1026_cr1_set, #object +arm1026_cr1_clear: + .word 0x7f3f +arm1026_cr1_set: + .word 0x3935 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm1026_processor_functions, #object +arm1026_processor_functions: + .word v5t_early_abort + .word cpu_arm1026_proc_init + .word cpu_arm1026_proc_fin + .word cpu_arm1026_reset + .word cpu_arm1026_do_idle + .word cpu_arm1026_dcache_clean_area + .word cpu_arm1026_switch_mm + .word cpu_arm1026_set_pte + .size arm1026_processor_functions, . - arm1026_processor_functions + + .section .rodata + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5tej" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5" + .size cpu_elf_name, . - cpu_elf_name + .align + + .type cpu_arm1026_name, #object +cpu_arm1026_name: + .ascii "ARM1026EJ-S" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif +#ifndef CONFIG_CPU_BPREDICT_DISABLE + .ascii "B" +#endif +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + .ascii "RR" +#endif + .ascii "\0" + .size cpu_arm1026_name, . - cpu_arm1026_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm1026_proc_info,#object +__arm1026_proc_info: + .long 0x4106a260 @ ARM 1026EJ-S (v5TEJ) + .long 0xff0ffff0 + .long PMD_TYPE_SECT | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm1026_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA + .long cpu_arm1026_name + .long arm1026_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long arm1026_cache_fns + .size __arm1026_proc_info, . - __arm1026_proc_info diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S new file mode 100644 index 0000000..0ee214b --- /dev/null +++ b/arch/arm/mm/proc-arm6_7.S @@ -0,0 +1,404 @@ +/* + * linux/arch/arm/mm/proc-arm6,7.S + * + * Copyright (C) 1997-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. + * + * These are the low level assembler for performing cache and TLB + * functions on the ARM610 & ARM710. + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> + +ENTRY(cpu_arm6_dcache_clean_area) +ENTRY(cpu_arm7_dcache_clean_area) + mov pc, lr + +/* + * Function: arm6_7_data_abort () + * + * Params : r2 = address of aborted instruction + * : sp = pointer to registers + * + * Purpose : obtain information about current aborted instruction + * + * Returns : r0 = address of abort + * : r1 = FSR + */ + +ENTRY(cpu_arm7_data_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + ldr r8, [r0] @ read arm instruction + tst r8, #1 << 20 @ L = 1 -> write? + orreq r1, r1, #1 << 8 @ yes. + and r7, r8, #15 << 24 + add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine + nop + +/* 0 */ b .data_unknown +/* 1 */ mov pc, lr @ swp +/* 2 */ b .data_unknown +/* 3 */ b .data_unknown +/* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m +/* 5 */ b .data_arm_lateldrpreconst @ ldr rd, [rn, #m] +/* 6 */ b .data_arm_lateldrpostreg @ ldr rd, [rn], rm +/* 7 */ b .data_arm_lateldrprereg @ ldr rd, [rn, rm] +/* 8 */ b .data_arm_ldmstm @ ldm*a rn, <rlist> +/* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> +/* a */ b .data_unknown +/* b */ b .data_unknown +/* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m +/* d */ mov pc, lr @ ldc rd, [rn, #m] +/* e */ b .data_unknown +/* f */ +.data_unknown: @ Part of jumptable + mov r0, r2 + mov r1, r8 + mov r2, sp + bl baddataabort + b ret_from_exception + +ENTRY(cpu_arm6_data_abort) + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR + ldr r8, [r2] @ read arm instruction + tst r8, #1 << 20 @ L = 1 -> write? + orreq r1, r1, #1 << 8 @ yes. + and r7, r8, #14 << 24 + teq r7, #8 << 24 @ was it ldm/stm + movne pc, lr + +.data_arm_ldmstm: + tst r8, #1 << 21 @ check writeback bit + moveq pc, lr @ no writeback -> no fixup + mov r7, #0x11 + orr r7, r7, #0x1100 + and r6, r8, r7 + and r2, r8, r7, lsl #1 + add r6, r6, r2, lsr #1 + and r2, r8, r7, lsl #2 + add r6, r6, r2, lsr #2 + and r2, r8, r7, lsl #3 + add r6, r6, r2, lsr #3 + add r6, r6, r6, lsr #8 + add r6, r6, r6, lsr #4 + and r6, r6, #15 @ r6 = no. of registers to transfer. + and r5, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r6, lsl #2 @ Undo increment + addeq r7, r7, r6, lsl #2 @ Undo decrement + str r7, [sp, r5, lsr #14] @ Put register 'Rn' + mov pc, lr + +.data_arm_apply_r6_and_rn: + and r5, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r6 @ Undo incrmenet + addeq r7, r7, r6 @ Undo decrement + str r7, [sp, r5, lsr #14] @ Put register 'Rn' + mov pc, lr + +.data_arm_lateldrpreconst: + tst r8, #1 << 21 @ check writeback bit + moveq pc, lr @ no writeback -> no fixup +.data_arm_lateldrpostconst: + movs r2, r8, lsl #20 @ Get offset + moveq pc, lr @ zero -> no fixup + and r5, r8, #15 << 16 @ Extract 'n' from instruction + ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' + tst r8, #1 << 23 @ Check U bit + subne r7, r7, r2, lsr #20 @ Undo increment + addeq r7, r7, r2, lsr #20 @ Undo decrement + str r7, [sp, r5, lsr #14] @ Put register 'Rn' + mov pc, lr + +.data_arm_lateldrprereg: + tst r8, #1 << 21 @ check writeback bit + moveq pc, lr @ no writeback -> no fixup +.data_arm_lateldrpostreg: + and r7, r8, #15 @ Extract 'm' from instruction + ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' + mov r5, r8, lsr #7 @ get shift count + ands r5, r5, #31 + and r7, r8, #0x70 @ get shift type + orreq r7, r7, #8 @ shift count = 0 + add pc, pc, r7 + nop + + mov r6, r6, lsl r5 @ 0: LSL #!0 + b .data_arm_apply_r6_and_rn + b .data_arm_apply_r6_and_rn @ 1: LSL #0 + nop + b .data_unknown @ 2: MUL? + nop + b .data_unknown @ 3: MUL? + nop + mov r6, r6, lsr r5 @ 4: LSR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, lsr #32 @ 5: LSR #32 + b .data_arm_apply_r6_and_rn + b .data_unknown @ 6: MUL? + nop + b .data_unknown @ 7: MUL? + nop + mov r6, r6, asr r5 @ 8: ASR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, asr #32 @ 9: ASR #32 + b .data_arm_apply_r6_and_rn + b .data_unknown @ A: MUL? + nop + b .data_unknown @ B: MUL? + nop + mov r6, r6, ror r5 @ C: ROR #!0 + b .data_arm_apply_r6_and_rn + mov r6, r6, rrx @ D: RRX + b .data_arm_apply_r6_and_rn + b .data_unknown @ E: MUL? + nop + b .data_unknown @ F: MUL? + +/* + * Function: arm6_7_proc_init (void) + * : arm6_7_proc_fin (void) + * + * Notes : This processor does not require these + */ +ENTRY(cpu_arm6_proc_init) +ENTRY(cpu_arm7_proc_init) + mov pc, lr + +ENTRY(cpu_arm6_proc_fin) +ENTRY(cpu_arm7_proc_fin) + mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, r0 + mov r0, #0x31 @ ....S..DP...M + mcr p15, 0, r0, c1, c0, 0 @ disable caches + mov pc, lr + +ENTRY(cpu_arm6_do_idle) +ENTRY(cpu_arm7_do_idle) + mov pc, lr + +/* + * Function: arm6_7_switch_mm(unsigned long pgd_phys) + * Params : pgd_phys Physical address of page table + * Purpose : Perform a task switch, saving the old processes state, and restoring + * the new. + */ +ENTRY(cpu_arm6_switch_mm) +ENTRY(cpu_arm7_switch_mm) + mov r1, #0 + mcr p15, 0, r1, c7, c0, 0 @ flush cache + mcr p15, 0, r0, c2, c0, 0 @ update page table ptr + mcr p15, 0, r1, c5, c0, 0 @ flush TLBs + mov pc, lr + +/* + * Function: arm6_7_set_pte(pte_t *ptep, pte_t pte) + * Params : r0 = Address to set + * : r1 = value to set + * Purpose : Set a PTE and flush it out of any WB cache + */ + .align 5 +ENTRY(cpu_arm6_set_pte) +ENTRY(cpu_arm7_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young + movne r2, #0 + + str r2, [r0] @ hardware version + mov pc, lr + +/* + * Function: _arm6_7_reset + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ +ENTRY(cpu_arm6_reset) +ENTRY(cpu_arm7_reset) + mov r1, #0 + mcr p15, 0, r1, c7, c0, 0 @ flush cache + mcr p15, 0, r1, c5, c0, 0 @ flush TLB + mov r1, #0x30 + mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc + mov pc, r0 + + __INIT + + .type __arm6_setup, #function +__arm6_setup: mov r0, #0 + mcr p15, 0, r0, c7, c0 @ flush caches on v3 + mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 + mov r0, #0x3d @ . ..RS BLDP WCAM + orr r0, r0, #0x100 @ . ..01 0011 1101 + mov pc, lr + .size __arm6_setup, . - __arm6_setup + + .type __arm7_setup, #function +__arm7_setup: mov r0, #0 + mcr p15, 0, r0, c7, c0 @ flush caches on v3 + mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 + mcr p15, 0, r0, c3, c0 @ load domain access register + mov r0, #0x7d @ . ..RS BLDP WCAM + orr r0, r0, #0x100 @ . ..01 0111 1101 + mov pc, lr + .size __arm7_setup, . - __arm7_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm6_processor_functions, #object +ENTRY(arm6_processor_functions) + .word cpu_arm6_data_abort + .word cpu_arm6_proc_init + .word cpu_arm6_proc_fin + .word cpu_arm6_reset + .word cpu_arm6_do_idle + .word cpu_arm6_dcache_clean_area + .word cpu_arm6_switch_mm + .word cpu_arm6_set_pte + .size arm6_processor_functions, . - arm6_processor_functions + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm7_processor_functions, #object +ENTRY(arm7_processor_functions) + .word cpu_arm7_data_abort + .word cpu_arm7_proc_init + .word cpu_arm7_proc_fin + .word cpu_arm7_reset + .word cpu_arm7_do_idle + .word cpu_arm7_dcache_clean_area + .word cpu_arm7_switch_mm + .word cpu_arm7_set_pte + .size arm7_processor_functions, . - arm7_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: .asciz "armv3" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: .asciz "v3" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm6_name, #object +cpu_arm6_name: .asciz "ARM6" + .size cpu_arm6_name, . - cpu_arm6_name + + .type cpu_arm610_name, #object +cpu_arm610_name: + .asciz "ARM610" + .size cpu_arm610_name, . - cpu_arm610_name + + .type cpu_arm7_name, #object +cpu_arm7_name: .asciz "ARM7" + .size cpu_arm7_name, . - cpu_arm7_name + + .type cpu_arm710_name, #object +cpu_arm710_name: + .asciz "ARM710" + .size cpu_arm710_name, . - cpu_arm710_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm6_proc_info, #object +__arm6_proc_info: + .long 0x41560600 + .long 0xfffffff0 + .long 0x00000c1e + b __arm6_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_26BIT + .long cpu_arm6_name + .long arm6_processor_functions + .long v3_tlb_fns + .long v3_user_fns + .long v3_cache_fns + .size __arm6_proc_info, . - __arm6_proc_info + + .type __arm610_proc_info, #object +__arm610_proc_info: + .long 0x41560610 + .long 0xfffffff0 + .long 0x00000c1e + b __arm6_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_26BIT + .long cpu_arm610_name + .long arm6_processor_functions + .long v3_tlb_fns + .long v3_user_fns + .long v3_cache_fns + .size __arm610_proc_info, . - __arm610_proc_info + + .type __arm7_proc_info, #object +__arm7_proc_info: + .long 0x41007000 + .long 0xffffff00 + .long 0x00000c1e + b __arm7_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_26BIT + .long cpu_arm7_name + .long arm7_processor_functions + .long v3_tlb_fns + .long v3_user_fns + .long v3_cache_fns + .size __arm7_proc_info, . - __arm7_proc_info + + .type __arm710_proc_info, #object +__arm710_proc_info: + .long 0x41007100 + .long 0xfff8ff00 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm7_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_26BIT + .long cpu_arm710_name + .long arm7_processor_functions + .long v3_tlb_fns + .long v3_user_fns + .long v3_cache_fns + .size __arm710_proc_info, . - __arm710_proc_info diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S new file mode 100644 index 0000000..57cfa6a --- /dev/null +++ b/arch/arm/mm/proc-arm720.S @@ -0,0 +1,267 @@ +/* + * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720 + * + * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) + * Rob Scott (rscott@mtrob.fdns.net) + * Copyright (C) 2000 ARM Limited, 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 + * + * + * These are the low level assembler for performing cache and TLB + * functions on the ARM720T. The ARM720T has a writethrough IDC + * cache, so we don't need to clean it. + * + * Changelog: + * 05-09-2000 SJH Created by moving 720 specific functions + * out of 'proc-arm6,7.S' per RMK discussion + * 07-25-2000 SJH Added idle function. + * 08-25-2000 DBS Updated for integration of ARM Ltd version. + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> +#include <asm/hardware.h> + +/* + * Function: arm720_proc_init (void) + * : arm720_proc_fin (void) + * + * Notes : This processor does not require these + */ +ENTRY(cpu_arm720_dcache_clean_area) +ENTRY(cpu_arm720_proc_init) + mov pc, lr + +ENTRY(cpu_arm720_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + mcr p15, 0, r1, c7, c7, 0 @ invalidate cache + ldmfd sp!, {pc} + +/* + * Function: arm720_proc_do_idle(void) + * Params : r0 = unused + * Purpose : put the processer in proper idle mode + */ +ENTRY(cpu_arm720_do_idle) + mov pc, lr + +/* + * Function: arm720_switch_mm(unsigned long pgd_phys) + * Params : pgd_phys Physical address of page table + * Purpose : Perform a task switch, saving the old process' state and restoring + * the new. + */ +ENTRY(cpu_arm720_switch_mm) + mov r1, #0 + mcr p15, 0, r1, c7, c7, 0 @ invalidate cache + mcr p15, 0, r0, c2, c0, 0 @ update page table ptr + mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4) + mov pc, lr + +/* + * Function: arm720_set_pte(pte_t *ptep, pte_t pte) + * Params : r0 = Address to set + * : r1 = value to set + * Purpose : Set a PTE and flush it out of any WB cache + */ + .align 5 +ENTRY(cpu_arm720_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young + movne r2, #0 + + str r2, [r0] @ hardware version + mov pc, lr + +/* + * Function: arm720_reset + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ +ENTRY(cpu_arm720_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate cache + mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x2100 @ ..v....s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + + __INIT + + .type __arm710_setup, #function +__arm710_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 @ invalidate caches + mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, r0, c1, c0 @ get control register + ldr r5, arm710_cr1_clear + bic r0, r0, r5 + ldr r5, arm710_cr1_set + orr r0, r0, r5 + mov pc, lr @ __ret (head.S) + .size __arm710_setup, . - __arm710_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * .... 0001 ..11 1101 + * + */ + .type arm710_cr1_clear, #object + .type arm710_cr1_set, #object +arm710_cr1_clear: + .word 0x0f3f +arm710_cr1_set: + .word 0x013d + + .type __arm720_setup, #function +__arm720_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 @ invalidate caches + mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, r0, c1, c0 @ get control register + ldr r5, arm720_cr1_clear + bic r0, r0, r5 + ldr r5, arm720_cr1_set + orr r0, r0, r5 + mov pc, lr @ __ret (head.S) + .size __arm720_setup, . - __arm720_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * ..1. 1001 ..11 1101 + * + */ + .type arm720_cr1_clear, #object + .type arm720_cr1_set, #object +arm720_cr1_clear: + .word 0x2f3f +arm720_cr1_set: + .word 0x213d + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm720_processor_functions, #object +ENTRY(arm720_processor_functions) + .word v4t_late_abort + .word cpu_arm720_proc_init + .word cpu_arm720_proc_fin + .word cpu_arm720_reset + .word cpu_arm720_do_idle + .word cpu_arm720_dcache_clean_area + .word cpu_arm720_switch_mm + .word cpu_arm720_set_pte + .size arm720_processor_functions, . - arm720_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm710_name, #object +cpu_arm710_name: + .asciz "ARM710T" + .size cpu_arm710_name, . - cpu_arm710_name + + .type cpu_arm720_name, #object +cpu_arm720_name: + .asciz "ARM720T" + .size cpu_arm720_name, . - cpu_arm720_name + + .align + +/* + * See linux/include/asm-arm/procinfo.h for a definition of this structure. + */ + + .section ".proc.info", #alloc, #execinstr + + .type __arm710_proc_info, #object +__arm710_proc_info: + .long 0x41807100 @ cpu_val + .long 0xffffff00 @ cpu_mask + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm710_setup @ cpu_flush + .long cpu_arch_name @ arch_name + .long cpu_elf_name @ elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap + .long cpu_arm710_name @ name + .long arm720_processor_functions + .long v4_tlb_fns + .long v4wt_user_fns + .long v4_cache_fns + .size __arm710_proc_info, . - __arm710_proc_info + + .type __arm720_proc_info, #object +__arm720_proc_info: + .long 0x41807200 @ cpu_val + .long 0xffffff00 @ cpu_mask + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm720_setup @ cpu_flush + .long cpu_arch_name @ arch_name + .long cpu_elf_name @ elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap + .long cpu_arm720_name @ name + .long arm720_processor_functions + .long v4_tlb_fns + .long v4wt_user_fns + .long v4_cache_fns + .size __arm720_proc_info, . - __arm720_proc_info diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S new file mode 100644 index 0000000..0f490a0 --- /dev/null +++ b/arch/arm/mm/proc-arm920.S @@ -0,0 +1,480 @@ +/* + * linux/arch/arm/mm/proc-arm920.S: MMU functions for ARM920 + * + * 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 + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm920. + * + * CONFIG_CPU_ARM920_CPU_IDLE -> nohlt + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include <asm/ptrace.h> +#include "proc-macros.S" + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 32 + +/* + * The number of data cache segments. + */ +#define CACHE_DSEGMENTS 8 + +/* + * The number of lines in a cache segment. + */ +#define CACHE_DENTRIES 64 + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. + */ +#define CACHE_DLIMIT 65536 + + + .text +/* + * cpu_arm920_proc_init() + */ +ENTRY(cpu_arm920_proc_init) + mov pc, lr + +/* + * cpu_arm920_proc_fin() + */ +ENTRY(cpu_arm920_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + bl arm920_flush_kern_cache_all +#else + bl v4wt_flush_kern_cache_all +#endif + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm920_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm920_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm920_do_idle() + */ + .align 5 +ENTRY(cpu_arm920_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + + +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + */ +ENTRY(arm920_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm920_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: + mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 8 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags for address space + */ +ENTRY(arm920_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + tst r2, #VM_EXEC + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm920_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm920_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(arm920_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm920_dma_inv_range) + tst r0, #CACHE_DLINESIZE - 1 + bic r0, r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm920_dma_clean_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm920_dma_flush_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm920_cache_fns) + .long arm920_flush_kern_cache_all + .long arm920_flush_user_cache_all + .long arm920_flush_user_cache_range + .long arm920_coherent_kern_range + .long arm920_coherent_user_range + .long arm920_flush_kern_dcache_page + .long arm920_dma_inv_range + .long arm920_dma_clean_range + .long arm920_dma_flush_range + +#endif + + +ENTRY(cpu_arm920_dcache_clean_area) +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm920_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm920_switch_mm) + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +@ && 'Clean & Invalidate whole DCache' +@ && Re-written to use Index Ops. +@ && Uses registers r1, r3 and ip + + mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 8 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm920_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm920_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r2, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __arm920_setup, #function +__arm920_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, arm920_cr1_clear + bic r0, r0, r5 + ldr r5, arm920_cr1_set + orr r0, r0, r5 + mov pc, lr + .size __arm920_setup, . - __arm920_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * ..11 0001 ..11 0101 + * + */ + .type arm920_cr1_clear, #object + .type arm920_cr1_set, #object +arm920_cr1_clear: + .word 0x3f3f +arm920_cr1_set: + .word 0x3135 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm920_processor_functions, #object +arm920_processor_functions: + .word v4t_early_abort + .word cpu_arm920_proc_init + .word cpu_arm920_proc_fin + .word cpu_arm920_reset + .word cpu_arm920_do_idle + .word cpu_arm920_dcache_clean_area + .word cpu_arm920_switch_mm + .word cpu_arm920_set_pte + .size arm920_processor_functions, . - arm920_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm920_name, #object +cpu_arm920_name: + .ascii "ARM920T" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif + .ascii "\0" + .size cpu_arm920_name, . - cpu_arm920_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm920_proc_info,#object +__arm920_proc_info: + .long 0x41009200 + .long 0xff00fff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm920_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm920_name + .long arm920_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + .long arm920_cache_fns +#else + .long v4wt_cache_fns +#endif + .size __arm920_proc_info, . - __arm920_proc_info diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S new file mode 100644 index 0000000..62bc34a --- /dev/null +++ b/arch/arm/mm/proc-arm922.S @@ -0,0 +1,484 @@ +/* + * linux/arch/arm/mm/proc-arm922.S: MMU functions for ARM922 + * + * Copyright (C) 1999,2000 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * Copyright (C) 2001 Altera Corporation + * + * 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 + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm922. + * + * CONFIG_CPU_ARM922_CPU_IDLE -> nohlt + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include <asm/ptrace.h> +#include "proc-macros.S" + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 32 + +/* + * The number of data cache segments. + */ +#define CACHE_DSEGMENTS 4 + +/* + * The number of lines in a cache segment. + */ +#define CACHE_DENTRIES 64 + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. (I think this should + * be 32768). + */ +#define CACHE_DLIMIT 8192 + + + .text +/* + * cpu_arm922_proc_init() + */ +ENTRY(cpu_arm922_proc_init) + mov pc, lr + +/* + * cpu_arm922_proc_fin() + */ +ENTRY(cpu_arm922_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + bl arm922_flush_kern_cache_all +#else + bl v4wt_flush_kern_cache_all +#endif + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm922_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm922_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm922_do_idle() + */ + .align 5 +ENTRY(cpu_arm922_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + + +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + +/* + * flush_user_cache_all() + * + * Clean and invalidate all cache entries in a particular + * address space. + */ +ENTRY(arm922_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm922_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: + mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 8 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address range. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags describing address space + */ +ENTRY(arm922_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + tst r2, #VM_EXEC + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm922_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm922_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(arm922_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm922_dma_inv_range) + tst r0, #CACHE_DLINESIZE - 1 + bic r0, r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm922_dma_clean_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm922_dma_flush_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm922_cache_fns) + .long arm922_flush_kern_cache_all + .long arm922_flush_user_cache_all + .long arm922_flush_user_cache_range + .long arm922_coherent_kern_range + .long arm922_coherent_user_range + .long arm922_flush_kern_dcache_page + .long arm922_dma_inv_range + .long arm922_dma_clean_range + .long arm922_dma_flush_range + +#endif + + +ENTRY(cpu_arm922_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm922_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm922_switch_mm) + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +@ && 'Clean & Invalidate whole DCache' +@ && Re-written to use Index Ops. +@ && Uses registers r1, r3 and ip + + mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 5 + bcs 1b @ segments 7 to 0 +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm922_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm922_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r2, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __arm922_setup, #function +__arm922_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, arm922_cr1_clear + bic r0, r0, r5 + ldr r5, arm922_cr1_set + orr r0, r0, r5 + mov pc, lr + .size __arm922_setup, . - __arm922_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * ..11 0001 ..11 0101 + * + */ + .type arm922_cr1_clear, #object + .type arm922_cr1_set, #object +arm922_cr1_clear: + .word 0x3f3f +arm922_cr1_set: + .word 0x3135 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm922_processor_functions, #object +arm922_processor_functions: + .word v4t_early_abort + .word cpu_arm922_proc_init + .word cpu_arm922_proc_fin + .word cpu_arm922_reset + .word cpu_arm922_do_idle + .word cpu_arm922_dcache_clean_area + .word cpu_arm922_switch_mm + .word cpu_arm922_set_pte + .size arm922_processor_functions, . - arm922_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm922_name, #object +cpu_arm922_name: + .ascii "ARM922T" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#endif + .ascii "\0" + .size cpu_arm922_name, . - cpu_arm922_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm922_proc_info,#object +__arm922_proc_info: + .long 0x41009220 + .long 0xff00fff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm922_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm922_name + .long arm922_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + .long arm922_cache_fns +#else + .long v4wt_cache_fns +#endif + .size __arm922_proc_info, . - __arm922_proc_info diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S new file mode 100644 index 0000000..ee49aa2 --- /dev/null +++ b/arch/arm/mm/proc-arm925.S @@ -0,0 +1,562 @@ +/* + * linux/arch/arm/mm/arm925.S: MMU functions for ARM925 + * + * Copyright (C) 1999,2000 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * Copyright (C) 2002 RidgeRun, Inc. + * Copyright (C) 2002-2003 MontaVista Software, Inc. + * + * Update for Linux-2.6 and cache flush improvements + * Copyright (C) 2004 Nokia Corporation by Tony Lindgren <tony@atomide.com> + * + * 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 + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm925. + * + * CONFIG_CPU_ARM925_CPU_IDLE -> nohlt + * + * Some additional notes based on deciphering the TI TRM on OMAP-5910: + * + * NOTE1: The TI925T Configuration Register bit "D-cache clean and flush + * entry mode" must be 0 to flush the entries in both segments + * at once. This is the default value. See TRM 2-20 and 2-24 for + * more information. + * + * NOTE2: Default is the "D-cache clean and flush entry mode". It looks + * like the "Transparent mode" must be on for partial cache flushes + * to work in this mode. This mode only works with 16-bit external + * memory. See TRM 2-24 for more information. + * + * NOTE3: Write-back cache flushing seems to be flakey with devices using + * direct memory access, such as USB OHCI. The workaround is to use + * write-through cache with CONFIG_CPU_DCACHE_WRITETHROUGH (this is + * the default for OMAP-1510). + */ + +#include <linux/linkage.h> +#include <linux/config.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include <asm/ptrace.h> +#include "proc-macros.S" + +/* + * The size of one data cache line. + */ +#define CACHE_DLINESIZE 16 + +/* + * The number of data cache segments. + */ +#define CACHE_DSEGMENTS 2 + +/* + * The number of lines in a cache segment. + */ +#define CACHE_DENTRIES 256 + +/* + * This is the size at which it becomes more efficient to + * clean the whole cache, rather than using the individual + * cache line maintainence instructions. + */ +#define CACHE_DLIMIT 8192 + + .text +/* + * cpu_arm925_proc_init() + */ +ENTRY(cpu_arm925_proc_init) + mov pc, lr + +/* + * cpu_arm925_proc_fin() + */ +ENTRY(cpu_arm925_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm925_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm925_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm925_reset) + /* Send software reset to MPU and DSP */ + mov ip, #0xff000000 + orr ip, ip, #0x00fe0000 + orr ip, ip, #0x0000ce00 + mov r4, #1 + strh r4, [ip, #0x10] + + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm925_do_idle() + * + * Called with IRQs disabled + */ + .align 10 +ENTRY(cpu_arm925_do_idle) + mov r0, #0 + mrc p15, 0, r1, c1, c0, 0 @ Read control register + mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer + bic r2, r1, #1 << 12 + mcr p15, 0, r2, c1, c0, 0 @ Disable I cache + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mcr p15, 0, r1, c1, c0, 0 @ Restore ICache enable + mov pc, lr + +/* + * flush_user_cache_all() + * + * Clean and invalidate all cache entries in a particular + * address space. + */ +ENTRY(arm925_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm925_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else + /* Flush entries in both segments at once, see NOTE1 above */ + mov r3, #(CACHE_DENTRIES - 1) << 4 @ 256 entries in segment +2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index + subs r3, r3, #1 << 4 + bcs 2b @ entries 255 to 0 +#endif + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address range. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags describing address space + */ +ENTRY(arm925_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bgt __flush_whole_cache +1: tst r2, #VM_EXEC +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#else + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#endif + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm925_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm925_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(arm925_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm925_dma_inv_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + tst r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +#endif + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm925_dma_clean_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm925_dma_flush_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry +#else + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm925_cache_fns) + .long arm925_flush_kern_cache_all + .long arm925_flush_user_cache_all + .long arm925_flush_user_cache_range + .long arm925_coherent_kern_range + .long arm925_coherent_user_range + .long arm925_flush_kern_dcache_page + .long arm925_dma_inv_range + .long arm925_dma_clean_range + .long arm925_dma_flush_range + +ENTRY(cpu_arm925_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm925_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm925_switch_mm) + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else + /* Flush entries in bothe segments at once, see NOTE1 above */ + mov r3, #(CACHE_DENTRIES - 1) << 4 @ 256 entries in segment +2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index + subs r3, r3, #1 << 4 + bcs 2b @ entries 255 to 0 +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm925_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm925_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r2, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __arm925_setup, #function +__arm925_setup: + mov r0, #0 +#if defined(CONFIG_CPU_ICACHE_STREAMING_DISABLE) + orr r0,r0,#1 << 7 +#endif + + /* Transparent on, D-cache clean & flush mode. See NOTE2 above */ + orr r0,r0,#1 << 1 @ transparent mode on + mcr p15, 0, r0, c15, c1, 0 @ write TI config register + + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #4 @ disable write-back on caches explicitly + mcr p15, 7, r0, c15, c0, 0 +#endif + + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, arm925_cr1_clear + bic r0, r0, r5 + ldr r5, arm925_cr1_set + orr r0, r0, r5 +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x4000 @ .1.. .... .... .... +#endif + mov pc, lr + .size __arm925_setup, . - __arm925_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * .011 0001 ..11 1101 + * + */ + .type arm925_cr1_clear, #object + .type arm925_cr1_set, #object +arm925_cr1_clear: + .word 0x7f3f +arm925_cr1_set: + .word 0x313d + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm925_processor_functions, #object +arm925_processor_functions: + .word v4t_early_abort + .word cpu_arm925_proc_init + .word cpu_arm925_proc_fin + .word cpu_arm925_reset + .word cpu_arm925_do_idle + .word cpu_arm925_dcache_clean_area + .word cpu_arm925_switch_mm + .word cpu_arm925_set_pte + .size arm925_processor_functions, . - arm925_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm925_name, #object +cpu_arm925_name: + .ascii "ARM925T" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + .ascii "RR" +#endif +#endif + .ascii "\0" + .size cpu_arm925_name, . - cpu_arm925_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm925_proc_info,#object +__arm925_proc_info: + .long 0x54029250 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm925_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm925_name + .long arm925_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long arm925_cache_fns + .size __arm925_proc_info, . - __arm925_proc_info + + .type __arm915_proc_info,#object +__arm915_proc_info: + .long 0x54029150 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm925_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm925_name + .long arm925_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long arm925_cache_fns + .size __arm925_proc_info, . - __arm925_proc_info diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S new file mode 100644 index 0000000..bb95cc9 --- /dev/null +++ b/arch/arm/mm/proc-arm926.S @@ -0,0 +1,495 @@ +/* + * linux/arch/arm/mm/proc-arm926.S: MMU functions for ARM926EJ-S + * + * Copyright (C) 1999-2001 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 + * + * + * These are the low level assembler for performing cache and TLB + * functions on the arm926. + * + * CONFIG_CPU_ARM926_CPU_IDLE -> nohlt + */ +#include <linux/linkage.h> +#include <linux/config.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include <asm/page.h> +#include <asm/ptrace.h> +#include "proc-macros.S" + +/* + * This is the maximum size of an area which will be invalidated + * using the single invalidate entry instructions. Anything larger + * than this, and we go for the whole cache. + * + * This value should be chosen such that we choose the cheapest + * alternative. + */ +#define CACHE_DLIMIT 16384 + +/* + * the cache line size of the I and D cache + */ +#define CACHE_DLINESIZE 32 + + .text +/* + * cpu_arm926_proc_init() + */ +ENTRY(cpu_arm926_proc_init) + mov pc, lr + +/* + * cpu_arm926_proc_fin() + */ +ENTRY(cpu_arm926_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm926_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm926_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_arm926_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm926_do_idle() + * + * Called with IRQs disabled + */ + .align 10 +ENTRY(cpu_arm926_do_idle) + mov r0, #0 + mrc p15, 0, r1, c1, c0, 0 @ Read control register + mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer + bic r2, r1, #1 << 12 + mcr p15, 0, r2, c1, c0, 0 @ Disable I cache + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mcr p15, 0, r1, c1, c0, 0 @ Restore ICache enable + mov pc, lr + +/* + * flush_user_cache_all() + * + * Clean and invalidate all cache entries in a particular + * address space. + */ +ENTRY(arm926_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm926_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate + bne 1b +#endif + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address range. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags describing address space + */ +ENTRY(arm926_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bgt __flush_whole_cache +1: tst r2, #VM_EXEC +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#else + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#endif + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm926_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm926_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(arm926_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm926_dma_inv_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + tst r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +#endif + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as v4wb) + */ +ENTRY(arm926_dma_clean_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm926_dma_flush_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry +#else + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm926_cache_fns) + .long arm926_flush_kern_cache_all + .long arm926_flush_user_cache_all + .long arm926_flush_user_cache_range + .long arm926_coherent_kern_range + .long arm926_coherent_user_range + .long arm926_flush_kern_dcache_page + .long arm926_dma_inv_range + .long arm926_dma_clean_range + .long arm926_dma_flush_range + +ENTRY(cpu_arm926_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_arm926_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_arm926_switch_mm) + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache +#else +@ && 'Clean & Invalidate whole DCache' +1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate + bne 1b +#endif + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_arm926_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_arm926_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + eor r3, r2, #0x0a @ C & small page? + tst r3, #0x0b + biceq r2, r2, #4 +#endif + str r2, [r0] @ hardware version + mov r0, r0 +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __arm926_setup, #function +__arm926_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + + +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #4 @ disable write-back on caches explicitly + mcr p15, 7, r0, c15, c0, 0 +#endif + + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, arm926_cr1_clear + bic r0, r0, r5 + ldr r5, arm926_cr1_set + orr r0, r0, r5 +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x4000 @ .1.. .... .... .... +#endif + mov pc, lr + .size __arm926_setup, . - __arm926_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * .011 0001 ..11 0101 + * + */ + .type arm926_cr1_clear, #object + .type arm926_cr1_set, #object +arm926_cr1_clear: + .word 0x7f3f +arm926_cr1_set: + .word 0x3135 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm926_processor_functions, #object +arm926_processor_functions: + .word v5tj_early_abort + .word cpu_arm926_proc_init + .word cpu_arm926_proc_fin + .word cpu_arm926_reset + .word cpu_arm926_do_idle + .word cpu_arm926_dcache_clean_area + .word cpu_arm926_switch_mm + .word cpu_arm926_set_pte + .size arm926_processor_functions, . - arm926_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5tej" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm926_name, #object +cpu_arm926_name: + .ascii "ARM926EJ-S" +#ifndef CONFIG_CPU_ICACHE_DISABLE + .ascii "i" +#endif +#ifndef CONFIG_CPU_DCACHE_DISABLE + .ascii "d" +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + .ascii "(wt)" +#else + .ascii "(wb)" +#endif +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + .ascii "RR" +#endif +#endif + .ascii "\0" + .size cpu_arm926_name, . - cpu_arm926_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __arm926_proc_info,#object +__arm926_proc_info: + .long 0x41069260 @ ARM926EJ-S (v5TEJ) + .long 0xff0ffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_BIT4 | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __arm926_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA + .long cpu_arm926_name + .long arm926_processor_functions + .long v4wbi_tlb_fns + .long v4wb_user_fns + .long arm926_cache_fns + .size __arm926_proc_info, . - __arm926_proc_info diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S new file mode 100644 index 0000000..9137fe5 --- /dev/null +++ b/arch/arm/mm/proc-macros.S @@ -0,0 +1,51 @@ +/* + * We need constants.h for: + * VMA_VM_MM + * VMA_VM_FLAGS + * VM_EXEC + */ +#include <asm/constants.h> +#include <asm/thread_info.h> + +/* + * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm) + */ + .macro vma_vm_mm, rd, rn + ldr \rd, [\rn, #VMA_VM_MM] + .endm + +/* + * vma_vm_flags - get vma->vm_flags + */ + .macro vma_vm_flags, rd, rn + ldr \rd, [\rn, #VMA_VM_FLAGS] + .endm + + .macro tsk_mm, rd, rn + ldr \rd, [\rn, #TI_TASK] + ldr \rd, [\rd, #TSK_ACTIVE_MM] + .endm + +/* + * act_mm - get current->active_mm + */ + .macro act_mm, rd + bic \rd, sp, #8128 + bic \rd, \rd, #63 + ldr \rd, [\rd, #TI_TASK] + ldr \rd, [\rd, #TSK_ACTIVE_MM] + .endm + +/* + * mmid - get context id from mm pointer (mm->context.id) + */ + .macro mmid, rd, rn + ldr \rd, [\rn, #MM_CONTEXT_ID] + .endm + +/* + * mask_asid - mask the ASID from the context ID + */ + .macro asid, rd, rn + and \rd, \rn, #255 + .endm diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S new file mode 100644 index 0000000..360cae9 --- /dev/null +++ b/arch/arm/mm/proc-sa110.S @@ -0,0 +1,272 @@ +/* + * linux/arch/arm/mm/proc-sa110.S + * + * Copyright (C) 1997-2002 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. + * + * MMU functions for SA110 + * + * These are the low level assembler for performing cache and TLB + * functions on the StrongARM-110. + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include <asm/pgtable.h> +#include <asm/ptrace.h> + +/* + * the cache line size of the I and D cache + */ +#define DCACHELINESIZE 32 +#define FLUSH_OFFSET 32768 + + .macro flush_110_dcache rd, ra, re + ldr \rd, =flush_base + ldr \ra, [\rd] + eor \ra, \ra, #FLUSH_OFFSET + str \ra, [\rd] + add \re, \ra, #16384 @ only necessary for 16k +1001: ldr \rd, [\ra], #DCACHELINESIZE + teq \re, \ra + bne 1001b + .endm + + .data +flush_base: + .long FLUSH_BASE + .text + +/* + * cpu_sa110_proc_init() + */ +ENTRY(cpu_sa110_proc_init) + mov r0, #0 + mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching + mov pc, lr + +/* + * cpu_sa110_proc_fin() + */ +ENTRY(cpu_sa110_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl v4wb_flush_kern_cache_all @ clean caches +1: mov r0, #0 + mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_sa110_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_sa110_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_sa110_do_idle(type) + * + * Cause the processor to idle + * + * type: call type: + * 0 = slow idle + * 1 = fast idle + * 2 = switch to slow processor clock + * 3 = switch to fast processor clock + */ + .align 5 + +ENTRY(cpu_sa110_do_idle) + mcr p15, 0, ip, c15, c2, 2 @ disable clock switching + ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc + ldr r1, [r1, #0] @ force switch to MCLK + mov r0, r0 @ safety + mov r0, r0 @ safety + mov r0, r0 @ safety + mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned + mov r0, r0 @ safety + mov r0, r0 @ safety + mov r0, r0 @ safety + mcr p15, 0, r0, c15, c1, 2 @ enable clock switching + mov pc, lr + +/* ================================= CACHE ================================ */ + +/* + * cpu_sa110_dcache_clean_area(addr,sz) + * + * Clean the specified entry of any caches such that the MMU + * translation fetches will obtain correct data. + * + * addr: cache-unaligned virtual address + */ + .align 5 +ENTRY(cpu_sa110_dcache_clean_area) +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #DCACHELINESIZE + bhi 1b + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_sa110_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_sa110_switch_mm) + flush_110_dcache r3, ip, r1 + mov r1, #0 + mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_sa110_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_sa110_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __sa110_setup, #function +__sa110_setup: + mov r10, #0 + mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v4 + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, sa110_cr1_clear + bic r0, r0, r5 + ldr r5, sa110_cr1_set + orr r0, r0, r5 + mov pc, lr + .size __sa110_setup, . - __sa110_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * ..01 0001 ..11 1101 + * + */ + .type sa110_cr1_clear, #object + .type sa110_cr1_set, #object +sa110_cr1_clear: + .word 0x3f3f +sa110_cr1_set: + .word 0x113d + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + + .type sa110_processor_functions, #object +ENTRY(sa110_processor_functions) + .word v4_early_abort + .word cpu_sa110_proc_init + .word cpu_sa110_proc_fin + .word cpu_sa110_reset + .word cpu_sa110_do_idle + .word cpu_sa110_dcache_clean_area + .word cpu_sa110_switch_mm + .word cpu_sa110_set_pte + .size sa110_processor_functions, . - sa110_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_sa110_name, #object +cpu_sa110_name: + .asciz "StrongARM-110" + .size cpu_sa110_name, . - cpu_sa110_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __sa110_proc_info,#object +__sa110_proc_info: + .long 0x4401a100 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __sa110_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT + .long cpu_sa110_name + .long sa110_processor_functions + .long v4wb_tlb_fns + .long v4wb_user_fns + .long v4wb_cache_fns + .size __sa110_proc_info, . - __sa110_proc_info diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S new file mode 100644 index 0000000..d447cd5 --- /dev/null +++ b/arch/arm/mm/proc-sa1100.S @@ -0,0 +1,323 @@ +/* + * linux/arch/arm/mm/proc-sa1100.S + * + * Copyright (C) 1997-2002 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. + * + * MMU functions for SA110 + * + * These are the low level assembler for performing cache and TLB + * functions on the StrongARM-1100 and StrongARM-1110. + * + * Note that SA1100 and SA1110 share everything but their name and CPU ID. + * + * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl): + * Flush the read buffer at context switches + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include <asm/pgtable.h> + +/* + * the cache line size of the I and D cache + */ +#define DCACHELINESIZE 32 +#define FLUSH_OFFSET 32768 + + .macro flush_1100_dcache rd, ra, re + ldr \rd, =flush_base + ldr \ra, [\rd] + eor \ra, \ra, #FLUSH_OFFSET + str \ra, [\rd] + add \re, \ra, #8192 @ only necessary for 8k +1001: ldr \rd, [\ra], #DCACHELINESIZE + teq \re, \ra + bne 1001b +#ifdef FLUSH_BASE_MINICACHE + add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE + add \re, \ra, #512 @ only 512 bytes +1002: ldr \rd, [\ra], #DCACHELINESIZE + teq \re, \ra + bne 1002b +#endif + .endm + + .data +flush_base: + .long FLUSH_BASE + .text + + __INIT + +/* + * cpu_sa1100_proc_init() + */ +ENTRY(cpu_sa1100_proc_init) + mov r0, #0 + mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching + mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland + mov pc, lr + + .previous + +/* + * cpu_sa1100_proc_fin() + * + * Prepare the CPU for reset: + * - Disable interrupts + * - Clean and turn off caches. + */ +ENTRY(cpu_sa1100_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + flush_1100_dcache r0, r1, r2 @ clean caches + mov r0, #0 + mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1000 @ ...i............ + bic r0, r0, #0x000e @ ............wca. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_sa1100_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_sa1100_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x1100 @ ...i...s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_sa1100_do_idle(type) + * + * Cause the processor to idle + * + * type: call type: + * 0 = slow idle + * 1 = fast idle + * 2 = switch to slow processor clock + * 3 = switch to fast processor clock + */ + .align 5 +ENTRY(cpu_sa1100_do_idle) + mov r0, r0 @ 4 nop padding + mov r0, r0 + mov r0, r0 + mov r0, r0 @ 4 nop padding + mov r0, r0 + mov r0, r0 + mov r0, #0 + ldr r1, =UNCACHEABLE_ADDR @ ptr to uncacheable address + @ --- aligned to a cache line + mcr p15, 0, r0, c15, c2, 2 @ disable clock switching + ldr r1, [r1, #0] @ force switch to MCLK + mcr p15, 0, r0, c15, c8, 2 @ wait for interrupt + mov r0, r0 @ safety + mcr p15, 0, r0, c15, c1, 2 @ enable clock switching + mov pc, lr + +/* ================================= CACHE ================================ */ + +/* + * cpu_sa1100_dcache_clean_area(addr,sz) + * + * Clean the specified entry of any caches such that the MMU + * translation fetches will obtain correct data. + * + * addr: cache-unaligned virtual address + */ + .align 5 +ENTRY(cpu_sa1100_dcache_clean_area) +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #DCACHELINESIZE + subs r1, r1, #DCACHELINESIZE + bhi 1b + mov pc, lr + +/* =============================== PageTable ============================== */ + +/* + * cpu_sa1100_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_sa1100_switch_mm) + flush_1100_dcache r3, ip, r1 + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c9, c0, 0 @ invalidate RB + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, lr + +/* + * cpu_sa1100_set_pte(ptep, pte) + * + * Set a PTE and flush it out + */ + .align 5 +ENTRY(cpu_sa1100_set_pte) + str r1, [r0], #-2048 @ linux version + + eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + bic r2, r1, #PTE_SMALL_AP_MASK + bic r2, r2, #PTE_TYPE_MASK + orr r2, r2, #PTE_TYPE_SMALL + + tst r1, #L_PTE_USER @ User? + orrne r2, r2, #PTE_SMALL_AP_URO_SRW + + tst r1, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_SMALL_AP_UNO_SRW + + tst r1, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 + + str r2, [r0] @ hardware version + mov r0, r0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __sa1100_setup, #function +__sa1100_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 + mrc p15, 0, r0, c1, c0 @ get control register v4 + ldr r5, sa1100_cr1_clear + bic r0, r0, r5 + ldr r5, sa1100_cr1_set + orr r0, r0, r5 + mov pc, lr + .size __sa1100_setup, . - __sa1100_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * ..11 0001 ..11 1101 + * + */ + .type sa1100_cr1_clear, #object + .type sa1100_cr1_set, #object +sa1100_cr1_clear: + .word 0x3f3f +sa1100_cr1_set: + .word 0x313d + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + +/* + * SA1100 and SA1110 share the same function calls + */ + .type sa1100_processor_functions, #object +ENTRY(sa1100_processor_functions) + .word v4_early_abort + .word cpu_sa1100_proc_init + .word cpu_sa1100_proc_fin + .word cpu_sa1100_reset + .word cpu_sa1100_do_idle + .word cpu_sa1100_dcache_clean_area + .word cpu_sa1100_switch_mm + .word cpu_sa1100_set_pte + .size sa1100_processor_functions, . - sa1100_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_sa1100_name, #object +cpu_sa1100_name: + .asciz "StrongARM-1100" + .size cpu_sa1100_name, . - cpu_sa1100_name + + .type cpu_sa1110_name, #object +cpu_sa1110_name: + .asciz "StrongARM-1110" + .size cpu_sa1110_name, . - cpu_sa1110_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __sa1100_proc_info,#object +__sa1100_proc_info: + .long 0x4401a110 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __sa1100_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT + .long cpu_sa1100_name + .long sa1100_processor_functions + .long v4wb_tlb_fns + .long v4_mc_user_fns + .long v4wb_cache_fns + .size __sa1100_proc_info, . - __sa1100_proc_info + + .type __sa1110_proc_info,#object +__sa1110_proc_info: + .long 0x6901b110 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __sa1100_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT + .long cpu_sa1110_name + .long sa1100_processor_functions + .long v4wb_tlb_fns + .long v4_mc_user_fns + .long v4wb_cache_fns + .size __sa1110_proc_info, . - __sa1110_proc_info diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c new file mode 100644 index 0000000..6c5f0fe --- /dev/null +++ b/arch/arm/mm/proc-syms.c @@ -0,0 +1,40 @@ +/* + * linux/arch/arm/mm/proc-syms.c + * + * Copyright (C) 2000-2002 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/module.h> +#include <linux/mm.h> + +#include <asm/cacheflush.h> +#include <asm/proc-fns.h> +#include <asm/tlbflush.h> + +#ifndef MULTI_CPU +EXPORT_SYMBOL(cpu_dcache_clean_area); +EXPORT_SYMBOL(cpu_set_pte); +#else +EXPORT_SYMBOL(processor); +#endif + +#ifndef MULTI_CACHE +EXPORT_SYMBOL(__cpuc_flush_kern_all); +EXPORT_SYMBOL(__cpuc_flush_user_all); +EXPORT_SYMBOL(__cpuc_flush_user_range); +EXPORT_SYMBOL(__cpuc_coherent_kern_range); +#else +EXPORT_SYMBOL(cpu_cache); +#endif + +/* + * No module should need to touch the TLB (and currently + * no modules do. We export this for "loadkernel" support + * (booting a new kernel from within a running kernel.) + */ +#ifdef MULTI_TLB +EXPORT_SYMBOL(cpu_tlb); +#endif diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S new file mode 100644 index 0000000..0aa73d4 --- /dev/null +++ b/arch/arm/mm/proc-v6.S @@ -0,0 +1,272 @@ +/* + * linux/arch/arm/mm/proc-v6.S + * + * Copyright (C) 2001 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 version 2 as + * published by the Free Software Foundation. + * + * This is the "shell" of the ARMv6 processor support. + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include <asm/constants.h> +#include <asm/procinfo.h> +#include <asm/pgtable.h> + +#include "proc-macros.S" + +#define D_CACHE_LINE_SIZE 32 + + .macro cpsie, flags + .ifc \flags, f + .long 0xf1080040 + .exitm + .endif + .ifc \flags, i + .long 0xf1080080 + .exitm + .endif + .ifc \flags, if + .long 0xf10800c0 + .exitm + .endif + .err + .endm + + .macro cpsid, flags + .ifc \flags, f + .long 0xf10c0040 + .exitm + .endif + .ifc \flags, i + .long 0xf10c0080 + .exitm + .endif + .ifc \flags, if + .long 0xf10c00c0 + .exitm + .endif + .err + .endm + +ENTRY(cpu_v6_proc_init) + mov pc, lr + +ENTRY(cpu_v6_proc_fin) + mov pc, lr + +/* + * cpu_v6_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * - loc - location to jump to for soft reset + * + * It is assumed that: + */ + .align 5 +ENTRY(cpu_v6_reset) + mov pc, r0 + +/* + * cpu_v6_do_idle() + * + * Idle the processor (eg, wait for interrupt). + * + * IRQs are already disabled. + */ +ENTRY(cpu_v6_do_idle) + mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt + mov pc, lr + +ENTRY(cpu_v6_dcache_clean_area) +#ifndef TLB_CAN_READ_FROM_L1_CACHE +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #D_CACHE_LINE_SIZE + subs r1, r1, #D_CACHE_LINE_SIZE + bhi 1b +#endif + mov pc, lr + +/* + * cpu_arm926_switch_mm(pgd_phys, tsk) + * + * Set the translation table base pointer to be pgd_phys + * + * - pgd_phys - physical address of new TTB + * + * It is assumed that: + * - we are not using split page tables + */ +ENTRY(cpu_v6_switch_mm) + mov r2, #0 + ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id + mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB + mcr p15, 0, r2, c7, c10, 4 @ drain write buffer + mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 + mcr p15, 0, r1, c13, c0, 1 @ set context ID + mov pc, lr + +#define nG (1 << 11) +#define APX (1 << 9) +#define AP1 (1 << 5) +#define AP0 (1 << 4) +#define XN (1 << 0) + +/* + * cpu_v6_set_pte(ptep, pte) + * + * Set a level 2 translation table entry. + * + * - ptep - pointer to level 2 translation table entry + * (hardware version is stored at -1024 bytes) + * - pte - PTE value to store + * + * Permissions: + * YUWD APX AP1 AP0 SVC User + * 0xxx 0 0 0 no acc no acc + * 100x 1 0 1 r/o no acc + * 10x0 1 0 1 r/o no acc + * 1011 0 0 1 r/w no acc + * 110x 1 1 0 r/o r/o + * 11x0 1 1 0 r/o r/o + * 1111 0 1 1 r/w r/w + */ +ENTRY(cpu_v6_set_pte) + str r1, [r0], #-2048 @ linux version + + bic r2, r1, #0x00000ff0 + bic r2, r2, #0x00000003 + orr r2, r2, #AP0 | 2 + + tst r1, #L_PTE_WRITE + tstne r1, #L_PTE_DIRTY + orreq r2, r2, #APX + + tst r1, #L_PTE_USER + orrne r2, r2, #AP1 | nG + tstne r2, #APX + eorne r2, r2, #AP0 + + tst r1, #L_PTE_YOUNG + biceq r2, r2, #APX | AP1 | AP0 + +@ tst r1, #L_PTE_EXEC +@ orreq r2, r2, #XN + + tst r1, #L_PTE_PRESENT + moveq r2, #0 + + str r2, [r0] + mcr p15, 0, r0, c7, c10, 1 @ flush_pte + mov pc, lr + + + + +cpu_v6_name: + .asciz "Some Random V6 Processor" + .align + + .section ".text.init", #alloc, #execinstr + +/* + * __v6_setup + * + * Initialise TLB, Caches, and MMU state ready to switch the MMU + * on. Return in r0 the new CP15 C1 control register setting. + * + * We automatically detect if we have a Harvard cache, and use the + * Harvard cache control instructions insead of the unified cache + * control instructions. + * + * This should be able to cover all ARMv6 cores. + * + * It is assumed that: + * - cache type register is implemented + */ +__v6_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs + mcr p15, 0, r0, c2, c0, 2 @ TTB control register + mcr p15, 0, r4, c2, c0, 1 @ load TTB1 +#ifdef CONFIG_VFP + mrc p15, 0, r0, c1, c0, 2 + orr r0, r0, #(3 << 20) + mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP +#endif + mrc p15, 0, r0, c1, c0, 0 @ read control register + ldr r5, v6_cr1_clear @ get mask for bits to clear + bic r0, r0, r5 @ clear bits them + ldr r5, v6_cr1_set @ get mask for bits to set + orr r0, r0, r5 @ set them + mov pc, lr @ return to head.S:__ret + + /* + * V X F I D LR + * .... ...E PUI. .T.T 4RVI ZFRS BLDP WCAM + * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced + * 0 110 0011 1.00 .111 1101 < we want + */ + .type v6_cr1_clear, #object + .type v6_cr1_set, #object +v6_cr1_clear: + .word 0x01e0fb7f +v6_cr1_set: + .word 0x00c0387d + + .type v6_processor_functions, #object +ENTRY(v6_processor_functions) + .word v6_early_abort + .word cpu_v6_proc_init + .word cpu_v6_proc_fin + .word cpu_v6_reset + .word cpu_v6_do_idle + .word cpu_v6_dcache_clean_area + .word cpu_v6_switch_mm + .word cpu_v6_set_pte + .size v6_processor_functions, . - v6_processor_functions + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv6" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v6" + .size cpu_elf_name, . - cpu_elf_name + .align + + .section ".proc.info", #alloc, #execinstr + + /* + * Match any ARMv6 processor core. + */ + .type __v6_proc_info, #object +__v6_proc_info: + .long 0x0007b000 + .long 0x0007f000 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __v6_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA + .long cpu_v6_name + .long v6_processor_functions + .long v6wbi_tlb_fns + .long v6_user_fns + .long v6_cache_fns + .size __v6_proc_info, . - __v6_proc_info diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S new file mode 100644 index 0000000..2d977b4 --- /dev/null +++ b/arch/arm/mm/proc-xscale.S @@ -0,0 +1,934 @@ +/* + * linux/arch/arm/mm/proc-xscale.S + * + * Author: Nicolas Pitre + * Created: November 2000 + * Copyright: (C) 2000, 2001 MontaVista Software Inc. + * + * 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. + * + * MMU functions for the Intel XScale CPUs + * + * 2001 Aug 21: + * some contributions by Brett Gaines <brett.w.gaines@intel.com> + * Copyright 2001 by Intel Corp. + * + * 2001 Sep 08: + * Completely revisited, many important fixes + * Nicolas Pitre <nico@cam.org> + */ + +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/procinfo.h> +#include <asm/hardware.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/ptrace.h> +#include "proc-macros.S" + +/* + * 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 + */ +#define MAX_AREA_SIZE 32768 + +/* + * the cache line size of the I and D cache + */ +#define CACHELINESIZE 32 + +/* + * the size of the data cache + */ +#define CACHESIZE 32768 + +/* + * Virtual address used to allocate the cache when flushed + * + * This must be an address range which is _never_ used. It should + * apparently have a mapping in the corresponding page table for + * compatibility with future CPUs that _could_ require it. For instance we + * don't care. + * + * This must be aligned on a 2*CACHESIZE boundary. The code selects one of + * the 2 areas in alternance each time the clean_d_cache macro is used. + * Without this the XScale core exhibits cache eviction problems and no one + * knows why. + * + * Reminder: the vector table is located at 0xffff0000-0xffff0fff. + */ +#define CLEAN_ADDR 0xfffe0000 + +/* + * This macro is used to wait for a CP15 write and is needed + * when we have to ensure that the last operation to the co-pro + * was completed before continuing with operation. + */ + .macro cpwait, rd + mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 + mov \rd, \rd @ wait for completion + sub pc, pc, #4 @ flush instruction pipeline + .endm + + .macro cpwait_ret, lr, rd + mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 + sub pc, \lr, \rd, LSR #32 @ wait for completion and + @ flush instruction pipeline + .endm + +/* + * This macro cleans the entire dcache using line allocate. + * The main loop has been unrolled to reduce loop overhead. + * rd and rs are two scratch registers. + */ + .macro clean_d_cache, rd, rs + ldr \rs, =clean_addr + ldr \rd, [\rs] + eor \rd, \rd, #CACHESIZE + str \rd, [\rs] + add \rs, \rd, #CACHESIZE +1: mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line + add \rd, \rd, #CACHELINESIZE + mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line + add \rd, \rd, #CACHELINESIZE + mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line + add \rd, \rd, #CACHELINESIZE + mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line + add \rd, \rd, #CACHELINESIZE + teq \rd, \rs + bne 1b + .endm + + .data +clean_addr: .word CLEAN_ADDR + + .text + +/* + * cpu_xscale_proc_init() + * + * Nothing too exciting at the moment + */ +ENTRY(cpu_xscale_proc_init) + mov pc, lr + +/* + * cpu_xscale_proc_fin() + */ +ENTRY(cpu_xscale_proc_fin) + str lr, [sp, #-4]! + mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE + msr cpsr_c, r0 + bl xscale_flush_kern_cache_all @ clean caches + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1800 @ ...IZ........... + bic r0, r0, #0x0006 @ .............CA. + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldr pc, [sp], #4 + +/* + * cpu_xscale_reset(loc) + * + * Perform a soft reset of the system. Put the CPU into the + * same state as it would be if it had been reset, and branch + * to what would be the reset vector. + * + * loc: location to jump to for soft reset + */ + .align 5 +ENTRY(cpu_xscale_reset) + mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE + msr cpsr_c, r1 @ reset CPSR + mrc p15, 0, r1, c1, c0, 0 @ ctrl register + bic r1, r1, #0x0086 @ ........B....CA. + bic r1, r1, #0x3900 @ ..VIZ..S........ + mcr p15, 0, r1, c1, c0, 0 @ ctrl register + mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB + bic r1, r1, #0x0001 @ ...............M + mcr p15, 0, r1, c1, c0, 0 @ ctrl register + @ CAUTION: MMU turned off from this point. We count on the pipeline + @ already containing those two last instructions to survive. + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mov pc, r0 + +/* + * cpu_xscale_do_idle() + * + * Cause the processor to idle + * + * For now we do nothing but go to idle mode for every case + * + * XScale supports clock switching, but using idle mode support + * allows external hardware to react to system state changes. + */ + .align 5 + +ENTRY(cpu_xscale_do_idle) + mov r0, #1 + mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE + mov pc, lr + +/* ================================= CACHE ================================ */ + +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + */ +ENTRY(xscale_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(xscale_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: + clean_d_cache r0, r1 + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB + mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov pc, lr + +/* + * flush_user_cache_range(start, end, vm_flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - vma - vma_area_struct describing address space + */ + .align 5 +ENTRY(xscale_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #MAX_AREA_SIZE + bhs __flush_whole_cache + +1: tst r2, #VM_EXEC + mcrne p15, 0, r0, c7, c5, 1 @ Invalidate I cache line + mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line + mcr p15, 0, r0, c7, c6, 1 @ Invalidate D cache line + add r0, r0, #CACHELINESIZE + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB + mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + * + * Note: single I-cache line invalidation isn't used here since + * it also trashes the mini I-cache used by JTAG debuggers. + */ +ENTRY(xscale_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + * + * Note: single I-cache line invalidation isn't used here since + * it also trashes the mini I-cache used by JTAG debuggers. + */ +ENTRY(xscale_coherent_user_range) + bic r0, r0, #CACHELINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHELINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB + mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(xscale_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHELINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB + mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(xscale_dma_inv_range) + mrc p15, 0, r2, c0, c0, 0 @ read ID + eor r2, r2, #0x69000000 + eor r2, r2, #0x00052000 + bics r2, r2, #1 + beq xscale_dma_flush_range + + tst r0, #CACHELINESIZE - 1 + bic r0, r0, #CACHELINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHELINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHELINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(xscale_dma_clean_range) + bic r0, r0, #CACHELINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHELINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(xscale_dma_flush_range) + bic r0, r0, #CACHELINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHELINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov pc, lr + +ENTRY(xscale_cache_fns) + .long xscale_flush_kern_cache_all + .long xscale_flush_user_cache_all + .long xscale_flush_user_cache_range + .long xscale_coherent_kern_range + .long xscale_coherent_user_range + .long xscale_flush_kern_dcache_page + .long xscale_dma_inv_range + .long xscale_dma_clean_range + .long xscale_dma_flush_range + +ENTRY(cpu_xscale_dcache_clean_area) +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHELINESIZE + subs r1, r1, #CACHELINESIZE + bhi 1b + mov pc, lr + +/* ================================ CACHE LOCKING============================ + * + * The XScale MicroArchitecture implements support for locking entries into + * the data and instruction cache. The following functions implement the core + * low level instructions needed to accomplish the locking. The developer's + * manual states that the code that performs the locking must be in non-cached + * memory. To accomplish this, the code in xscale-cache-lock.c copies the + * following functions from the cache into a non-cached memory region that + * is allocated through consistent_alloc(). + * + */ + .align 5 +/* + * xscale_icache_lock + * + * r0: starting address to lock + * r1: end address to lock + */ +ENTRY(xscale_icache_lock) + +iLockLoop: + bic r0, r0, #CACHELINESIZE - 1 + mcr p15, 0, r0, c9, c1, 0 @ lock into cache + cmp r0, r1 @ are we done? + add r0, r0, #CACHELINESIZE @ advance to next cache line + bls iLockLoop + mov pc, lr + +/* + * xscale_icache_unlock + */ +ENTRY(xscale_icache_unlock) + mcr p15, 0, r0, c9, c1, 1 @ Unlock icache + mov pc, lr + +/* + * xscale_dcache_lock + * + * r0: starting address to lock + * r1: end address to lock + */ +ENTRY(xscale_dcache_lock) + mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov r2, #1 + mcr p15, 0, r2, c9, c2, 0 @ Put dcache in lock mode + cpwait ip @ Wait for completion + + mrs r2, cpsr + orr r3, r2, #PSR_F_BIT | PSR_I_BIT +dLockLoop: + msr cpsr_c, r3 + mcr p15, 0, r0, c7, c10, 1 @ Write back line if it is dirty + mcr p15, 0, r0, c7, c6, 1 @ Flush/invalidate line + msr cpsr_c, r2 + ldr ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from + @ location [r0]. Post-increment + @ r3 to next cache line + cmp r0, r1 @ Are we done? + bls dLockLoop + + mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov r2, #0 + mcr p15, 0, r2, c9, c2, 0 @ Get out of lock mode + cpwait_ret lr, ip + +/* + * xscale_dcache_unlock + */ +ENTRY(xscale_dcache_unlock) + mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer + mcr p15, 0, ip, c9, c2, 1 @ Unlock cache + mov pc, lr + +/* + * Needed to determine the length of the code that needs to be copied. + */ + .align 5 +ENTRY(xscale_cache_dummy) + mov pc, lr + +/* ================================ TLB LOCKING============================== + * + * The XScale MicroArchitecture implements support for locking entries into + * the Instruction and Data TLBs. The following functions provide the + * low level support for supporting these under Linux. xscale-lock.c + * implements some higher level management code. Most of the following + * is taken straight out of the Developer's Manual. + */ + +/* + * Lock I-TLB entry + * + * r0: Virtual address to translate and lock + */ + .align 5 +ENTRY(xscale_itlb_lock) + mrs r2, cpsr + orr r3, r2, #PSR_F_BIT | PSR_I_BIT + msr cpsr_c, r3 @ Disable interrupts + mcr p15, 0, r0, c8, c5, 1 @ Invalidate I-TLB entry + mcr p15, 0, r0, c10, c4, 0 @ Translate and lock + msr cpsr_c, r2 @ Restore interrupts + cpwait_ret lr, ip + +/* + * Lock D-TLB entry + * + * r0: Virtual address to translate and lock + */ + .align 5 +ENTRY(xscale_dtlb_lock) + mrs r2, cpsr + orr r3, r2, #PSR_F_BIT | PSR_I_BIT + msr cpsr_c, r3 @ Disable interrupts + mcr p15, 0, r0, c8, c6, 1 @ Invalidate D-TLB entry + mcr p15, 0, r0, c10, c8, 0 @ Translate and lock + msr cpsr_c, r2 @ Restore interrupts + cpwait_ret lr, ip + +/* + * Unlock all I-TLB entries + */ + .align 5 +ENTRY(xscale_itlb_unlock) + mcr p15, 0, ip, c10, c4, 1 @ Unlock I-TLB + mcr p15, 0, ip, c8, c5, 0 @ Invalidate I-TLB + cpwait_ret lr, ip + +/* + * Unlock all D-TLB entries + */ +ENTRY(xscale_dtlb_unlock) + mcr p15, 0, ip, c10, c8, 1 @ Unlock D-TBL + mcr p15, 0, ip, c8, c6, 0 @ Invalidate D-TLB + cpwait_ret lr, ip + +/* =============================== PageTable ============================== */ + +#define PTE_CACHE_WRITE_ALLOCATE 0 + +/* + * cpu_xscale_switch_mm(pgd) + * + * Set the translation base pointer to be as described by pgd. + * + * pgd: new page tables + */ + .align 5 +ENTRY(cpu_xscale_switch_mm) + clean_d_cache r1, r2 + mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB + mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + cpwait_ret lr, ip + +/* + * cpu_xscale_set_pte(ptep, pte) + * + * Set a PTE and flush it out + * + * Errata 40: must set memory to write-through for user read-only pages. + */ + .align 5 +ENTRY(cpu_xscale_set_pte) + str r1, [r0], #-2048 @ linux version + + bic r2, r1, #0xff0 + orr r2, r2, #PTE_TYPE_EXT @ extended page + + eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY + + tst r3, #L_PTE_USER @ User? + orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w + + tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? + orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w + @ combined with user -> user r/w + + @ + @ Handle the X bit. We want to set this bit for the minicache + @ (U = E = B = W = 0, C = 1) or when write allocate is enabled, + @ and we have a writeable, cacheable region. If we ignore the + @ U and E bits, we can allow user space to use the minicache as + @ well. + @ + @ X = (C & ~W & ~B) | (C & W & B & write_allocate) + @ + eor ip, r1, #L_PTE_CACHEABLE + tst ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE +#if PTE_CACHE_WRITE_ALLOCATE + eorne ip, r1, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE + tstne ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE +#endif + orreq r2, r2, #PTE_EXT_TEX(1) + + @ + @ Erratum 40: The B bit must be cleared for a user read-only + @ cacheable page. + @ + @ B = B & ~(U & C & ~W) + @ + and ip, r1, #L_PTE_USER | L_PTE_WRITE | L_PTE_CACHEABLE + teq ip, #L_PTE_USER | L_PTE_CACHEABLE + biceq r2, r2, #PTE_BUFFERABLE + + tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? + movne r2, #0 @ no -> fault + + str r2, [r0] @ hardware version + mov ip, #0 + mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line + mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer + mov pc, lr + + + .ltorg + + .align + + __INIT + + .type __xscale_setup, #function +__xscale_setup: + mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB + mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs +#ifdef CONFIG_IWMMXT + mov r0, #0 @ initially disallow access to CP0/CP1 +#else + mov r0, #1 @ Allow access to CP0 +#endif + orr r0, r0, #1 << 6 @ cp6 for IOP3xx and Bulverde + orr r0, r0, #1 << 13 @ Its undefined whether this + mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes + mrc p15, 0, r0, c1, c0, 0 @ get control register + ldr r5, xscale_cr1_clear + bic r0, r0, r5 + ldr r5, xscale_cr1_set + orr r0, r0, r5 + mov pc, lr + .size __xscale_setup, . - __xscale_setup + + /* + * R + * .RVI ZFRS BLDP WCAM + * ..11 1.01 .... .101 + * + */ + .type xscale_cr1_clear, #object + .type xscale_cr1_set, #object +xscale_cr1_clear: + .word 0x3b07 +xscale_cr1_set: + .word 0x3905 + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + + .type xscale_processor_functions, #object +ENTRY(xscale_processor_functions) + .word v5t_early_abort + .word cpu_xscale_proc_init + .word cpu_xscale_proc_fin + .word cpu_xscale_reset + .word cpu_xscale_do_idle + .word cpu_xscale_dcache_clean_area + .word cpu_xscale_switch_mm + .word cpu_xscale_set_pte + .size xscale_processor_functions, . - xscale_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5te" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_80200_name, #object +cpu_80200_name: + .asciz "XScale-80200" + .size cpu_80200_name, . - cpu_80200_name + + .type cpu_8032x_name, #object +cpu_8032x_name: + .asciz "XScale-IOP8032x Family" + .size cpu_8032x_name, . - cpu_8032x_name + + .type cpu_8033x_name, #object +cpu_8033x_name: + .asciz "XScale-IOP8033x Family" + .size cpu_8033x_name, . - cpu_8033x_name + + .type cpu_pxa250_name, #object +cpu_pxa250_name: + .asciz "XScale-PXA250" + .size cpu_pxa250_name, . - cpu_pxa250_name + + .type cpu_pxa210_name, #object +cpu_pxa210_name: + .asciz "XScale-PXA210" + .size cpu_pxa210_name, . - cpu_pxa210_name + + .type cpu_ixp42x_name, #object +cpu_ixp42x_name: + .asciz "XScale-IXP42x Family" + .size cpu_ixp42x_name, . - cpu_ixp42x_name + + .type cpu_ixp46x_name, #object +cpu_ixp46x_name: + .asciz "XScale-IXP46x Family" + .size cpu_ixp46x_name, . - cpu_ixp46x_name + + .type cpu_ixp2400_name, #object +cpu_ixp2400_name: + .asciz "XScale-IXP2400" + .size cpu_ixp2400_name, . - cpu_ixp2400_name + + .type cpu_ixp2800_name, #object +cpu_ixp2800_name: + .asciz "XScale-IXP2800" + .size cpu_ixp2800_name, . - cpu_ixp2800_name + + .type cpu_pxa255_name, #object +cpu_pxa255_name: + .asciz "XScale-PXA255" + .size cpu_pxa255_name, . - cpu_pxa255_name + + .type cpu_pxa270_name, #object +cpu_pxa270_name: + .asciz "XScale-PXA270" + .size cpu_pxa270_name, . - cpu_pxa270_name + + .align + + .section ".proc.info", #alloc, #execinstr + + .type __80200_proc_info,#object +__80200_proc_info: + .long 0x69052000 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_80200_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __80200_proc_info, . - __80200_proc_info + + .type __8032x_proc_info,#object +__8032x_proc_info: + .long 0x69052420 + .long 0xfffff5e0 @ mask should accomodate IOP80219 also + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_8032x_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __8032x_proc_info, . - __8032x_proc_info + + .type __8033x_proc_info,#object +__8033x_proc_info: + .long 0x69054010 + .long 0xffffff30 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_8033x_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __8033x_proc_info, . - __8033x_proc_info + + .type __pxa250_proc_info,#object +__pxa250_proc_info: + .long 0x69052100 + .long 0xfffff7f0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_pxa250_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __pxa250_proc_info, . - __pxa250_proc_info + + .type __pxa210_proc_info,#object +__pxa210_proc_info: + .long 0x69052120 + .long 0xfffff3f0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_pxa210_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __pxa210_proc_info, . - __pxa210_proc_info + + .type __ixp2400_proc_info, #object +__ixp2400_proc_info: + .long 0x69054190 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_ixp2400_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __ixp2400_proc_info, . - __ixp2400_proc_info + + .type __ixp2800_proc_info, #object +__ixp2800_proc_info: + .long 0x690541a0 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_ixp2800_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __ixp2800_proc_info, . - __ixp2800_proc_info + + .type __ixp42x_proc_info, #object +__ixp42x_proc_info: + .long 0x690541c0 + .long 0xffffffc0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_ixp42x_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __ixp42x_proc_info, . - __ixp42x_proc_info + + .type __ixp46x_proc_info, #object +__ixp46x_proc_info: + .long 0x69054200 + .long 0xffffff00 + .long 0x00000c0e + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_ixp46x_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __ixp46x_proc_info, . - __ixp46x_proc_info + + .type __pxa255_proc_info,#object +__pxa255_proc_info: + .long 0x69052d00 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_pxa255_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __pxa255_proc_info, . - __pxa255_proc_info + + .type __pxa270_proc_info,#object +__pxa270_proc_info: + .long 0x69054110 + .long 0xfffffff0 + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_pxa270_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_cache_fns + .size __pxa270_proc_info, . - __pxa270_proc_info + diff --git a/arch/arm/mm/tlb-v3.S b/arch/arm/mm/tlb-v3.S new file mode 100644 index 0000000..44b0dae --- /dev/null +++ b/arch/arm/mm/tlb-v3.S @@ -0,0 +1,52 @@ +/* + * linux/arch/arm/mm/tlbv3.S + * + * Copyright (C) 1997-2002 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. + * + * ARM architecture version 3 TLB handling functions. + * + * Processors: ARM610, ARM710. + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> +#include <asm/tlbflush.h> +#include "proc-macros.S" + + .align 5 +/* + * v3_flush_user_tlb_range(start, end, mm) + * + * Invalidate a range of TLB entries in the specified address space. + * + * - start - range start address + * - end - range end address + * - mm - mm_struct describing address space + */ + .align 5 +ENTRY(v3_flush_user_tlb_range) + vma_vm_mm r2, r2 + act_mm r3 @ get current->active_mm + teq r2, r3 @ == mm ? + movne pc, lr @ no, we dont do anything +ENTRY(v3_flush_kern_tlb_range) + bic r0, r0, #0x0ff + bic r0, r0, #0xf00 +1: mcr p15, 0, r0, c6, c0, 0 @ invalidate TLB entry + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + + __INITDATA + + .type v3_tlb_fns, #object +ENTRY(v3_tlb_fns) + .long v3_flush_user_tlb_range + .long v3_flush_kern_tlb_range + .long v3_tlb_flags + .size v3_tlb_fns, . - v3_tlb_fns diff --git a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S new file mode 100644 index 0000000..db82ee4 --- /dev/null +++ b/arch/arm/mm/tlb-v4.S @@ -0,0 +1,65 @@ +/* + * linux/arch/arm/mm/tlbv4.S + * + * Copyright (C) 1997-2002 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. + * + * ARM architecture version 4 TLB handling functions. + * These assume a split I/D TLBs, and no write buffer. + * + * Processors: ARM720T + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> +#include <asm/tlbflush.h> +#include "proc-macros.S" + + .align 5 +/* + * v4_flush_user_tlb_range(start, end, mm) + * + * Invalidate a range of TLB entries in the specified user address space. + * + * - start - range start address + * - end - range end address + * - mm - mm_struct describing address space + */ + .align 5 +ENTRY(v4_flush_user_tlb_range) + vma_vm_mm ip, r2 + act_mm r3 @ get current->active_mm + eors r3, ip, r3 @ == mm ? + movne pc, lr @ no, we dont do anything +.v4_flush_kern_tlb_range: + bic r0, r0, #0x0ff + bic r0, r0, #0xf00 +1: mcr p15, 0, r0, c8, c7, 1 @ invalidate TLB entry + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + +/* + * v4_flush_kern_tlb_range(start, end) + * + * Invalidate a range of TLB entries in the specified kernel + * address range. + * + * - start - virtual address (may not be aligned) + * - end - virtual address (may not be aligned) + */ +.globl v4_flush_kern_tlb_range +.equ v4_flush_kern_tlb_range, .v4_flush_kern_tlb_range + + __INITDATA + + .type v4_tlb_fns, #object +ENTRY(v4_tlb_fns) + .long v4_flush_user_tlb_range + .long v4_flush_kern_tlb_range + .long v4_tlb_flags + .size v4_tlb_fns, . - v4_tlb_fns diff --git a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S new file mode 100644 index 0000000..7908d5f --- /dev/null +++ b/arch/arm/mm/tlb-v4wb.S @@ -0,0 +1,77 @@ +/* + * linux/arch/arm/mm/tlbv4wb.S + * + * Copyright (C) 1997-2002 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. + * + * ARM architecture version 4 TLB handling functions. + * These assume a split I/D TLBs w/o I TLB entry, with a write buffer. + * + * Processors: SA110 SA1100 SA1110 + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> +#include <asm/tlbflush.h> +#include "proc-macros.S" + + .align 5 +/* + * v4wb_flush_user_tlb_range(start, end, mm) + * + * Invalidate a range of TLB entries in the specified address space. + * + * - start - range start address + * - end - range end address + * - mm - mm_struct describing address space + */ + .align 5 +ENTRY(v4wb_flush_user_tlb_range) + vma_vm_mm ip, r2 + act_mm r3 @ get current->active_mm + eors r3, ip, r3 @ == mm ? + movne pc, lr @ no, we dont do anything + vma_vm_flags r2, r2 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + tst r2, #VM_EXEC + mcrne p15, 0, r3, c8, c5, 0 @ invalidate I TLB + bic r0, r0, #0x0ff + bic r0, r0, #0xf00 +1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + +/* + * v4_flush_kern_tlb_range(start, end) + * + * Invalidate a range of TLB entries in the specified kernel + * address range. + * + * - start - virtual address (may not be aligned) + * - end - virtual address (may not be aligned) + */ +ENTRY(v4wb_flush_kern_tlb_range) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + bic r0, r0, #0x0ff + bic r0, r0, #0xf00 + mcr p15, 0, r3, c8, c5, 0 @ invalidate I TLB +1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + + __INITDATA + + .type v4wb_tlb_fns, #object +ENTRY(v4wb_tlb_fns) + .long v4wb_flush_user_tlb_range + .long v4wb_flush_kern_tlb_range + .long v4wb_tlb_flags + .size v4wb_tlb_fns, . - v4wb_tlb_fns diff --git a/arch/arm/mm/tlb-v4wbi.S b/arch/arm/mm/tlb-v4wbi.S new file mode 100644 index 0000000..efbe94b --- /dev/null +++ b/arch/arm/mm/tlb-v4wbi.S @@ -0,0 +1,68 @@ +/* + * linux/arch/arm/mm/tlbv4wbi.S + * + * Copyright (C) 1997-2002 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. + * + * ARM architecture version 4 and version 5 TLB handling functions. + * These assume a split I/D TLBs, with a write buffer. + * + * Processors: ARM920 ARM922 ARM925 ARM926 XScale + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> +#include <asm/tlbflush.h> +#include "proc-macros.S" + +/* + * v4wb_flush_user_tlb_range(start, end, mm) + * + * Invalidate a range of TLB entries in the specified address space. + * + * - start - range start address + * - end - range end address + * - mm - mm_struct describing address space + */ + .align 5 +ENTRY(v4wbi_flush_user_tlb_range) + vma_vm_mm ip, r2 + act_mm r3 @ get current->active_mm + eors r3, ip, r3 @ == mm ? + movne pc, lr @ no, we dont do anything + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + vma_vm_flags r2, r2 + bic r0, r0, #0x0ff + bic r0, r0, #0xf00 +1: tst r2, #VM_EXEC + mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + +ENTRY(v4wbi_flush_kern_tlb_range) + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB + bic r0, r0, #0x0ff + bic r0, r0, #0xf00 +1: mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry + mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + + __INITDATA + + .type v4wbi_tlb_fns, #object +ENTRY(v4wbi_tlb_fns) + .long v4wbi_flush_user_tlb_range + .long v4wbi_flush_kern_tlb_range + .long v4wbi_tlb_flags + .size v4wbi_tlb_fns, . - v4wbi_tlb_fns diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S new file mode 100644 index 0000000..99ed26e --- /dev/null +++ b/arch/arm/mm/tlb-v6.S @@ -0,0 +1,92 @@ +/* + * linux/arch/arm/mm/tlb-v6.S + * + * Copyright (C) 1997-2002 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. + * + * ARM architecture version 6 TLB handling functions. + * These assume a split I/D TLB. + */ +#include <linux/linkage.h> +#include <asm/constants.h> +#include <asm/page.h> +#include <asm/tlbflush.h> +#include "proc-macros.S" + +#define HARVARD_TLB + +/* + * v6wbi_flush_user_tlb_range(start, end, vma) + * + * Invalidate a range of TLB entries in the specified address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - vma - vma_struct describing address range + * + * It is assumed that: + * - the "Invalidate single entry" instruction will invalidate + * both the I and the D TLBs on Harvard-style TLBs + */ +ENTRY(v6wbi_flush_user_tlb_range) + vma_vm_mm r3, r2 @ get vma->vm_mm + mov ip, #0 + mmid r3, r3 @ get vm_mm->context.id + mcr p15, 0, ip, c7, c10, 4 @ drain write buffer + mov r0, r0, lsr #PAGE_SHIFT @ align address + mov r1, r1, lsr #PAGE_SHIFT + asid r3, r3 @ mask ASID + orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA + mov r1, r1, lsl #PAGE_SHIFT + vma_vm_flags r2, r2 @ get vma->vm_flags +1: +#ifdef HARVARD_TLB + mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA (was 1) + tst r2, #VM_EXEC @ Executable area ? + mcrne p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA (was 1) +#else + mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate MVA (was 1) +#endif + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + +/* + * v6wbi_flush_kern_tlb_range(start,end) + * + * Invalidate a range of kernel TLB entries + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + */ +ENTRY(v6wbi_flush_kern_tlb_range) + mov r2, #0 + mcr p15, 0, r2, c7, c10, 4 @ drain write buffer + mov r0, r0, lsr #PAGE_SHIFT @ align address + mov r1, r1, lsr #PAGE_SHIFT + mov r0, r0, lsl #PAGE_SHIFT + mov r1, r1, lsl #PAGE_SHIFT +1: +#ifdef HARVARD_TLB + mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA + mcr p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA +#else + mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate MVA +#endif + add r0, r0, #PAGE_SZ + cmp r0, r1 + blo 1b + mov pc, lr + + .section ".text.init", #alloc, #execinstr + + .type v6wbi_tlb_fns, #object +ENTRY(v6wbi_tlb_fns) + .long v6wbi_flush_user_tlb_range + .long v6wbi_flush_kern_tlb_range + .long v6wbi_tlb_flags + .size v6wbi_tlb_fns, . - v6wbi_tlb_fns diff --git a/arch/arm/nwfpe/ARM-gcc.h b/arch/arm/nwfpe/ARM-gcc.h new file mode 100644 index 0000000..e659847 --- /dev/null +++ b/arch/arm/nwfpe/ARM-gcc.h @@ -0,0 +1,120 @@ +/* +------------------------------------------------------------------------------- +The macro `BITS64' can be defined to indicate that 64-bit integer types are +supported by the compiler. +------------------------------------------------------------------------------- +*/ +#define BITS64 + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines the most convenient type that holds +integers of at least as many bits as specified. For example, `uint8' should +be the most convenient type that can hold unsigned integers of as many as +8 bits. The `flag' type must be able to hold either a 0 or 1. For most +implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +to the same as `int'. +------------------------------------------------------------------------------- +*/ +typedef char flag; +typedef unsigned char uint8; +typedef signed char int8; +typedef int uint16; +typedef int int16; +typedef unsigned int uint32; +typedef signed int int32; +#ifdef BITS64 +typedef unsigned long long int bits64; +typedef signed long long int sbits64; +#endif + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines a type that holds integers +of _exactly_ the number of bits specified. For instance, for most +implementation of C, `bits16' and `sbits16' should be `typedef'ed to +`unsigned short int' and `signed short int' (or `short int'), respectively. +------------------------------------------------------------------------------- +*/ +typedef unsigned char bits8; +typedef signed char sbits8; +typedef unsigned short int bits16; +typedef signed short int sbits16; +typedef unsigned int bits32; +typedef signed int sbits32; +#ifdef BITS64 +typedef unsigned long long int uint64; +typedef signed long long int int64; +#endif + +#ifdef BITS64 +/* +------------------------------------------------------------------------------- +The `LIT64' macro takes as its argument a textual integer literal and if +necessary ``marks'' the literal as having a 64-bit integer type. For +example, the Gnu C Compiler (`gcc') requires that 64-bit literals be +appended with the letters `LL' standing for `long long', which is `gcc's +name for the 64-bit integer type. Some compilers may allow `LIT64' to be +defined as the identity macro: `#define LIT64( a ) a'. +------------------------------------------------------------------------------- +*/ +#define LIT64( a ) a##LL +#endif + +/* +------------------------------------------------------------------------------- +The macro `INLINE' can be used before functions that should be inlined. If +a compiler does not support explicit inlining, this macro should be defined +to be `static'. +------------------------------------------------------------------------------- +*/ +#define INLINE extern __inline__ + + +/* For use as a GCC soft-float library we need some special function names. */ + +#ifdef __LIBFLOAT__ + +/* Some 32-bit ops can be mapped straight across by just changing the name. */ +#define float32_add __addsf3 +#define float32_sub __subsf3 +#define float32_mul __mulsf3 +#define float32_div __divsf3 +#define int32_to_float32 __floatsisf +#define float32_to_int32_round_to_zero __fixsfsi +#define float32_to_uint32_round_to_zero __fixunssfsi + +/* These ones go through the glue code. To avoid namespace pollution + we rename the internal functions too. */ +#define float32_eq ___float32_eq +#define float32_le ___float32_le +#define float32_lt ___float32_lt + +/* All the 64-bit ops have to go through the glue, so we pull the same + trick. */ +#define float64_add ___float64_add +#define float64_sub ___float64_sub +#define float64_mul ___float64_mul +#define float64_div ___float64_div +#define int32_to_float64 ___int32_to_float64 +#define float64_to_int32_round_to_zero ___float64_to_int32_round_to_zero +#define float64_to_uint32_round_to_zero ___float64_to_uint32_round_to_zero +#define float64_to_float32 ___float64_to_float32 +#define float32_to_float64 ___float32_to_float64 +#define float64_eq ___float64_eq +#define float64_le ___float64_le +#define float64_lt ___float64_lt + +#if 0 +#define float64_add __adddf3 +#define float64_sub __subdf3 +#define float64_mul __muldf3 +#define float64_div __divdf3 +#define int32_to_float64 __floatsidf +#define float64_to_int32_round_to_zero __fixdfsi +#define float64_to_uint32_round_to_zero __fixunsdfsi +#define float64_to_float32 __truncdfsf2 +#define float32_to_float64 __extendsfdf2 +#endif + +#endif diff --git a/arch/arm/nwfpe/ChangeLog b/arch/arm/nwfpe/ChangeLog new file mode 100644 index 0000000..eeb5a7c --- /dev/null +++ b/arch/arm/nwfpe/ChangeLog @@ -0,0 +1,91 @@ +2003-03-22 Ralph Siemsen <ralphs@netwinder.org> + * Reformat all but softfloat files to get a consistent coding style. + Used "indent -kr -i8 -ts8 -sob -l132 -ss" and a few manual fixups. + * Removed dead code and fixed function protypes to match definitions. + * Consolidated use of (opcode && MASK_ARITHMETIC_OPCODE) >> 20. + * Make 80-bit precision a compile-time option. (1%) + * Only initialize FPE state once in repeat-FP situations. (6%) + +2002-01-19 Russell King <rmk@arm.linux.org.uk> + + * fpa11.h - Add documentation + - remove userRegisters pointer from this structure. + - add new method to obtain integer register values. + * softfloat.c - Remove float128 + * softfloat.h - Remove float128 + * softfloat-specialize - Remove float128 + + * The FPA11 structure is not a kernel-specific data structure. + It is used by users of ptrace to examine the values of the + floating point registers. Therefore, any changes to the + FPA11 structure (size or position of elements contained + within) have to be well thought out. + + * Since 128-bit float requires the FPA11 structure to change + size, it has been removed. 128-bit float is currently unused, + and needs various things to be re-worked so that we won't + overflow the available space in the task structure. + + * The changes are designed to break any patch that goes on top + of this code, so that the authors properly review their changes. + +1999-08-19 Scott Bambrough <scottb@netwinder.org> + + * fpmodule.c - Changed version number to 0.95 + * fpa11.h - modified FPA11, FPREG structures + * fpa11.c - Changes due to FPA11, FPREG structure alterations. + * fpa11_cpdo.c - Changes due to FPA11, FPREG structure alterations. + * fpa11_cpdt.c - Changes due to FPA11, FPREG structure alterations. + * fpa11_cprt.c - Changes due to FPA11, FPREG structure alterations. + * single_cpdo.c - Changes due to FPA11, FPREG structure alterations. + * double_cpdo.c - Changes due to FPA11, FPREG structure alterations. + * extended_cpdo.c - Changes due to FPA11, FPREG structure alterations. + + * I discovered several bugs. First and worst is that the kernel + passes in a pointer to the FPE's state area. This is defined + as a struct user_fp (see user.h). This pointer was cast to a + FPA11*. Unfortunately FPA11 and user_fp are of different sizes; + user_fp is smaller. This meant that the FPE scribbled on things + below its area, which is bad, as the area is in the thread_struct + embedded in the process task structure. Thus we were scribbling + over one of the most important structures in the entire OS. + + * user_fp and FPA11 have now been harmonized. Most of the changes + in the above code were dereferencing problems due to moving the + register type out of FPREG, and getting rid of the union variable + fpvalue. + + * Second I noticed resetFPA11 was not always being called for a + task. This should happen on the first floating point exception + that occurs. It is controlled by init_flag in FPA11. The + comment in the code beside init_flag state the kernel guarantees + this to be zero. Not so. I found that the kernel recycles task + structures, and that recycled ones may not have init_flag zeroed. + I couldn't even find anything that guarantees it is zeroed when + when the task structure is initially allocated. In any case + I now initialize the entire FPE state in the thread structure to + zero when allocated and recycled. See alloc_task_struct() and + flush_thread() in arch/arm/process.c. The change to + alloc_task_struct() may not be necessary, but I left it in for + completeness (better safe than sorry). + +1998-11-23 Scott Bambrough <scottb@netwinder.org> + + * README.FPE - fix typo in description of lfm/sfm instructions + * NOTES - Added file to describe known bugs/problems + * fpmodule.c - Changed version number to 0.94 + +1998-11-20 Scott Bambrough <scottb@netwinder.org> + + * README.FPE - fix description of URD, NRM instructions + * TODO - remove URD, NRM instructions from TODO list + * single_cpdo.c - implement URD, NRM + * double_cpdo.c - implement URD, NRM + * extended_cpdo.c - implement URD, NRM + +1998-11-19 Scott Bambrough <scottb@netwinder.org> + + * ChangeLog - Added this file to track changes made. + * fpa11.c - added code to initialize register types to typeNone + * fpa11_cpdt.c - fixed bug in storeExtended (typeExtended changed to + typeDouble in switch statement) diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile new file mode 100644 index 0000000..ed7b26b --- /dev/null +++ b/arch/arm/nwfpe/Makefile @@ -0,0 +1,13 @@ +# +# Copyright (C) 1998, 1999, 2001 Philip Blundell +# + +obj-$(CONFIG_FPE_NWFPE) += nwfpe.o + +nwfpe-y += fpa11.o fpa11_cpdo.o fpa11_cpdt.o \ + fpa11_cprt.o fpmodule.o fpopcode.o \ + softfloat.o single_cpdo.o double_cpdo.o + +nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o +nwfpe-$(CONFIG_CPU_26) += entry26.o +nwfpe-$(CONFIG_CPU_32) += entry.o diff --git a/arch/arm/nwfpe/double_cpdo.c b/arch/arm/nwfpe/double_cpdo.c new file mode 100644 index 0000000..7ffd8cb --- /dev/null +++ b/arch/arm/nwfpe/double_cpdo.c @@ -0,0 +1,167 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "fpa11.h" +#include "softfloat.h" +#include "fpopcode.h" + +union float64_components { + float64 f64; + unsigned int i[2]; +}; + +float64 float64_exp(float64 Fm); +float64 float64_ln(float64 Fm); +float64 float64_sin(float64 rFm); +float64 float64_cos(float64 rFm); +float64 float64_arcsin(float64 rFm); +float64 float64_arctan(float64 rFm); +float64 float64_log(float64 rFm); +float64 float64_tan(float64 rFm); +float64 float64_arccos(float64 rFm); +float64 float64_pow(float64 rFn, float64 rFm); +float64 float64_pol(float64 rFn, float64 rFm); + +static float64 float64_rsf(float64 rFn, float64 rFm) +{ + return float64_sub(rFm, rFn); +} + +static float64 float64_rdv(float64 rFn, float64 rFm) +{ + return float64_div(rFm, rFn); +} + +static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = { + [ADF_CODE >> 20] = float64_add, + [MUF_CODE >> 20] = float64_mul, + [SUF_CODE >> 20] = float64_sub, + [RSF_CODE >> 20] = float64_rsf, + [DVF_CODE >> 20] = float64_div, + [RDF_CODE >> 20] = float64_rdv, + [RMF_CODE >> 20] = float64_rem, + + /* strictly, these opcodes should not be implemented */ + [FML_CODE >> 20] = float64_mul, + [FDV_CODE >> 20] = float64_div, + [FRD_CODE >> 20] = float64_rdv, +}; + +static float64 float64_mvf(float64 rFm) +{ + return rFm; +} + +static float64 float64_mnf(float64 rFm) +{ + union float64_components u; + + u.f64 = rFm; +#ifdef __ARMEB__ + u.i[0] ^= 0x80000000; +#else + u.i[1] ^= 0x80000000; +#endif + + return u.f64; +} + +static float64 float64_abs(float64 rFm) +{ + union float64_components u; + + u.f64 = rFm; +#ifdef __ARMEB__ + u.i[0] &= 0x7fffffff; +#else + u.i[1] &= 0x7fffffff; +#endif + + return u.f64; +} + +static float64 (*const monadic_double[16])(float64 rFm) = { + [MVF_CODE >> 20] = float64_mvf, + [MNF_CODE >> 20] = float64_mnf, + [ABS_CODE >> 20] = float64_abs, + [RND_CODE >> 20] = float64_round_to_int, + [URD_CODE >> 20] = float64_round_to_int, + [SQT_CODE >> 20] = float64_sqrt, + [NRM_CODE >> 20] = float64_mvf, +}; + +unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd) +{ + FPA11 *fpa11 = GET_FPA11(); + float64 rFm; + unsigned int Fm, opc_mask_shift; + + Fm = getFm(opcode); + if (CONSTANT_FM(opcode)) { + rFm = getDoubleConstant(Fm); + } else { + switch (fpa11->fType[Fm]) { + case typeSingle: + rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle); + break; + + case typeDouble: + rFm = fpa11->fpreg[Fm].fDouble; + break; + + default: + return 0; + } + } + + opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; + if (!MONADIC_INSTRUCTION(opcode)) { + unsigned int Fn = getFn(opcode); + float64 rFn; + + switch (fpa11->fType[Fn]) { + case typeSingle: + rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle); + break; + + case typeDouble: + rFn = fpa11->fpreg[Fn].fDouble; + break; + + default: + return 0; + } + + if (dyadic_double[opc_mask_shift]) { + rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm); + } else { + return 0; + } + } else { + if (monadic_double[opc_mask_shift]) { + rFd->fDouble = monadic_double[opc_mask_shift](rFm); + } else { + return 0; + } + } + + return 1; +} diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S new file mode 100644 index 0000000..1dc13bc --- /dev/null +++ b/arch/arm/nwfpe/entry.S @@ -0,0 +1,119 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998 + (c) 1998, 1999 Philip Blundell + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* This is the kernel's entry point into the floating point emulator. +It is called from the kernel with code similar to this: + + sub r4, r5, #4 + ldrt r0, [r4] @ r0 = instruction + adrsvc al, r9, ret_from_exception @ r9 = normal FP return + adrsvc al, lr, fpundefinstr @ lr = undefined instr return + + get_current_task r10 + mov r8, #1 + strb r8, [r10, #TSK_USED_MATH] @ set current->used_math + add r10, r10, #TSS_FPESAVE @ r10 = workspace + ldr r4, .LC2 + ldr pc, [r4] @ Call FP emulator entry point + +The kernel expects the emulator to return via one of two possible +points of return it passes to the emulator. The emulator, if +successful in its emulation, jumps to ret_from_exception (passed in +r9) and the kernel takes care of returning control from the trap to +the user code. If the emulator is unable to emulate the instruction, +it returns via _fpundefinstr (passed via lr) and the kernel halts the +user program with a core dump. + +On entry to the emulator r10 points to an area of private FP workspace +reserved in the thread structure for this process. This is where the +emulator saves its registers across calls. The first word of this area +is used as a flag to detect the first time a process uses floating point, +so that the emulator startup cost can be avoided for tasks that don't +want it. + +This routine does three things: + +1) The kernel has created a struct pt_regs on the stack and saved the +user registers into it. See /usr/include/asm/proc/ptrace.h for details. + +2) It calls EmulateAll to emulate a floating point instruction. +EmulateAll returns 1 if the emulation was successful, or 0 if not. + +3) If an instruction has been emulated successfully, it looks ahead at +the next instruction. If it is a floating point instruction, it +executes the instruction, without returning to user space. In this +way it repeatedly looks ahead and executes floating point instructions +until it encounters a non floating point instruction, at which time it +returns via _fpreturn. + +This is done to reduce the effect of the trap overhead on each +floating point instructions. GCC attempts to group floating point +instructions to allow the emulator to spread the cost of the trap over +several floating point instructions. */ + + .globl nwfpe_enter +nwfpe_enter: + mov r4, lr @ save the failure-return addresses + mov sl, sp @ we access the registers via 'sl' + + ldr r5, [sp, #60] @ get contents of PC; +emulate: + bl EmulateAll @ emulate the instruction + cmp r0, #0 @ was emulation successful + moveq pc, r4 @ no, return failure + +next: +.Lx1: ldrt r6, [r5], #4 @ get the next instruction and + @ increment PC + + and r2, r6, #0x0F000000 @ test for FP insns + teq r2, #0x0C000000 + teqne r2, #0x0D000000 + teqne r2, #0x0E000000 + movne pc, r9 @ return ok if not a fp insn + + str r5, [sp, #60] @ update PC copy in regs + + mov r0, r6 @ save a copy + ldr r1, [sp, #64] @ fetch the condition codes + bl checkCondition @ check the condition + cmp r0, #0 @ r0 = 0 ==> condition failed + + @ if condition code failed to match, next insn + beq next @ get the next instruction; + + mov r0, r6 @ prepare for EmulateAll() + b emulate @ if r0 != 0, goto EmulateAll + + @ We need to be prepared for the instructions at .Lx1 and .Lx2 + @ to fault. Emit the appropriate exception gunk to fix things up. + @ ??? For some reason, faults can happen at .Lx2 even with a + @ plain LDR instruction. Weird, but it seems harmless. + .section .fixup,"ax" + .align 2 +.Lfix: mov pc, r9 @ let the user eat segfaults + .previous + + .section __ex_table,"a" + .align 3 + .long .Lx1, .Lfix + .previous diff --git a/arch/arm/nwfpe/entry26.S b/arch/arm/nwfpe/entry26.S new file mode 100644 index 0000000..0ed38b0 --- /dev/null +++ b/arch/arm/nwfpe/entry26.S @@ -0,0 +1,112 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998 + (c) Philip Blundell 1998-1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#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: + + mov fp, #0 + teqp pc, #PSR_I_BIT | MODE_SVC + ldr r4, .LC2 + ldr pc, [r4] @ Call FP module USR entry point + +The kernel expects the emulator to return via one of two possible +points of return it passes to the emulator. The emulator, if +successful in its emulation, jumps to ret_from_exception and the +kernel takes care of returning control from the trap to the user code. +If the emulator is unable to emulate the instruction, it returns to +fpundefinstr and the kernel halts the user program with a core dump. + +This routine does four things: + +1) It saves SP into a variable called userRegisters. The kernel has +created a struct pt_regs on the stack and saved the user registers +into it. See /usr/include/asm/proc/ptrace.h for details. The +emulator code uses userRegisters as the base of an array of words from +which the contents of the registers can be extracted. + +2) It locates the FP emulator work area within the TSS structure and +points `fpa11' to it. + +3) It calls EmulateAll to emulate a floating point instruction. +EmulateAll returns 1 if the emulation was successful, or 0 if not. + +4) If an instruction has been emulated successfully, it looks ahead at +the next instruction. If it is a floating point instruction, it +executes the instruction, without returning to user space. In this +way it repeatedly looks ahead and executes floating point instructions +until it encounters a non floating point instruction, at which time it +returns via _fpreturn. + +This is done to reduce the effect of the trap overhead on each +floating point instructions. GCC attempts to group floating point +instructions to allow the emulator to spread the cost of the trap over +several floating point instructions. */ + + .globl nwfpe_enter +nwfpe_enter: + mov sl, sp + ldr r5, [sp, #60] @ get contents of PC + bic r5, r5, #0xfc000003 + ldr r0, [r5, #-4] @ get actual instruction into r0 + bl EmulateAll @ emulate the instruction +1: cmp r0, #0 @ was emulation successful + beq fpundefinstr @ no, return failure + +next: +.Lx1: ldrt r6, [r5], #4 @ get the next instruction and + @ increment PC + + and r2, r6, #0x0F000000 @ test for FP insns + teq r2, #0x0C000000 + teqne r2, #0x0D000000 + teqne r2, #0x0E000000 + bne ret_from_exception @ return ok if not a fp insn + + ldr r9, [sp, #60] @ get new condition codes + and r9, r9, #0xfc000003 + orr r7, r5, r9 + str r7, [sp, #60] @ update PC copy in regs + + mov r0, r6 @ save a copy + mov r1, r9 @ fetch the condition codes + bl checkCondition @ check the condition + cmp r0, #0 @ r0 = 0 ==> condition failed + + @ if condition code failed to match, next insn + beq next @ get the next instruction; + + mov r0, r6 @ prepare for EmulateAll() + adr lr, 1b + orr lr, lr, #3 + b EmulateAll @ if r0 != 0, goto EmulateAll + +.Lret: b ret_from_exception @ let the user eat segfaults + + @ We need to be prepared for the instruction at .Lx1 to fault. + @ Emit the appropriate exception gunk to fix things up. + .section __ex_table,"a" + .align 3 + .long .Lx1 + ldr lr, [lr, $(.Lret - .Lx1)/4] + .previous diff --git a/arch/arm/nwfpe/extended_cpdo.c b/arch/arm/nwfpe/extended_cpdo.c new file mode 100644 index 0000000..c39f68a --- /dev/null +++ b/arch/arm/nwfpe/extended_cpdo.c @@ -0,0 +1,154 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "fpa11.h" +#include "softfloat.h" +#include "fpopcode.h" + +floatx80 floatx80_exp(floatx80 Fm); +floatx80 floatx80_ln(floatx80 Fm); +floatx80 floatx80_sin(floatx80 rFm); +floatx80 floatx80_cos(floatx80 rFm); +floatx80 floatx80_arcsin(floatx80 rFm); +floatx80 floatx80_arctan(floatx80 rFm); +floatx80 floatx80_log(floatx80 rFm); +floatx80 floatx80_tan(floatx80 rFm); +floatx80 floatx80_arccos(floatx80 rFm); +floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm); +floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm); + +static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm) +{ + return floatx80_sub(rFm, rFn); +} + +static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm) +{ + return floatx80_div(rFm, rFn); +} + +static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = { + [ADF_CODE >> 20] = floatx80_add, + [MUF_CODE >> 20] = floatx80_mul, + [SUF_CODE >> 20] = floatx80_sub, + [RSF_CODE >> 20] = floatx80_rsf, + [DVF_CODE >> 20] = floatx80_div, + [RDF_CODE >> 20] = floatx80_rdv, + [RMF_CODE >> 20] = floatx80_rem, + + /* strictly, these opcodes should not be implemented */ + [FML_CODE >> 20] = floatx80_mul, + [FDV_CODE >> 20] = floatx80_div, + [FRD_CODE >> 20] = floatx80_rdv, +}; + +static floatx80 floatx80_mvf(floatx80 rFm) +{ + return rFm; +} + +static floatx80 floatx80_mnf(floatx80 rFm) +{ + rFm.high ^= 0x8000; + return rFm; +} + +static floatx80 floatx80_abs(floatx80 rFm) +{ + rFm.high &= 0x7fff; + return rFm; +} + +static floatx80 (*const monadic_extended[16])(floatx80 rFm) = { + [MVF_CODE >> 20] = floatx80_mvf, + [MNF_CODE >> 20] = floatx80_mnf, + [ABS_CODE >> 20] = floatx80_abs, + [RND_CODE >> 20] = floatx80_round_to_int, + [URD_CODE >> 20] = floatx80_round_to_int, + [SQT_CODE >> 20] = floatx80_sqrt, + [NRM_CODE >> 20] = floatx80_mvf, +}; + +unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd) +{ + FPA11 *fpa11 = GET_FPA11(); + floatx80 rFm; + unsigned int Fm, opc_mask_shift; + + Fm = getFm(opcode); + if (CONSTANT_FM(opcode)) { + rFm = getExtendedConstant(Fm); + } else { + switch (fpa11->fType[Fm]) { + case typeSingle: + rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); + break; + + case typeDouble: + rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); + break; + + case typeExtended: + rFm = fpa11->fpreg[Fm].fExtended; + break; + + default: + return 0; + } + } + + opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; + if (!MONADIC_INSTRUCTION(opcode)) { + unsigned int Fn = getFn(opcode); + floatx80 rFn; + + switch (fpa11->fType[Fn]) { + case typeSingle: + rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); + break; + + case typeDouble: + rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); + break; + + case typeExtended: + rFn = fpa11->fpreg[Fn].fExtended; + break; + + default: + return 0; + } + + if (dyadic_extended[opc_mask_shift]) { + rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm); + } else { + return 0; + } + } else { + if (monadic_extended[opc_mask_shift]) { + rFd->fExtended = monadic_extended[opc_mask_shift](rFm); + } else { + return 0; + } + } + + return 1; +} diff --git a/arch/arm/nwfpe/fpa11.c b/arch/arm/nwfpe/fpa11.c new file mode 100644 index 0000000..bf61696 --- /dev/null +++ b/arch/arm/nwfpe/fpa11.c @@ -0,0 +1,143 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 2001 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "fpa11.h" +#include "fpopcode.h" + +#include "fpmodule.h" +#include "fpmodule.inl" + +#include <linux/config.h> +#include <linux/compiler.h> +#include <linux/string.h> +#include <asm/system.h> + +/* forward declarations */ +unsigned int EmulateCPDO(const unsigned int); +unsigned int EmulateCPDT(const unsigned int); +unsigned int EmulateCPRT(const unsigned int); + +/* Reset the FPA11 chip. Called to initialize and reset the emulator. */ +static void resetFPA11(void) +{ + int i; + FPA11 *fpa11 = GET_FPA11(); + + /* initialize the register type array */ + for (i = 0; i <= 7; i++) { + fpa11->fType[i] = typeNone; + } + + /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */ + fpa11->fpsr = FP_EMULATOR | BIT_AC; +} + +void SetRoundingMode(const unsigned int opcode) +{ + switch (opcode & MASK_ROUNDING_MODE) { + default: + case ROUND_TO_NEAREST: + float_rounding_mode = float_round_nearest_even; + break; + + case ROUND_TO_PLUS_INFINITY: + float_rounding_mode = float_round_up; + break; + + case ROUND_TO_MINUS_INFINITY: + float_rounding_mode = float_round_down; + break; + + case ROUND_TO_ZERO: + float_rounding_mode = float_round_to_zero; + break; + } +} + +void SetRoundingPrecision(const unsigned int opcode) +{ +#ifdef CONFIG_FPE_NWFPE_XP + switch (opcode & MASK_ROUNDING_PRECISION) { + case ROUND_SINGLE: + floatx80_rounding_precision = 32; + break; + + case ROUND_DOUBLE: + floatx80_rounding_precision = 64; + break; + + case ROUND_EXTENDED: + floatx80_rounding_precision = 80; + break; + + default: + floatx80_rounding_precision = 80; + } +#endif +} + +void nwfpe_init_fpa(union fp_state *fp) +{ + FPA11 *fpa11 = (FPA11 *)fp; +#ifdef NWFPE_DEBUG + printk("NWFPE: setting up state.\n"); +#endif + memset(fpa11, 0, sizeof(FPA11)); + resetFPA11(); + SetRoundingMode(ROUND_TO_NEAREST); + SetRoundingPrecision(ROUND_EXTENDED); + fpa11->initflag = 1; +} + +/* Emulate the instruction in the opcode. */ +unsigned int EmulateAll(unsigned int opcode) +{ + unsigned int code; + +#ifdef NWFPE_DEBUG + printk("NWFPE: emulating opcode %08x\n", opcode); +#endif + code = opcode & 0x00000f00; + if (code == 0x00000100 || code == 0x00000200) { + /* For coprocessor 1 or 2 (FPA11) */ + code = opcode & 0x0e000000; + if (code == 0x0e000000) { + if (opcode & 0x00000010) { + /* Emulate conversion opcodes. */ + /* Emulate register transfer opcodes. */ + /* Emulate comparison opcodes. */ + return EmulateCPRT(opcode); + } else { + /* Emulate monadic arithmetic opcodes. */ + /* Emulate dyadic arithmetic opcodes. */ + return EmulateCPDO(opcode); + } + } else if (code == 0x0c000000) { + /* Emulate load/store opcodes. */ + /* Emulate load/store multiple opcodes. */ + return EmulateCPDT(opcode); + } + } + + /* Invalid instruction detected. Return FALSE. */ + return 0; +} diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h new file mode 100644 index 0000000..45cc654 --- /dev/null +++ b/arch/arm/nwfpe/fpa11.h @@ -0,0 +1,93 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.com, 1998-1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __FPA11_H__ +#define __FPA11_H__ + +#define GET_FPA11() ((FPA11 *)(¤t_thread_info()->fpstate)) + +/* + * The processes registers are always at the very top of the 8K + * stack+task struct. Use the same method as 'current' uses to + * reach them. + */ +register unsigned long *user_registers asm("sl"); + +#define GET_USERREG() (user_registers) + +#include <linux/config.h> +#include <linux/thread_info.h> + +/* includes */ +#include "fpsr.h" /* FP control and status register definitions */ +#include "milieu.h" +#include "softfloat.h" + +#define typeNone 0x00 +#define typeSingle 0x01 +#define typeDouble 0x02 +#define typeExtended 0x03 + +/* + * This must be no more and no less than 12 bytes. + */ +typedef union tagFPREG { + float32 fSingle; + float64 fDouble; +#ifdef CONFIG_FPE_NWFPE_XP + floatx80 fExtended; +#else + int padding[3]; +#endif +} FPREG; + +/* + * FPA11 device model. + * + * This structure is exported to user space. Do not re-order. + * Only add new stuff to the end, and do not change the size of + * any element. Elements of this structure are used by user + * space, and must match struct user_fp in include/asm-arm/user.h. + * We include the byte offsets below for documentation purposes. + * + * The size of this structure and FPREG are checked by fpmodule.c + * on initialisation. If the rules have been broken, NWFPE will + * not initialise. + */ +typedef struct tagFPA11 { +/* 0 */ FPREG fpreg[8]; /* 8 floating point registers */ +/* 96 */ FPSR fpsr; /* floating point status register */ +/* 100 */ FPCR fpcr; /* floating point control register */ +/* 104 */ unsigned char fType[8]; /* type of floating point value held in + floating point registers. One of + none, single, double or extended. */ +/* 112 */ int initflag; /* this is special. The kernel guarantees + to set it to 0 when a thread is launched, + so we can use it to detect whether this + instance of the emulator needs to be + initialised. */ +} FPA11; + +extern void SetRoundingMode(const unsigned int); +extern void SetRoundingPrecision(const unsigned int); +extern void nwfpe_init_fpa(union fp_state *fp); + +#endif diff --git a/arch/arm/nwfpe/fpa11.inl b/arch/arm/nwfpe/fpa11.inl new file mode 100644 index 0000000..10c3caf --- /dev/null +++ b/arch/arm/nwfpe/fpa11.inl @@ -0,0 +1,51 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "fpa11.h" + +/* Read and write floating point status register */ +extern __inline__ unsigned int readFPSR(void) +{ + FPA11 *fpa11 = GET_FPA11(); + return (fpa11->fpsr); +} + +extern __inline__ void writeFPSR(FPSR reg) +{ + FPA11 *fpa11 = GET_FPA11(); + /* the sysid byte in the status register is readonly */ + fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID); +} + +/* Read and write floating point control register */ +extern __inline__ FPCR readFPCR(void) +{ + FPA11 *fpa11 = GET_FPA11(); + /* clear SB, AB and DA bits before returning FPCR */ + return (fpa11->fpcr & ~MASK_RFC); +} + +extern __inline__ void writeFPCR(FPCR reg) +{ + FPA11 *fpa11 = GET_FPA11(); + fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */ + fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */ +} diff --git a/arch/arm/nwfpe/fpa11_cpdo.c b/arch/arm/nwfpe/fpa11_cpdo.c new file mode 100644 index 0000000..1bea674 --- /dev/null +++ b/arch/arm/nwfpe/fpa11_cpdo.c @@ -0,0 +1,132 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 2001 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <linux/config.h> +#include "fpa11.h" +#include "fpopcode.h" + +unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd); +unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd); +unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd); + +unsigned int EmulateCPDO(const unsigned int opcode) +{ + FPA11 *fpa11 = GET_FPA11(); + FPREG *rFd; + unsigned int nType, nDest, nRc; + + /* Get the destination size. If not valid let Linux perform + an invalid instruction trap. */ + nDest = getDestinationSize(opcode); + if (typeNone == nDest) + return 0; + + SetRoundingMode(opcode); + + /* Compare the size of the operands in Fn and Fm. + Choose the largest size and perform operations in that size, + in order to make use of all the precision of the operands. + If Fm is a constant, we just grab a constant of a size + matching the size of the operand in Fn. */ + if (MONADIC_INSTRUCTION(opcode)) + nType = nDest; + else + nType = fpa11->fType[getFn(opcode)]; + + if (!CONSTANT_FM(opcode)) { + register unsigned int Fm = getFm(opcode); + if (nType < fpa11->fType[Fm]) { + nType = fpa11->fType[Fm]; + } + } + + rFd = &fpa11->fpreg[getFd(opcode)]; + + switch (nType) { + case typeSingle: + nRc = SingleCPDO(opcode, rFd); + break; + case typeDouble: + nRc = DoubleCPDO(opcode, rFd); + break; +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + nRc = ExtendedCPDO(opcode, rFd); + break; +#endif + default: + nRc = 0; + } + + /* The CPDO functions used to always set the destination type + to be the same as their working size. */ + + if (nRc != 0) { + /* If the operation succeeded, check to see if the result in the + destination register is the correct size. If not force it + to be. */ + + fpa11->fType[getFd(opcode)] = nDest; + +#ifdef CONFIG_FPE_NWFPE_XP + if (nDest != nType) { + switch (nDest) { + case typeSingle: + { + if (typeDouble == nType) + rFd->fSingle = float64_to_float32(rFd->fDouble); + else + rFd->fSingle = floatx80_to_float32(rFd->fExtended); + } + break; + + case typeDouble: + { + if (typeSingle == nType) + rFd->fDouble = float32_to_float64(rFd->fSingle); + else + rFd->fDouble = floatx80_to_float64(rFd->fExtended); + } + break; + + case typeExtended: + { + if (typeSingle == nType) + rFd->fExtended = float32_to_floatx80(rFd->fSingle); + else + rFd->fExtended = float64_to_floatx80(rFd->fDouble); + } + break; + } + } +#else + if (nDest != nType) { + if (nDest == typeSingle) + rFd->fSingle = float64_to_float32(rFd->fDouble); + else + rFd->fDouble = float32_to_float64(rFd->fSingle); + } +#endif + } + + return nRc; +} diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c new file mode 100644 index 0000000..95fb63f --- /dev/null +++ b/arch/arm/nwfpe/fpa11_cpdt.c @@ -0,0 +1,392 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.com, 1998-1999 + (c) Philip Blundell, 1998, 2001 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <linux/config.h> +#include "fpa11.h" +#include "softfloat.h" +#include "fpopcode.h" +#include "fpmodule.h" +#include "fpmodule.inl" + +#include <asm/uaccess.h> + +static inline void loadSingle(const unsigned int Fn, const unsigned int __user *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + fpa11->fType[Fn] = typeSingle; + get_user(fpa11->fpreg[Fn].fSingle, pMem); +} + +static inline void loadDouble(const unsigned int Fn, const unsigned int __user *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + unsigned int *p; + p = (unsigned int *) &fpa11->fpreg[Fn].fDouble; + fpa11->fType[Fn] = typeDouble; +#ifdef __ARMEB__ + get_user(p[0], &pMem[0]); /* sign & exponent */ + get_user(p[1], &pMem[1]); +#else + get_user(p[0], &pMem[1]); + get_user(p[1], &pMem[0]); /* sign & exponent */ +#endif +} + +#ifdef CONFIG_FPE_NWFPE_XP +static inline void loadExtended(const unsigned int Fn, const unsigned int __user *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + unsigned int *p; + p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; + fpa11->fType[Fn] = typeExtended; + get_user(p[0], &pMem[0]); /* sign & exponent */ + get_user(p[1], &pMem[2]); /* ls bits */ + get_user(p[2], &pMem[1]); /* ms bits */ +} +#endif + +static inline void loadMultiple(const unsigned int Fn, const unsigned int __user *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + register unsigned int *p; + unsigned long x; + + p = (unsigned int *) &(fpa11->fpreg[Fn]); + get_user(x, &pMem[0]); + fpa11->fType[Fn] = (x >> 14) & 0x00000003; + + switch (fpa11->fType[Fn]) { + case typeSingle: + case typeDouble: + { + get_user(p[0], &pMem[2]); /* Single */ + get_user(p[1], &pMem[1]); /* double msw */ + p[2] = 0; /* empty */ + } + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + { + get_user(p[1], &pMem[2]); + get_user(p[2], &pMem[1]); /* msw */ + p[0] = (x & 0x80003fff); + } + break; +#endif + } +} + +static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + union { + float32 f; + unsigned int i[1]; + } val; + + switch (fpa11->fType[Fn]) { + case typeDouble: + val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble); + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended); + break; +#endif + + default: + val.f = fpa11->fpreg[Fn].fSingle; + } + + put_user(val.i[0], pMem); +} + +static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + union { + float64 f; + unsigned int i[2]; + } val; + + switch (fpa11->fType[Fn]) { + case typeSingle: + val.f = float32_to_float64(fpa11->fpreg[Fn].fSingle); + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended); + break; +#endif + + default: + val.f = fpa11->fpreg[Fn].fDouble; + } + +#ifdef __ARMEB__ + put_user(val.i[0], &pMem[0]); /* msw */ + put_user(val.i[1], &pMem[1]); /* lsw */ +#else + put_user(val.i[1], &pMem[0]); /* msw */ + put_user(val.i[0], &pMem[1]); /* lsw */ +#endif +} + +#ifdef CONFIG_FPE_NWFPE_XP +static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + union { + floatx80 f; + unsigned int i[3]; + } val; + + switch (fpa11->fType[Fn]) { + case typeSingle: + val.f = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); + break; + + case typeDouble: + val.f = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); + break; + + default: + val.f = fpa11->fpreg[Fn].fExtended; + } + + put_user(val.i[0], &pMem[0]); /* sign & exp */ + put_user(val.i[1], &pMem[2]); + put_user(val.i[2], &pMem[1]); /* msw */ +} +#endif + +static inline void storeMultiple(const unsigned int Fn, unsigned int __user *pMem) +{ + FPA11 *fpa11 = GET_FPA11(); + register unsigned int nType, *p; + + p = (unsigned int *) &(fpa11->fpreg[Fn]); + nType = fpa11->fType[Fn]; + + switch (nType) { + case typeSingle: + case typeDouble: + { + put_user(p[0], &pMem[2]); /* single */ + put_user(p[1], &pMem[1]); /* double msw */ + put_user(nType << 14, &pMem[0]); + } + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + { + put_user(p[2], &pMem[1]); /* msw */ + put_user(p[1], &pMem[2]); + put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]); + } + break; +#endif + } +} + +unsigned int PerformLDF(const unsigned int opcode) +{ + unsigned int __user *pBase, *pAddress, *pFinal; + unsigned int nRc = 1, write_back = WRITE_BACK(opcode); + + pBase = (unsigned int __user *) readRegister(getRn(opcode)); + if (REG_PC == getRn(opcode)) { + pBase += 2; + write_back = 0; + } + + pFinal = pBase; + if (BIT_UP_SET(opcode)) + pFinal += getOffset(opcode); + else + pFinal -= getOffset(opcode); + + if (PREINDEXED(opcode)) + pAddress = pFinal; + else + pAddress = pBase; + + switch (opcode & MASK_TRANSFER_LENGTH) { + case TRANSFER_SINGLE: + loadSingle(getFd(opcode), pAddress); + break; + case TRANSFER_DOUBLE: + loadDouble(getFd(opcode), pAddress); + break; +#ifdef CONFIG_FPE_NWFPE_XP + case TRANSFER_EXTENDED: + loadExtended(getFd(opcode), pAddress); + break; +#endif + default: + nRc = 0; + } + + if (write_back) + writeRegister(getRn(opcode), (unsigned long) pFinal); + return nRc; +} + +unsigned int PerformSTF(const unsigned int opcode) +{ + unsigned int __user *pBase, *pAddress, *pFinal; + unsigned int nRc = 1, write_back = WRITE_BACK(opcode); + + SetRoundingMode(ROUND_TO_NEAREST); + + pBase = (unsigned int __user *) readRegister(getRn(opcode)); + if (REG_PC == getRn(opcode)) { + pBase += 2; + write_back = 0; + } + + pFinal = pBase; + if (BIT_UP_SET(opcode)) + pFinal += getOffset(opcode); + else + pFinal -= getOffset(opcode); + + if (PREINDEXED(opcode)) + pAddress = pFinal; + else + pAddress = pBase; + + switch (opcode & MASK_TRANSFER_LENGTH) { + case TRANSFER_SINGLE: + storeSingle(getFd(opcode), pAddress); + break; + case TRANSFER_DOUBLE: + storeDouble(getFd(opcode), pAddress); + break; +#ifdef CONFIG_FPE_NWFPE_XP + case TRANSFER_EXTENDED: + storeExtended(getFd(opcode), pAddress); + break; +#endif + default: + nRc = 0; + } + + if (write_back) + writeRegister(getRn(opcode), (unsigned long) pFinal); + return nRc; +} + +unsigned int PerformLFM(const unsigned int opcode) +{ + unsigned int __user *pBase, *pAddress, *pFinal; + unsigned int i, Fd, write_back = WRITE_BACK(opcode); + + pBase = (unsigned int __user *) readRegister(getRn(opcode)); + if (REG_PC == getRn(opcode)) { + pBase += 2; + write_back = 0; + } + + pFinal = pBase; + if (BIT_UP_SET(opcode)) + pFinal += getOffset(opcode); + else + pFinal -= getOffset(opcode); + + if (PREINDEXED(opcode)) + pAddress = pFinal; + else + pAddress = pBase; + + Fd = getFd(opcode); + for (i = getRegisterCount(opcode); i > 0; i--) { + loadMultiple(Fd, pAddress); + pAddress += 3; + Fd++; + if (Fd == 8) + Fd = 0; + } + + if (write_back) + writeRegister(getRn(opcode), (unsigned long) pFinal); + return 1; +} + +unsigned int PerformSFM(const unsigned int opcode) +{ + unsigned int __user *pBase, *pAddress, *pFinal; + unsigned int i, Fd, write_back = WRITE_BACK(opcode); + + pBase = (unsigned int __user *) readRegister(getRn(opcode)); + if (REG_PC == getRn(opcode)) { + pBase += 2; + write_back = 0; + } + + pFinal = pBase; + if (BIT_UP_SET(opcode)) + pFinal += getOffset(opcode); + else + pFinal -= getOffset(opcode); + + if (PREINDEXED(opcode)) + pAddress = pFinal; + else + pAddress = pBase; + + Fd = getFd(opcode); + for (i = getRegisterCount(opcode); i > 0; i--) { + storeMultiple(Fd, pAddress); + pAddress += 3; + Fd++; + if (Fd == 8) + Fd = 0; + } + + if (write_back) + writeRegister(getRn(opcode), (unsigned long) pFinal); + return 1; +} + +unsigned int EmulateCPDT(const unsigned int opcode) +{ + unsigned int nRc = 0; + + if (LDF_OP(opcode)) { + nRc = PerformLDF(opcode); + } else if (LFM_OP(opcode)) { + nRc = PerformLFM(opcode); + } else if (STF_OP(opcode)) { + nRc = PerformSTF(opcode); + } else if (SFM_OP(opcode)) { + nRc = PerformSFM(opcode); + } else { + nRc = 0; + } + + return nRc; +} diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c new file mode 100644 index 0000000..db01fbc --- /dev/null +++ b/arch/arm/nwfpe/fpa11_cprt.c @@ -0,0 +1,369 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 1999, 2001 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <linux/config.h> +#include "fpa11.h" +#include "fpopcode.h" +#include "fpa11.inl" +#include "fpmodule.h" +#include "fpmodule.inl" + +#ifdef CONFIG_FPE_NWFPE_XP +extern flag floatx80_is_nan(floatx80); +#endif +extern flag float64_is_nan(float64); +extern flag float32_is_nan(float32); + +void SetRoundingMode(const unsigned int opcode); + +unsigned int PerformFLT(const unsigned int opcode); +unsigned int PerformFIX(const unsigned int opcode); + +static unsigned int PerformComparison(const unsigned int opcode); + +unsigned int EmulateCPRT(const unsigned int opcode) +{ + + if (opcode & 0x800000) { + /* This is some variant of a comparison (PerformComparison + will sort out which one). Since most of the other CPRT + instructions are oddball cases of some sort or other it + makes sense to pull this out into a fast path. */ + return PerformComparison(opcode); + } + + /* Hint to GCC that we'd like a jump table rather than a load of CMPs */ + switch ((opcode & 0x700000) >> 20) { + case FLT_CODE >> 20: + return PerformFLT(opcode); + break; + case FIX_CODE >> 20: + return PerformFIX(opcode); + break; + + case WFS_CODE >> 20: + writeFPSR(readRegister(getRd(opcode))); + break; + case RFS_CODE >> 20: + writeRegister(getRd(opcode), readFPSR()); + break; + + default: + return 0; + } + + return 1; +} + +unsigned int PerformFLT(const unsigned int opcode) +{ + FPA11 *fpa11 = GET_FPA11(); + SetRoundingMode(opcode); + SetRoundingPrecision(opcode); + + switch (opcode & MASK_ROUNDING_PRECISION) { + case ROUND_SINGLE: + { + fpa11->fType[getFn(opcode)] = typeSingle; + fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode))); + } + break; + + case ROUND_DOUBLE: + { + fpa11->fType[getFn(opcode)] = typeDouble; + fpa11->fpreg[getFn(opcode)].fDouble = int32_to_float64(readRegister(getRd(opcode))); + } + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case ROUND_EXTENDED: + { + fpa11->fType[getFn(opcode)] = typeExtended; + fpa11->fpreg[getFn(opcode)].fExtended = int32_to_floatx80(readRegister(getRd(opcode))); + } + break; +#endif + + default: + return 0; + } + + return 1; +} + +unsigned int PerformFIX(const unsigned int opcode) +{ + FPA11 *fpa11 = GET_FPA11(); + unsigned int Fn = getFm(opcode); + + SetRoundingMode(opcode); + + switch (fpa11->fType[Fn]) { + case typeSingle: + { + writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle)); + } + break; + + case typeDouble: + { + writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble)); + } + break; + +#ifdef CONFIG_FPE_NWFPE_XP + case typeExtended: + { + writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended)); + } + break; +#endif + + default: + return 0; + } + + return 1; +} + +/* This instruction sets the flags N, Z, C, V in the FPSR. */ +static unsigned int PerformComparison(const unsigned int opcode) +{ + FPA11 *fpa11 = GET_FPA11(); + unsigned int Fn = getFn(opcode), Fm = getFm(opcode); + int e_flag = opcode & 0x400000; /* 1 if CxFE */ + int n_flag = opcode & 0x200000; /* 1 if CNxx */ + unsigned int flags = 0; + +#ifdef CONFIG_FPE_NWFPE_XP + floatx80 rFn, rFm; + + /* Check for unordered condition and convert all operands to 80-bit + format. + ?? Might be some mileage in avoiding this conversion if possible. + Eg, if both operands are 32-bit, detect this and do a 32-bit + comparison (cheaper than an 80-bit one). */ + switch (fpa11->fType[Fn]) { + case typeSingle: + //printk("single.\n"); + if (float32_is_nan(fpa11->fpreg[Fn].fSingle)) + goto unordered; + rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); + break; + + case typeDouble: + //printk("double.\n"); + if (float64_is_nan(fpa11->fpreg[Fn].fDouble)) + goto unordered; + rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); + break; + + case typeExtended: + //printk("extended.\n"); + if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended)) + goto unordered; + rFn = fpa11->fpreg[Fn].fExtended; + break; + + default: + return 0; + } + + if (CONSTANT_FM(opcode)) { + //printk("Fm is a constant: #%d.\n",Fm); + rFm = getExtendedConstant(Fm); + if (floatx80_is_nan(rFm)) + goto unordered; + } else { + //printk("Fm = r%d which contains a ",Fm); + switch (fpa11->fType[Fm]) { + case typeSingle: + //printk("single.\n"); + if (float32_is_nan(fpa11->fpreg[Fm].fSingle)) + goto unordered; + rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); + break; + + case typeDouble: + //printk("double.\n"); + if (float64_is_nan(fpa11->fpreg[Fm].fDouble)) + goto unordered; + rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); + break; + + case typeExtended: + //printk("extended.\n"); + if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended)) + goto unordered; + rFm = fpa11->fpreg[Fm].fExtended; + break; + + default: + return 0; + } + } + + if (n_flag) + rFm.high ^= 0x8000; + + /* test for less than condition */ + if (floatx80_lt(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (floatx80_eq(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (floatx80_lt(rFm, rFn)) + flags |= CC_CARRY; + +#else + if (CONSTANT_FM(opcode)) { + /* Fm is a constant. Do the comparison in whatever precision + Fn happens to be stored in. */ + if (fpa11->fType[Fn] == typeSingle) { + float32 rFm = getSingleConstant(Fm); + float32 rFn = fpa11->fpreg[Fn].fSingle; + + if (float32_is_nan(rFn)) + goto unordered; + + if (n_flag) + rFm ^= 0x80000000; + + /* test for less than condition */ + if (float32_lt_nocheck(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (float32_eq_nocheck(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (float32_lt_nocheck(rFm, rFn)) + flags |= CC_CARRY; + } else { + float64 rFm = getDoubleConstant(Fm); + float64 rFn = fpa11->fpreg[Fn].fDouble; + + if (float64_is_nan(rFn)) + goto unordered; + + if (n_flag) + rFm ^= 0x8000000000000000ULL; + + /* test for less than condition */ + if (float64_lt_nocheck(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (float64_eq_nocheck(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (float64_lt_nocheck(rFm, rFn)) + flags |= CC_CARRY; + } + } else { + /* Both operands are in registers. */ + if (fpa11->fType[Fn] == typeSingle + && fpa11->fType[Fm] == typeSingle) { + float32 rFm = fpa11->fpreg[Fm].fSingle; + float32 rFn = fpa11->fpreg[Fn].fSingle; + + if (float32_is_nan(rFn) + || float32_is_nan(rFm)) + goto unordered; + + if (n_flag) + rFm ^= 0x80000000; + + /* test for less than condition */ + if (float32_lt_nocheck(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (float32_eq_nocheck(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (float32_lt_nocheck(rFm, rFn)) + flags |= CC_CARRY; + } else { + /* Promote 32-bit operand to 64 bits. */ + float64 rFm, rFn; + + rFm = (fpa11->fType[Fm] == typeSingle) ? + float32_to_float64(fpa11->fpreg[Fm].fSingle) + : fpa11->fpreg[Fm].fDouble; + + rFn = (fpa11->fType[Fn] == typeSingle) ? + float32_to_float64(fpa11->fpreg[Fn].fSingle) + : fpa11->fpreg[Fn].fDouble; + + if (float64_is_nan(rFn) + || float64_is_nan(rFm)) + goto unordered; + + if (n_flag) + rFm ^= 0x8000000000000000ULL; + + /* test for less than condition */ + if (float64_lt_nocheck(rFn, rFm)) + flags |= CC_NEGATIVE; + + /* test for equal condition */ + if (float64_eq_nocheck(rFn, rFm)) + flags |= CC_ZERO; + + /* test for greater than or equal condition */ + if (float64_lt_nocheck(rFm, rFn)) + flags |= CC_CARRY; + } + } + +#endif + + writeConditionCodes(flags); + + return 1; + + unordered: + /* ?? The FPA data sheet is pretty vague about this, in particular + about whether the non-E comparisons can ever raise exceptions. + This implementation is based on a combination of what it says in + the data sheet, observation of how the Acorn emulator actually + behaves (and how programs expect it to) and guesswork. */ + flags |= CC_OVERFLOW; + flags &= ~(CC_ZERO | CC_NEGATIVE); + + if (BIT_AC & readFPSR()) + flags |= CC_CARRY; + + if (e_flag) + float_raise(float_flag_invalid); + + writeConditionCodes(flags); + return 1; +} diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c new file mode 100644 index 0000000..a806fea --- /dev/null +++ b/arch/arm/nwfpe/fpmodule.c @@ -0,0 +1,173 @@ + +/* + NetWinder Floating Point Emulator + (c) Rebel.com, 1998-1999 + (c) Philip Blundell, 1998-1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "fpa11.h" + +#include <linux/module.h> +#include <linux/version.h> +#include <linux/config.h> + +/* XXX */ +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/init.h> +/* XXX */ + +#include "softfloat.h" +#include "fpopcode.h" +#include "fpmodule.h" +#include "fpa11.inl" + +/* kernel symbols required for signal handling */ +#ifdef CONFIG_FPE_NWFPE_XP +#define NWFPE_BITS "extended" +#else +#define NWFPE_BITS "double" +#endif + +#ifdef MODULE +void fp_send_sig(unsigned long sig, struct task_struct *p, int priv); +#else +#define fp_send_sig send_sig +#define kern_fp_enter fp_enter + +extern char fpe_type[]; +#endif + +/* kernel function prototypes required */ +void fp_setup(void); + +/* external declarations for saved kernel symbols */ +extern void (*kern_fp_enter)(void); +extern void (*fp_init)(union fp_state *); + +/* Original value of fp_enter from kernel before patched by fpe_init. */ +static void (*orig_fp_enter)(void); +static void (*orig_fp_init)(union fp_state *); + +/* forward declarations */ +extern void nwfpe_enter(void); + +static int __init fpe_init(void) +{ + if (sizeof(FPA11) > sizeof(union fp_state)) { + printk(KERN_ERR "nwfpe: bad structure size\n"); + return -EINVAL; + } + + if (sizeof(FPREG) != 12) { + printk(KERN_ERR "nwfpe: bad register size\n"); + return -EINVAL; + } + if (fpe_type[0] && strcmp(fpe_type, "nwfpe")) + return 0; + + /* Display title, version and copyright information. */ + printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 (" + NWFPE_BITS " precision)\n"); + + /* Save pointer to the old FP handler and then patch ourselves in */ + orig_fp_enter = kern_fp_enter; + orig_fp_init = fp_init; + kern_fp_enter = nwfpe_enter; + fp_init = nwfpe_init_fpa; + + return 0; +} + +static void __exit fpe_exit(void) +{ + /* Restore the values we saved earlier. */ + kern_fp_enter = orig_fp_enter; + fp_init = orig_fp_init; +} + +/* +ScottB: November 4, 1998 + +Moved this function out of softfloat-specialize into fpmodule.c. +This effectively isolates all the changes required for integrating with the +Linux kernel into fpmodule.c. Porting to NetBSD should only require modifying +fpmodule.c to integrate with the NetBSD kernel (I hope!). + +[1/1/99: Not quite true any more unfortunately. There is Linux-specific +code to access data in user space in some other source files at the +moment (grep for get_user / put_user calls). --philb] + +float_exception_flags is a global variable in SoftFloat. + +This function is called by the SoftFloat routines to raise a floating +point exception. We check the trap enable byte in the FPSR, and raise +a SIGFPE exception if necessary. If not the relevant bits in the +cumulative exceptions flag byte are set and we return. +*/ + +void float_raise(signed char flags) +{ + register unsigned int fpsr, cumulativeTraps; + +#ifdef CONFIG_DEBUG_USER + printk(KERN_DEBUG + "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n", + current->comm, current->pid, flags, + __builtin_return_address(0), GET_USERREG()[15]); +#endif + + /* Keep SoftFloat exception flags up to date. */ + float_exception_flags |= flags; + + /* Read fpsr and initialize the cumulativeTraps. */ + fpsr = readFPSR(); + cumulativeTraps = 0; + + /* For each type of exception, the cumulative trap exception bit is only + set if the corresponding trap enable bit is not set. */ + if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC)) + cumulativeTraps |= BIT_IXC; + if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC)) + cumulativeTraps |= BIT_UFC; + if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC)) + cumulativeTraps |= BIT_OFC; + if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC)) + cumulativeTraps |= BIT_DZC; + if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC)) + cumulativeTraps |= BIT_IOC; + + /* Set the cumulative exceptions flags. */ + if (cumulativeTraps) + writeFPSR(fpsr | cumulativeTraps); + + /* Raise an exception if necessary. */ + if (fpsr & (flags << 16)) + fp_send_sig(SIGFPE, current, 1); +} + +module_init(fpe_init); +module_exit(fpe_exit); + +MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>"); +MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/nwfpe/fpmodule.h b/arch/arm/nwfpe/fpmodule.h new file mode 100644 index 0000000..5c2e8e4 --- /dev/null +++ b/arch/arm/nwfpe/fpmodule.h @@ -0,0 +1,47 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.com, 1998-1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + 27/03/03 Ian Molton Clean up CONFIG_CPU +*/ + +#ifndef __FPMODULE_H__ +#define __FPMODULE_H__ + +#define REG_ORIG_R0 17 +#define REG_CPSR 16 +#define REG_PC 15 +#define REG_LR 14 +#define REG_SP 13 +#define REG_IP 12 +#define REG_FP 11 +#define REG_R10 10 +#define REG_R9 9 +#define REG_R9 9 +#define REG_R8 8 +#define REG_R7 7 +#define REG_R6 6 +#define REG_R5 5 +#define REG_R4 4 +#define REG_R3 3 +#define REG_R2 2 +#define REG_R1 1 +#define REG_R0 0 + +#endif diff --git a/arch/arm/nwfpe/fpmodule.inl b/arch/arm/nwfpe/fpmodule.inl new file mode 100644 index 0000000..e5f59e9 --- /dev/null +++ b/arch/arm/nwfpe/fpmodule.inl @@ -0,0 +1,74 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +static inline unsigned long readRegister(const unsigned int nReg) +{ + /* Note: The CPU thinks it has dealt with the current instruction. + As a result the program counter has been advanced to the next + instruction, and points 4 bytes beyond the actual instruction + that caused the invalid instruction trap to occur. We adjust + for this in this routine. LDF/STF instructions with Rn = PC + depend on the PC being correct, as they use PC+8 in their + address calculations. */ + unsigned long *userRegisters = GET_USERREG(); + unsigned int val = userRegisters[nReg]; + if (REG_PC == nReg) + val -= 4; + return val; +} + +static inline void +writeRegister(const unsigned int nReg, const unsigned long val) +{ + unsigned long *userRegisters = GET_USERREG(); + userRegisters[nReg] = val; +} + +static inline unsigned long readCPSR(void) +{ + return (readRegister(REG_CPSR)); +} + +static inline void writeCPSR(const unsigned long val) +{ + writeRegister(REG_CPSR, val); +} + +static inline unsigned long readConditionCodes(void) +{ +#ifdef __FPEM_TEST__ + return (0); +#else + return (readCPSR() & CC_MASK); +#endif +} + +static inline void writeConditionCodes(const unsigned long val) +{ + unsigned long *userRegisters = GET_USERREG(); + unsigned long rval; + /* + * Operate directly on userRegisters since + * the CPSR may be the PC register itself. + */ + rval = userRegisters[REG_CPSR] & ~CC_MASK; + userRegisters[REG_CPSR] = rval | (val & CC_MASK); +} diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c new file mode 100644 index 0000000..4c9f570 --- /dev/null +++ b/arch/arm/nwfpe/fpopcode.c @@ -0,0 +1,90 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <linux/config.h> +#include "fpa11.h" +#include "softfloat.h" +#include "fpopcode.h" +#include "fpsr.h" +#include "fpmodule.h" +#include "fpmodule.inl" + +#ifdef CONFIG_FPE_NWFPE_XP +const floatx80 floatx80Constant[] = { + {0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ + {0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ + {0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ + {0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ + {0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ + {0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ + {0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ + {0x4002, 0xa000000000000000ULL} /* extended 10.0 */ +}; +#endif + +const float64 float64Constant[] = { + 0x0000000000000000ULL, /* double 0.0 */ + 0x3ff0000000000000ULL, /* double 1.0 */ + 0x4000000000000000ULL, /* double 2.0 */ + 0x4008000000000000ULL, /* double 3.0 */ + 0x4010000000000000ULL, /* double 4.0 */ + 0x4014000000000000ULL, /* double 5.0 */ + 0x3fe0000000000000ULL, /* double 0.5 */ + 0x4024000000000000ULL /* double 10.0 */ +}; + +const float32 float32Constant[] = { + 0x00000000, /* single 0.0 */ + 0x3f800000, /* single 1.0 */ + 0x40000000, /* single 2.0 */ + 0x40400000, /* single 3.0 */ + 0x40800000, /* single 4.0 */ + 0x40a00000, /* single 5.0 */ + 0x3f000000, /* single 0.5 */ + 0x41200000 /* single 10.0 */ +}; + +/* condition code lookup table + index into the table is test code: EQ, NE, ... LT, GT, AL, NV + bit position in short is condition code: NZCV */ +static const unsigned short aCC[16] = { + 0xF0F0, // EQ == Z set + 0x0F0F, // NE + 0xCCCC, // CS == C set + 0x3333, // CC + 0xFF00, // MI == N set + 0x00FF, // PL + 0xAAAA, // VS == V set + 0x5555, // VC + 0x0C0C, // HI == C set && Z clear + 0xF3F3, // LS == C clear || Z set + 0xAA55, // GE == (N==V) + 0x55AA, // LT == (N!=V) + 0x0A05, // GT == (!Z && (N==V)) + 0xF5FA, // LE == (Z || (N!=V)) + 0xFFFF, // AL always + 0 // NV +}; + +unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes) +{ + return (aCC[opcode >> 28] >> (ccodes >> 28)) & 1; +} diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h new file mode 100644 index 0000000..8035f4f --- /dev/null +++ b/arch/arm/nwfpe/fpopcode.h @@ -0,0 +1,479 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 2001 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __FPOPCODE_H__ +#define __FPOPCODE_H__ + +#include <linux/config.h> + +/* +ARM Floating Point Instruction Classes +| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +|c o n d|1 1 0 P|U|u|W|L| Rn |v| Fd |0|0|0|1| o f f s e t | CPDT +|c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|1|0| o f f s e t | CPDT (copro 2) +| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +|c o n d|1 1 1 0|a|b|c|d|e| Fn |j| Fd |0|0|0|1|f|g|h|0|i| Fm | CPDO +|c o n d|1 1 1 0|a|b|c|L|e| Fn | Rd |0|0|0|1|f|g|h|1|i| Fm | CPRT +|c o n d|1 1 1 0|a|b|c|1|e| Fn |1|1|1|1|0|0|0|1|f|g|h|1|i| Fm | comparisons +| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + +CPDT data transfer instructions + LDF, STF, LFM (copro 2), SFM (copro 2) + +CPDO dyadic arithmetic instructions + ADF, MUF, SUF, RSF, DVF, RDF, + POW, RPW, RMF, FML, FDV, FRD, POL + +CPDO monadic arithmetic instructions + MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP, + SIN, COS, TAN, ASN, ACS, ATN, URD, NRM + +CPRT joint arithmetic/data transfer instructions + FIX (arithmetic followed by load/store) + FLT (load/store followed by arithmetic) + CMF, CNF CMFE, CNFE (comparisons) + WFS, RFS (write/read floating point status register) + WFC, RFC (write/read floating point control register) + +cond condition codes +P pre/post index bit: 0 = postindex, 1 = preindex +U up/down bit: 0 = stack grows down, 1 = stack grows up +W write back bit: 1 = update base register (Rn) +L load/store bit: 0 = store, 1 = load +Rn base register +Rd destination/source register +Fd floating point destination register +Fn floating point source register +Fm floating point source register or floating point constant + +uv transfer length (TABLE 1) +wx register count (TABLE 2) +abcd arithmetic opcode (TABLES 3 & 4) +ef destination size (rounding precision) (TABLE 5) +gh rounding mode (TABLE 6) +j dyadic/monadic bit: 0 = dyadic, 1 = monadic +i constant bit: 1 = constant (TABLE 6) +*/ + +/* +TABLE 1 ++-------------------------+---+---+---------+---------+ +| Precision | u | v | FPSR.EP | length | ++-------------------------+---+---+---------+---------+ +| Single | 0 ü 0 | x | 1 words | +| Double | 1 ü 1 | x | 2 words | +| Extended | 1 ü 1 | x | 3 words | +| Packed decimal | 1 ü 1 | 0 | 3 words | +| Expanded packed decimal | 1 ü 1 | 1 | 4 words | ++-------------------------+---+---+---------+---------+ +Note: x = don't care +*/ + +/* +TABLE 2 ++---+---+---------------------------------+ +| w | x | Number of registers to transfer | ++---+---+---------------------------------+ +| 0 ü 1 | 1 | +| 1 ü 0 | 2 | +| 1 ü 1 | 3 | +| 0 ü 0 | 4 | ++---+---+---------------------------------+ +*/ + +/* +TABLE 3: Dyadic Floating Point Opcodes ++---+---+---+---+----------+-----------------------+-----------------------+ +| a | b | c | d | Mnemonic | Description | Operation | ++---+---+---+---+----------+-----------------------+-----------------------+ +| 0 | 0 | 0 | 0 | ADF | Add | Fd := Fn + Fm | +| 0 | 0 | 0 | 1 | MUF | Multiply | Fd := Fn * Fm | +| 0 | 0 | 1 | 0 | SUF | Subtract | Fd := Fn - Fm | +| 0 | 0 | 1 | 1 | RSF | Reverse subtract | Fd := Fm - Fn | +| 0 | 1 | 0 | 0 | DVF | Divide | Fd := Fn / Fm | +| 0 | 1 | 0 | 1 | RDF | Reverse divide | Fd := Fm / Fn | +| 0 | 1 | 1 | 0 | POW | Power | Fd := Fn ^ Fm | +| 0 | 1 | 1 | 1 | RPW | Reverse power | Fd := Fm ^ Fn | +| 1 | 0 | 0 | 0 | RMF | Remainder | Fd := IEEE rem(Fn/Fm) | +| 1 | 0 | 0 | 1 | FML | Fast Multiply | Fd := Fn * Fm | +| 1 | 0 | 1 | 0 | FDV | Fast Divide | Fd := Fn / Fm | +| 1 | 0 | 1 | 1 | FRD | Fast reverse divide | Fd := Fm / Fn | +| 1 | 1 | 0 | 0 | POL | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm) | +| 1 | 1 | 0 | 1 | | undefined instruction | trap | +| 1 | 1 | 1 | 0 | | undefined instruction | trap | +| 1 | 1 | 1 | 1 | | undefined instruction | trap | ++---+---+---+---+----------+-----------------------+-----------------------+ +Note: POW, RPW, POL are deprecated, and are available for backwards + compatibility only. +*/ + +/* +TABLE 4: Monadic Floating Point Opcodes ++---+---+---+---+----------+-----------------------+-----------------------+ +| a | b | c | d | Mnemonic | Description | Operation | ++---+---+---+---+----------+-----------------------+-----------------------+ +| 0 | 0 | 0 | 0 | MVF | Move | Fd := Fm | +| 0 | 0 | 0 | 1 | MNF | Move negated | Fd := - Fm | +| 0 | 0 | 1 | 0 | ABS | Absolute value | Fd := abs(Fm) | +| 0 | 0 | 1 | 1 | RND | Round to integer | Fd := int(Fm) | +| 0 | 1 | 0 | 0 | SQT | Square root | Fd := sqrt(Fm) | +| 0 | 1 | 0 | 1 | LOG | Log base 10 | Fd := log10(Fm) | +| 0 | 1 | 1 | 0 | LGN | Log base e | Fd := ln(Fm) | +| 0 | 1 | 1 | 1 | EXP | Exponent | Fd := e ^ Fm | +| 1 | 0 | 0 | 0 | SIN | Sine | Fd := sin(Fm) | +| 1 | 0 | 0 | 1 | COS | Cosine | Fd := cos(Fm) | +| 1 | 0 | 1 | 0 | TAN | Tangent | Fd := tan(Fm) | +| 1 | 0 | 1 | 1 | ASN | Arc Sine | Fd := arcsin(Fm) | +| 1 | 1 | 0 | 0 | ACS | Arc Cosine | Fd := arccos(Fm) | +| 1 | 1 | 0 | 1 | ATN | Arc Tangent | Fd := arctan(Fm) | +| 1 | 1 | 1 | 0 | URD | Unnormalized round | Fd := int(Fm) | +| 1 | 1 | 1 | 1 | NRM | Normalize | Fd := norm(Fm) | ++---+---+---+---+----------+-----------------------+-----------------------+ +Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are + available for backwards compatibility only. +*/ + +/* +TABLE 5 ++-------------------------+---+---+ +| Rounding Precision | e | f | ++-------------------------+---+---+ +| IEEE Single precision | 0 ü 0 | +| IEEE Double precision | 0 ü 1 | +| IEEE Extended precision | 1 ü 0 | +| undefined (trap) | 1 ü 1 | ++-------------------------+---+---+ +*/ + +/* +TABLE 5 ++---------------------------------+---+---+ +| Rounding Mode | g | h | ++---------------------------------+---+---+ +| Round to nearest (default) | 0 ü 0 | +| Round toward plus infinity | 0 ü 1 | +| Round toward negative infinity | 1 ü 0 | +| Round toward zero | 1 ü 1 | ++---------------------------------+---+---+ +*/ + +/* +=== +=== Definitions for load and store instructions +=== +*/ + +/* bit masks */ +#define BIT_PREINDEX 0x01000000 +#define BIT_UP 0x00800000 +#define BIT_WRITE_BACK 0x00200000 +#define BIT_LOAD 0x00100000 + +/* masks for load/store */ +#define MASK_CPDT 0x0c000000 /* data processing opcode */ +#define MASK_OFFSET 0x000000ff +#define MASK_TRANSFER_LENGTH 0x00408000 +#define MASK_REGISTER_COUNT MASK_TRANSFER_LENGTH +#define MASK_COPROCESSOR 0x00000f00 + +/* Tests for transfer length */ +#define TRANSFER_SINGLE 0x00000000 +#define TRANSFER_DOUBLE 0x00008000 +#define TRANSFER_EXTENDED 0x00400000 +#define TRANSFER_PACKED MASK_TRANSFER_LENGTH + +/* Get the coprocessor number from the opcode. */ +#define getCoprocessorNumber(opcode) ((opcode & MASK_COPROCESSOR) >> 8) + +/* Get the offset from the opcode. */ +#define getOffset(opcode) (opcode & MASK_OFFSET) + +/* Tests for specific data transfer load/store opcodes. */ +#define TEST_OPCODE(opcode,mask) (((opcode) & (mask)) == (mask)) + +#define LOAD_OP(opcode) TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD) +#define STORE_OP(opcode) ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT) + +#define LDF_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1)) +#define LFM_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2)) +#define STF_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1)) +#define SFM_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2)) + +#define PREINDEXED(opcode) ((opcode & BIT_PREINDEX) != 0) +#define POSTINDEXED(opcode) ((opcode & BIT_PREINDEX) == 0) +#define BIT_UP_SET(opcode) ((opcode & BIT_UP) != 0) +#define BIT_UP_CLEAR(opcode) ((opcode & BIT_DOWN) == 0) +#define WRITE_BACK(opcode) ((opcode & BIT_WRITE_BACK) != 0) +#define LOAD(opcode) ((opcode & BIT_LOAD) != 0) +#define STORE(opcode) ((opcode & BIT_LOAD) == 0) + +/* +=== +=== Definitions for arithmetic instructions +=== +*/ +/* bit masks */ +#define BIT_MONADIC 0x00008000 +#define BIT_CONSTANT 0x00000008 + +#define CONSTANT_FM(opcode) ((opcode & BIT_CONSTANT) != 0) +#define MONADIC_INSTRUCTION(opcode) ((opcode & BIT_MONADIC) != 0) + +/* instruction identification masks */ +#define MASK_CPDO 0x0e000000 /* arithmetic opcode */ +#define MASK_ARITHMETIC_OPCODE 0x00f08000 +#define MASK_DESTINATION_SIZE 0x00080080 + +/* dyadic arithmetic opcodes. */ +#define ADF_CODE 0x00000000 +#define MUF_CODE 0x00100000 +#define SUF_CODE 0x00200000 +#define RSF_CODE 0x00300000 +#define DVF_CODE 0x00400000 +#define RDF_CODE 0x00500000 +#define POW_CODE 0x00600000 +#define RPW_CODE 0x00700000 +#define RMF_CODE 0x00800000 +#define FML_CODE 0x00900000 +#define FDV_CODE 0x00a00000 +#define FRD_CODE 0x00b00000 +#define POL_CODE 0x00c00000 +/* 0x00d00000 is an invalid dyadic arithmetic opcode */ +/* 0x00e00000 is an invalid dyadic arithmetic opcode */ +/* 0x00f00000 is an invalid dyadic arithmetic opcode */ + +/* monadic arithmetic opcodes. */ +#define MVF_CODE 0x00008000 +#define MNF_CODE 0x00108000 +#define ABS_CODE 0x00208000 +#define RND_CODE 0x00308000 +#define SQT_CODE 0x00408000 +#define LOG_CODE 0x00508000 +#define LGN_CODE 0x00608000 +#define EXP_CODE 0x00708000 +#define SIN_CODE 0x00808000 +#define COS_CODE 0x00908000 +#define TAN_CODE 0x00a08000 +#define ASN_CODE 0x00b08000 +#define ACS_CODE 0x00c08000 +#define ATN_CODE 0x00d08000 +#define URD_CODE 0x00e08000 +#define NRM_CODE 0x00f08000 + +/* +=== +=== Definitions for register transfer and comparison instructions +=== +*/ + +#define MASK_CPRT 0x0e000010 /* register transfer opcode */ +#define MASK_CPRT_CODE 0x00f00000 +#define FLT_CODE 0x00000000 +#define FIX_CODE 0x00100000 +#define WFS_CODE 0x00200000 +#define RFS_CODE 0x00300000 +#define WFC_CODE 0x00400000 +#define RFC_CODE 0x00500000 +#define CMF_CODE 0x00900000 +#define CNF_CODE 0x00b00000 +#define CMFE_CODE 0x00d00000 +#define CNFE_CODE 0x00f00000 + +/* +=== +=== Common definitions +=== +*/ + +/* register masks */ +#define MASK_Rd 0x0000f000 +#define MASK_Rn 0x000f0000 +#define MASK_Fd 0x00007000 +#define MASK_Fm 0x00000007 +#define MASK_Fn 0x00070000 + +/* condition code masks */ +#define CC_MASK 0xf0000000 +#define CC_NEGATIVE 0x80000000 +#define CC_ZERO 0x40000000 +#define CC_CARRY 0x20000000 +#define CC_OVERFLOW 0x10000000 +#define CC_EQ 0x00000000 +#define CC_NE 0x10000000 +#define CC_CS 0x20000000 +#define CC_HS CC_CS +#define CC_CC 0x30000000 +#define CC_LO CC_CC +#define CC_MI 0x40000000 +#define CC_PL 0x50000000 +#define CC_VS 0x60000000 +#define CC_VC 0x70000000 +#define CC_HI 0x80000000 +#define CC_LS 0x90000000 +#define CC_GE 0xa0000000 +#define CC_LT 0xb0000000 +#define CC_GT 0xc0000000 +#define CC_LE 0xd0000000 +#define CC_AL 0xe0000000 +#define CC_NV 0xf0000000 + +/* rounding masks/values */ +#define MASK_ROUNDING_MODE 0x00000060 +#define ROUND_TO_NEAREST 0x00000000 +#define ROUND_TO_PLUS_INFINITY 0x00000020 +#define ROUND_TO_MINUS_INFINITY 0x00000040 +#define ROUND_TO_ZERO 0x00000060 + +#define MASK_ROUNDING_PRECISION 0x00080080 +#define ROUND_SINGLE 0x00000000 +#define ROUND_DOUBLE 0x00000080 +#define ROUND_EXTENDED 0x00080000 + +/* Get the condition code from the opcode. */ +#define getCondition(opcode) (opcode >> 28) + +/* Get the source register from the opcode. */ +#define getRn(opcode) ((opcode & MASK_Rn) >> 16) + +/* Get the destination floating point register from the opcode. */ +#define getFd(opcode) ((opcode & MASK_Fd) >> 12) + +/* Get the first source floating point register from the opcode. */ +#define getFn(opcode) ((opcode & MASK_Fn) >> 16) + +/* Get the second source floating point register from the opcode. */ +#define getFm(opcode) (opcode & MASK_Fm) + +/* Get the destination register from the opcode. */ +#define getRd(opcode) ((opcode & MASK_Rd) >> 12) + +/* Get the rounding mode from the opcode. */ +#define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) + +#ifdef CONFIG_FPE_NWFPE_XP +static inline const floatx80 getExtendedConstant(const unsigned int nIndex) +{ + extern const floatx80 floatx80Constant[]; + return floatx80Constant[nIndex]; +} +#endif + +static inline const float64 getDoubleConstant(const unsigned int nIndex) +{ + extern const float64 float64Constant[]; + return float64Constant[nIndex]; +} + +static inline const float32 getSingleConstant(const unsigned int nIndex) +{ + extern const float32 float32Constant[]; + return float32Constant[nIndex]; +} + +static inline unsigned int getTransferLength(const unsigned int opcode) +{ + unsigned int nRc; + + switch (opcode & MASK_TRANSFER_LENGTH) { + case 0x00000000: + nRc = 1; + break; /* single precision */ + case 0x00008000: + nRc = 2; + break; /* double precision */ + case 0x00400000: + nRc = 3; + break; /* extended precision */ + default: + nRc = 0; + } + + return (nRc); +} + +static inline unsigned int getRegisterCount(const unsigned int opcode) +{ + unsigned int nRc; + + switch (opcode & MASK_REGISTER_COUNT) { + case 0x00000000: + nRc = 4; + break; + case 0x00008000: + nRc = 1; + break; + case 0x00400000: + nRc = 2; + break; + case 0x00408000: + nRc = 3; + break; + default: + nRc = 0; + } + + return (nRc); +} + +static inline unsigned int getRoundingPrecision(const unsigned int opcode) +{ + unsigned int nRc; + + switch (opcode & MASK_ROUNDING_PRECISION) { + case 0x00000000: + nRc = 1; + break; + case 0x00000080: + nRc = 2; + break; + case 0x00080000: + nRc = 3; + break; + default: + nRc = 0; + } + + return (nRc); +} + +static inline unsigned int getDestinationSize(const unsigned int opcode) +{ + unsigned int nRc; + + switch (opcode & MASK_DESTINATION_SIZE) { + case 0x00000000: + nRc = typeSingle; + break; + case 0x00000080: + nRc = typeDouble; + break; + case 0x00080000: + nRc = typeExtended; + break; + default: + nRc = typeNone; + } + + return (nRc); +} + +#endif diff --git a/arch/arm/nwfpe/fpsr.h b/arch/arm/nwfpe/fpsr.h new file mode 100644 index 0000000..859b300 --- /dev/null +++ b/arch/arm/nwfpe/fpsr.h @@ -0,0 +1,108 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.com, 1998-1999 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __FPSR_H__ +#define __FPSR_H__ + +/* +The FPSR is a 32 bit register consisting of 4 parts, each exactly +one byte. + + SYSTEM ID + EXCEPTION TRAP ENABLE BYTE + SYSTEM CONTROL BYTE + CUMULATIVE EXCEPTION FLAGS BYTE + +The FPCR is a 32 bit register consisting of bit flags. +*/ + +/* SYSTEM ID +------------ +Note: the system id byte is read only */ + +typedef unsigned int FPSR; /* type for floating point status register */ +typedef unsigned int FPCR; /* type for floating point control register */ + +#define MASK_SYSID 0xff000000 +#define BIT_HARDWARE 0x80000000 +#define FP_EMULATOR 0x01000000 /* System ID for emulator */ +#define FP_ACCELERATOR 0x81000000 /* System ID for FPA11 */ + +/* EXCEPTION TRAP ENABLE BYTE +----------------------------- */ + +#define MASK_TRAP_ENABLE 0x00ff0000 +#define MASK_TRAP_ENABLE_STRICT 0x001f0000 +#define BIT_IXE 0x00100000 /* inexact exception enable */ +#define BIT_UFE 0x00080000 /* underflow exception enable */ +#define BIT_OFE 0x00040000 /* overflow exception enable */ +#define BIT_DZE 0x00020000 /* divide by zero exception enable */ +#define BIT_IOE 0x00010000 /* invalid operation exception enable */ + +/* SYSTEM CONTROL BYTE +---------------------- */ + +#define MASK_SYSTEM_CONTROL 0x0000ff00 +#define MASK_TRAP_STRICT 0x00001f00 + +#define BIT_AC 0x00001000 /* use alternative C-flag definition + for compares */ +#define BIT_EP 0x00000800 /* use expanded packed decimal format */ +#define BIT_SO 0x00000400 /* select synchronous operation of FPA */ +#define BIT_NE 0x00000200 /* NaN exception bit */ +#define BIT_ND 0x00000100 /* no denormalized numbers bit */ + +/* CUMULATIVE EXCEPTION FLAGS BYTE +---------------------------------- */ + +#define MASK_EXCEPTION_FLAGS 0x000000ff +#define MASK_EXCEPTION_FLAGS_STRICT 0x0000001f + +#define BIT_IXC 0x00000010 /* inexact exception flag */ +#define BIT_UFC 0x00000008 /* underflow exception flag */ +#define BIT_OFC 0x00000004 /* overfloat exception flag */ +#define BIT_DZC 0x00000002 /* divide by zero exception flag */ +#define BIT_IOC 0x00000001 /* invalid operation exception flag */ + +/* Floating Point Control Register +----------------------------------*/ + +#define BIT_RU 0x80000000 /* rounded up bit */ +#define BIT_IE 0x10000000 /* inexact bit */ +#define BIT_MO 0x08000000 /* mantissa overflow bit */ +#define BIT_EO 0x04000000 /* exponent overflow bit */ +#define BIT_SB 0x00000800 /* store bounce */ +#define BIT_AB 0x00000400 /* arithmetic bounce */ +#define BIT_RE 0x00000200 /* rounding exception */ +#define BIT_DA 0x00000100 /* disable FPA */ + +#define MASK_OP 0x00f08010 /* AU operation code */ +#define MASK_PR 0x00080080 /* AU precision */ +#define MASK_S1 0x00070000 /* AU source register 1 */ +#define MASK_S2 0x00000007 /* AU source register 2 */ +#define MASK_DS 0x00007000 /* AU destination register */ +#define MASK_RM 0x00000060 /* AU rounding mode */ +#define MASK_ALU 0x9cfff2ff /* only ALU can write these bits */ +#define MASK_RESET 0x00000d00 /* bits set on reset, all others cleared */ +#define MASK_WFC MASK_RESET +#define MASK_RFC ~MASK_RESET + +#endif diff --git a/arch/arm/nwfpe/milieu.h b/arch/arm/nwfpe/milieu.h new file mode 100644 index 0000000..a3892ab --- /dev/null +++ b/arch/arm/nwfpe/milieu.h @@ -0,0 +1,48 @@ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/softfloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Include common integer types and flags. +------------------------------------------------------------------------------- +*/ +#include "ARM-gcc.h" + +/* +------------------------------------------------------------------------------- +Symbolic Boolean literals. +------------------------------------------------------------------------------- +*/ +enum { + FALSE = 0, + TRUE = 1 +}; + diff --git a/arch/arm/nwfpe/single_cpdo.c b/arch/arm/nwfpe/single_cpdo.c new file mode 100644 index 0000000..705808e --- /dev/null +++ b/arch/arm/nwfpe/single_cpdo.c @@ -0,0 +1,124 @@ +/* + NetWinder Floating Point Emulator + (c) Rebel.COM, 1998,1999 + (c) Philip Blundell, 2001 + + Direct questions, comments to Scott Bambrough <scottb@netwinder.org> + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "fpa11.h" +#include "softfloat.h" +#include "fpopcode.h" + +float32 float32_exp(float32 Fm); +float32 float32_ln(float32 Fm); +float32 float32_sin(float32 rFm); +float32 float32_cos(float32 rFm); +float32 float32_arcsin(float32 rFm); +float32 float32_arctan(float32 rFm); +float32 float32_log(float32 rFm); +float32 float32_tan(float32 rFm); +float32 float32_arccos(float32 rFm); +float32 float32_pow(float32 rFn, float32 rFm); +float32 float32_pol(float32 rFn, float32 rFm); + +static float32 float32_rsf(float32 rFn, float32 rFm) +{ + return float32_sub(rFm, rFn); +} + +static float32 float32_rdv(float32 rFn, float32 rFm) +{ + return float32_div(rFm, rFn); +} + +static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = { + [ADF_CODE >> 20] = float32_add, + [MUF_CODE >> 20] = float32_mul, + [SUF_CODE >> 20] = float32_sub, + [RSF_CODE >> 20] = float32_rsf, + [DVF_CODE >> 20] = float32_div, + [RDF_CODE >> 20] = float32_rdv, + [RMF_CODE >> 20] = float32_rem, + + [FML_CODE >> 20] = float32_mul, + [FDV_CODE >> 20] = float32_div, + [FRD_CODE >> 20] = float32_rdv, +}; + +static float32 float32_mvf(float32 rFm) +{ + return rFm; +} + +static float32 float32_mnf(float32 rFm) +{ + return rFm ^ 0x80000000; +} + +static float32 float32_abs(float32 rFm) +{ + return rFm & 0x7fffffff; +} + +static float32 (*const monadic_single[16])(float32 rFm) = { + [MVF_CODE >> 20] = float32_mvf, + [MNF_CODE >> 20] = float32_mnf, + [ABS_CODE >> 20] = float32_abs, + [RND_CODE >> 20] = float32_round_to_int, + [URD_CODE >> 20] = float32_round_to_int, + [SQT_CODE >> 20] = float32_sqrt, + [NRM_CODE >> 20] = float32_mvf, +}; + +unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) +{ + FPA11 *fpa11 = GET_FPA11(); + float32 rFm; + unsigned int Fm, opc_mask_shift; + + Fm = getFm(opcode); + if (CONSTANT_FM(opcode)) { + rFm = getSingleConstant(Fm); + } else if (fpa11->fType[Fm] == typeSingle) { + rFm = fpa11->fpreg[Fm].fSingle; + } else { + return 0; + } + + opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20; + if (!MONADIC_INSTRUCTION(opcode)) { + unsigned int Fn = getFn(opcode); + float32 rFn; + + if (fpa11->fType[Fn] == typeSingle && + dyadic_single[opc_mask_shift]) { + rFn = fpa11->fpreg[Fn].fSingle; + rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm); + } else { + return 0; + } + } else { + if (monadic_single[opc_mask_shift]) { + rFd->fSingle = monadic_single[opc_mask_shift](rFm); + } else { + return 0; + } + } + + return 1; +} diff --git a/arch/arm/nwfpe/softfloat-macros b/arch/arm/nwfpe/softfloat-macros new file mode 100644 index 0000000..5469989 --- /dev/null +++ b/arch/arm/nwfpe/softfloat-macros @@ -0,0 +1,740 @@ + +/* +=============================================================================== + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/softfloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Shifts `a' right by the number of bits given in `count'. If any nonzero +bits are shifted off, they are ``jammed'' into the least significant bit of +the result by setting the least significant bit to 1. The value of `count' +can be arbitrarily large; in particular, if `count' is greater than 32, the +result will be either 0 or 1, depending on whether `a' is zero or nonzero. +The result is stored in the location pointed to by `zPtr'. +------------------------------------------------------------------------------- +*/ +INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) +{ + bits32 z; + if ( count == 0 ) { + z = a; + } + else if ( count < 32 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + *zPtr = z; +} + +/* +------------------------------------------------------------------------------- +Shifts `a' right by the number of bits given in `count'. If any nonzero +bits are shifted off, they are ``jammed'' into the least significant bit of +the result by setting the least significant bit to 1. The value of `count' +can be arbitrarily large; in particular, if `count' is greater than 64, the +result will be either 0 or 1, depending on whether `a' is zero or nonzero. +The result is stored in the location pointed to by `zPtr'. +------------------------------------------------------------------------------- +*/ +INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) +{ + bits64 z; + + __asm__("@shift64RightJamming -- start"); + if ( count == 0 ) { + z = a; + } + else if ( count < 64 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + __asm__("@shift64RightJamming -- end"); + *zPtr = z; +} + +/* +------------------------------------------------------------------------------- +Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 +_plus_ the number of bits given in `count'. The shifted result is at most +64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The +bits shifted off form a second 64-bit result as follows: The _last_ bit +shifted off is the most-significant bit of the extra result, and the other +63 bits of the extra result are all zero if and only if _all_but_the_last_ +bits shifted off were all zero. This extra result is stored in the location +pointed to by `z1Ptr'. The value of `count' can be arbitrarily large. + (This routine makes more sense if `a0' and `a1' are considered to form a +fixed-point value with binary point between `a0' and `a1'. This fixed-point +value is shifted right by the number of bits given in `count', and the +integer part of the result is returned at the location pointed to by +`z0Ptr'. The fractional part of the result may be slightly corrupted as +described above, and is returned at the location pointed to by `z1Ptr'.) +------------------------------------------------------------------------------- +*/ +INLINE void + shift64ExtraRightJamming( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<<negCount ) | ( a1 != 0 ); + z0 = a0>>count; + } + else { + if ( count == 64 ) { + z1 = a0 | ( a1 != 0 ); + } + else { + z1 = ( ( a0 | a1 ) != 0 ); + } + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +number of bits given in `count'. Any bits shifted off are lost. The value +of `count' can be arbitrarily large; in particular, if `count' is greater +than 128, the result will be 0. The result is broken into two 64-bit pieces +which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shift128Right( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<<negCount ) | ( a1>>count ); + z0 = a0>>count; + } + else { + z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0; + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +number of bits given in `count'. If any nonzero bits are shifted off, they +are ``jammed'' into the least significant bit of the result by setting the +least significant bit to 1. The value of `count' can be arbitrarily large; +in particular, if `count' is greater than 128, the result will be either 0 +or 1, depending on whether the concatenation of `a0' and `a1' is zero or +nonzero. The result is broken into two 64-bit pieces which are stored at +the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shift128RightJamming( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 ); + z0 = a0>>count; + } + else { + if ( count == 64 ) { + z1 = a0 | ( a1 != 0 ); + } + else if ( count < 128 ) { + z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 ); + } + else { + z1 = ( ( a0 | a1 ) != 0 ); + } + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right +by 64 _plus_ the number of bits given in `count'. The shifted result is +at most 128 nonzero bits; these are broken into two 64-bit pieces which are +stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted +off form a third 64-bit result as follows: The _last_ bit shifted off is +the most-significant bit of the extra result, and the other 63 bits of the +extra result are all zero if and only if _all_but_the_last_ bits shifted off +were all zero. This extra result is stored in the location pointed to by +`z2Ptr'. The value of `count' can be arbitrarily large. + (This routine makes more sense if `a0', `a1', and `a2' are considered +to form a fixed-point value with binary point between `a1' and `a2'. This +fixed-point value is shifted right by the number of bits given in `count', +and the integer part of the result is returned at the locations pointed to +by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly +corrupted as described above, and is returned at the location pointed to by +`z2Ptr'.) +------------------------------------------------------------------------------- +*/ +INLINE void + shift128ExtraRightJamming( + bits64 a0, + bits64 a1, + bits64 a2, + int16 count, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z2 = a2; + z1 = a1; + z0 = a0; + } + else { + if ( count < 64 ) { + z2 = a1<<negCount; + z1 = ( a0<<negCount ) | ( a1>>count ); + z0 = a0>>count; + } + else { + if ( count == 64 ) { + z2 = a1; + z1 = a0; + } + else { + a2 |= a1; + if ( count < 128 ) { + z2 = a0<<negCount; + z1 = a0>>( count & 63 ); + } + else { + z2 = ( count == 128 ) ? a0 : ( a0 != 0 ); + z1 = 0; + } + } + z0 = 0; + } + z2 |= ( a2 != 0 ); + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the +number of bits given in `count'. Any bits shifted off are lost. The value +of `count' must be less than 64. The result is broken into two 64-bit +pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shortShift128Left( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + + *z1Ptr = a1<<count; + *z0Ptr = + ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) ); + +} + +/* +------------------------------------------------------------------------------- +Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left +by the number of bits given in `count'. Any bits shifted off are lost. +The value of `count' must be less than 64. The result is broken into three +64-bit pieces which are stored at the locations pointed to by `z0Ptr', +`z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shortShift192Left( + bits64 a0, + bits64 a1, + bits64 a2, + int16 count, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 negCount; + + z2 = a2<<count; + z1 = a1<<count; + z0 = a0<<count; + if ( 0 < count ) { + negCount = ( ( - count ) & 63 ); + z1 |= a2>>negCount; + z0 |= a1>>negCount; + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit +value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so +any carry out is lost. The result is broken into two 64-bit pieces which +are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + add128( + bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z1; + + z1 = a1 + b1; + *z1Ptr = z1; + *z0Ptr = a0 + b0 + ( z1 < a1 ); + +} + +/* +------------------------------------------------------------------------------- +Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the +192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is +modulo 2^192, so any carry out is lost. The result is broken into three +64-bit pieces which are stored at the locations pointed to by `z0Ptr', +`z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + add192( + bits64 a0, + bits64 a1, + bits64 a2, + bits64 b0, + bits64 b1, + bits64 b2, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 carry0, carry1; + + z2 = a2 + b2; + carry1 = ( z2 < a2 ); + z1 = a1 + b1; + carry0 = ( z1 < a1 ); + z0 = a0 + b0; + z1 += carry1; + z0 += ( z1 < carry1 ); + z0 += carry0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the +128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +2^128, so any borrow out (carry out) is lost. The result is broken into two +64-bit pieces which are stored at the locations pointed to by `z0Ptr' and +`z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + sub128( + bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - ( a1 < b1 ); + +} + +/* +------------------------------------------------------------------------------- +Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' +from the 192-bit value formed by concatenating `a0', `a1', and `a2'. +Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The +result is broken into three 64-bit pieces which are stored at the locations +pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + sub192( + bits64 a0, + bits64 a1, + bits64 a2, + bits64 b0, + bits64 b1, + bits64 b2, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 borrow0, borrow1; + + z2 = a2 - b2; + borrow1 = ( a2 < b2 ); + z1 = a1 - b1; + borrow0 = ( a1 < b1 ); + z0 = a0 - b0; + z0 -= ( z1 < borrow1 ); + z1 -= borrow1; + z0 -= borrow0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies `a' by `b' to obtain a 128-bit product. The product is broken +into two 64-bit pieces which are stored at the locations pointed to by +`z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits32 aHigh, aLow, bHigh, bLow; + bits64 z0, zMiddleA, zMiddleB, z1; + + aLow = a; + aHigh = a>>32; + bLow = b; + bHigh = b>>32; + z1 = ( (bits64) aLow ) * bLow; + zMiddleA = ( (bits64) aLow ) * bHigh; + zMiddleB = ( (bits64) aHigh ) * bLow; + z0 = ( (bits64) aHigh ) * bHigh; + zMiddleA += zMiddleB; + z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); + zMiddleA <<= 32; + z1 += zMiddleA; + z0 += ( z1 < zMiddleA ); + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies the 128-bit value formed by concatenating `a0' and `a1' by `b' to +obtain a 192-bit product. The product is broken into three 64-bit pieces +which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and +`z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + mul128By64To192( + bits64 a0, + bits64 a1, + bits64 b, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2, more1; + + mul64To128( a1, b, &z1, &z2 ); + mul64To128( a0, b, &z0, &more1 ); + add128( z0, more1, 0, z1, &z0, &z1 ); + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the +128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit +product. The product is broken into four 64-bit pieces which are stored at +the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + mul128To256( + bits64 a0, + bits64 a1, + bits64 b0, + bits64 b1, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr, + bits64 *z3Ptr + ) +{ + bits64 z0, z1, z2, z3; + bits64 more1, more2; + + mul64To128( a1, b1, &z2, &z3 ); + mul64To128( a1, b0, &z1, &more2 ); + add128( z1, more2, 0, z2, &z1, &z2 ); + mul64To128( a0, b0, &z0, &more1 ); + add128( z0, more1, 0, z1, &z0, &z1 ); + mul64To128( a0, b1, &more1, &more2 ); + add128( more1, more2, 0, z2, &more1, &z2 ); + add128( z0, z1, 0, more1, &z0, &z1 ); + *z3Ptr = z3; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Returns an approximation to the 64-bit integer quotient obtained by dividing +`b' into the 128-bit value formed by concatenating `a0' and `a1'. The +divisor `b' must be at least 2^63. If q is the exact quotient truncated +toward zero, the approximation returned lies between q and q + 2 inclusive. +If the exact quotient q is larger than 64 bits, the maximum positive 64-bit +unsigned integer is returned. +------------------------------------------------------------------------------- +*/ +static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) +{ + bits64 b0, b1; + bits64 rem0, rem1, term0, term1; + bits64 z; + if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); + b0 = b>>32; + z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; + mul64To128( b, z, &term0, &term1 ); + sub128( a0, a1, term0, term1, &rem0, &rem1 ); + while ( ( (sbits64) rem0 ) < 0 ) { + z -= LIT64( 0x100000000 ); + b1 = b<<32; + add128( rem0, rem1, b0, b1, &rem0, &rem1 ); + } + rem0 = ( rem0<<32 ) | ( rem1>>32 ); + z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns an approximation to the square root of the 32-bit significand given +by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of +`aExp' (the least significant bit) is 1, the integer returned approximates +2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' +is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either +case, the approximation returned lies strictly within +/-2 of the exact +value. +------------------------------------------------------------------------------- +*/ +static bits32 estimateSqrt32( int16 aExp, bits32 a ) +{ + static const bits16 sqrtOddAdjustments[] = { + 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, + 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 + }; + static const bits16 sqrtEvenAdjustments[] = { + 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, + 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 + }; + int8 index; + bits32 z; + + index = ( a>>27 ) & 15; + if ( aExp & 1 ) { + z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; + z = ( ( a / z )<<14 ) + ( z<<15 ); + a >>= 1; + } + else { + z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; + z = a / z + z; + z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); + if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); + } + return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the number of leading 0 bits before the most-significant 1 bit +of `a'. If `a' is zero, 32 is returned. +------------------------------------------------------------------------------- +*/ +static int8 countLeadingZeros32( bits32 a ) +{ + static const int8 countLeadingZerosHigh[] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + int8 shiftCount; + + shiftCount = 0; + if ( a < 0x10000 ) { + shiftCount += 16; + a <<= 16; + } + if ( a < 0x1000000 ) { + shiftCount += 8; + a <<= 8; + } + shiftCount += countLeadingZerosHigh[ a>>24 ]; + return shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Returns the number of leading 0 bits before the most-significant 1 bit +of `a'. If `a' is zero, 64 is returned. +------------------------------------------------------------------------------- +*/ +static int8 countLeadingZeros64( bits64 a ) +{ + int8 shiftCount; + + shiftCount = 0; + if ( a < ( (bits64) 1 )<<32 ) { + shiftCount += 32; + } + else { + a >>= 32; + } + shiftCount += countLeadingZeros32( a ); + return shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' +is equal to the 128-bit value formed by concatenating `b0' and `b1'. +Otherwise, returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 == b0 ) && ( a1 == b1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less +than or equal to the 128-bit value formed by concatenating `b0' and `b1'. +Otherwise, returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less +than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, +returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is +not equal to the 128-bit value formed by concatenating `b0' and `b1'. +Otherwise, returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 != b0 ) || ( a1 != b1 ); + +} + diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize new file mode 100644 index 0000000..acf4091 --- /dev/null +++ b/arch/arm/nwfpe/softfloat-specialize @@ -0,0 +1,366 @@ + +/* +=============================================================================== + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/softfloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Underflow tininess-detection mode, statically initialized to default value. +(The declaration in `softfloat.h' must match the `int8' type here.) +------------------------------------------------------------------------------- +*/ +int8 float_detect_tininess = float_tininess_after_rounding; + +/* +------------------------------------------------------------------------------- +Raises the exceptions specified by `flags'. Floating-point traps can be +defined here if desired. It is currently not possible for such a trap to +substitute a result value. If traps are not implemented, this routine +should be simply `float_exception_flags |= flags;'. + +ScottB: November 4, 1998 +Moved this function out of softfloat-specialize into fpmodule.c. +This effectively isolates all the changes required for integrating with the +Linux kernel into fpmodule.c. Porting to NetBSD should only require modifying +fpmodule.c to integrate with the NetBSD kernel (I hope!). +------------------------------------------------------------------------------- +void float_raise( int8 flags ) +{ + float_exception_flags |= flags; +} +*/ + +/* +------------------------------------------------------------------------------- +Internal canonical NaN format. +------------------------------------------------------------------------------- +*/ +typedef struct { + flag sign; + bits64 high, low; +} commonNaNT; + +/* +------------------------------------------------------------------------------- +The pattern for a default generated single-precision NaN. +------------------------------------------------------------------------------- +*/ +#define float32_default_nan 0xFFFFFFFF + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is a NaN; +otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float32_is_nan( float32 a ) +{ + + return ( 0xFF000000 < (bits32) ( a<<1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is a signaling +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float32_is_signaling_nan( float32 a ) +{ + + return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point NaN +`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT float32ToCommonNaN( float32 a ) +{ + commonNaNT z; + + if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>31; + z.low = 0; + z.high = ( (bits64) a )<<41; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the single- +precision floating-point format. +------------------------------------------------------------------------------- +*/ +static float32 commonNaNToFloat32( commonNaNT a ) +{ + + return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); + +} + +/* +------------------------------------------------------------------------------- +Takes two single-precision floating-point values `a' and `b', one of which +is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float32 propagateFloat32NaN( float32 a, float32 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float32_is_nan( a ); + aIsSignalingNaN = float32_is_signaling_nan( a ); + bIsNaN = float32_is_nan( b ); + bIsSignalingNaN = float32_is_signaling_nan( b ); + a |= 0x00400000; + b |= 0x00400000; + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +/* +------------------------------------------------------------------------------- +The pattern for a default generated double-precision NaN. +------------------------------------------------------------------------------- +*/ +#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is a NaN; +otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float64_is_nan( float64 a ) +{ + + return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is a signaling +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float64_is_signaling_nan( float64 a ) +{ + + return + ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) + && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point NaN +`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT float64ToCommonNaN( float64 a ) +{ + commonNaNT z; + + if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>63; + z.low = 0; + z.high = a<<12; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the double- +precision floating-point format. +------------------------------------------------------------------------------- +*/ +static float64 commonNaNToFloat64( commonNaNT a ) +{ + + return + ( ( (bits64) a.sign )<<63 ) + | LIT64( 0x7FF8000000000000 ) + | ( a.high>>12 ); + +} + +/* +------------------------------------------------------------------------------- +Takes two double-precision floating-point values `a' and `b', one of which +is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float64 propagateFloat64NaN( float64 a, float64 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float64_is_nan( a ); + aIsSignalingNaN = float64_is_signaling_nan( a ); + bIsNaN = float64_is_nan( b ); + bIsSignalingNaN = float64_is_signaling_nan( b ); + a |= LIT64( 0x0008000000000000 ); + b |= LIT64( 0x0008000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +The pattern for a default generated extended double-precision NaN. The +`high' and `low' values hold the most- and least-significant bits, +respectively. +------------------------------------------------------------------------------- +*/ +#define floatx80_default_nan_high 0xFFFF +#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is a +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag floatx80_is_nan( floatx80 a ) +{ + + return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is a +signaling NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag floatx80_is_signaling_nan( floatx80 a ) +{ + //register int lr; + bits64 aLow; + + //__asm__("mov %0, lr" : : "g" (lr)); + //fp_printk("floatx80_is_signalling_nan() called from 0x%08x\n",lr); + aLow = a.low & ~ LIT64( 0x4000000000000000 ); + return + ( ( a.high & 0x7FFF ) == 0x7FFF ) + && (bits64) ( aLow<<1 ) + && ( a.low == aLow ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the +invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT floatx80ToCommonNaN( floatx80 a ) +{ + commonNaNT z; + + if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>15; + z.low = 0; + z.high = a.low<<1; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the extended +double-precision floating-point format. +------------------------------------------------------------------------------- +*/ +static floatx80 commonNaNToFloatx80( commonNaNT a ) +{ + floatx80 z; + + z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); + z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; + return z; + +} + +/* +------------------------------------------------------------------------------- +Takes two extended double-precision floating-point values `a' and `b', one +of which is a NaN, and returns the appropriate NaN result. If either `a' or +`b' is a signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = floatx80_is_nan( a ); + aIsSignalingNaN = floatx80_is_signaling_nan( a ); + bIsNaN = floatx80_is_nan( b ); + bIsSignalingNaN = floatx80_is_signaling_nan( b ); + a.low |= LIT64( 0xC000000000000000 ); + b.low |= LIT64( 0xC000000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#endif diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c new file mode 100644 index 0000000..9d743ae --- /dev/null +++ b/arch/arm/nwfpe/softfloat.c @@ -0,0 +1,3443 @@ +/* +=============================================================================== + +This C source file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/softfloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +#include "fpa11.h" +//#include "milieu.h" +//#include "softfloat.h" + +/* +------------------------------------------------------------------------------- +Floating-point rounding mode, extended double-precision rounding precision, +and exception flags. +------------------------------------------------------------------------------- +*/ +int8 float_rounding_mode = float_round_nearest_even; +int8 floatx80_rounding_precision = 80; +int8 float_exception_flags; + +/* +------------------------------------------------------------------------------- +Primitive arithmetic functions, including multi-word arithmetic, and +division and square root approximations. (Can be specialized to target if +desired.) +------------------------------------------------------------------------------- +*/ +#include "softfloat-macros" + +/* +------------------------------------------------------------------------------- +Functions and definitions to determine: (1) whether tininess for underflow +is detected before or after rounding by default, (2) what (if anything) +happens when exceptions are raised, (3) how signaling NaNs are distinguished +from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs +are propagated from function inputs to output. These details are target- +specific. +------------------------------------------------------------------------------- +*/ +#include "softfloat-specialize" + +/* +------------------------------------------------------------------------------- +Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 +and 7, and returns the properly rounded 32-bit integer corresponding to the +input. If `zSign' is nonzero, the input is negated before being converted +to an integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point +input is simply rounded to an integer, with the inexact exception raised if +the input cannot be represented exactly as an integer. If the fixed-point +input is too large, however, the invalid exception is raised and the largest +positive or negative integer is returned. +------------------------------------------------------------------------------- +*/ +static int32 roundAndPackInt32( flag zSign, bits64 absZ ) +{ + int8 roundingMode; + flag roundNearestEven; + int8 roundIncrement, roundBits; + int32 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + roundIncrement = 0x40; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = 0x7F; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = absZ & 0x7F; + absZ = ( absZ + roundIncrement )>>7; + absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + z = absZ; + if ( zSign ) z = - z; + if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { + float_exception_flags |= float_flag_invalid; + return zSign ? 0x80000000 : 0x7FFFFFFF; + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the fraction bits of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE bits32 extractFloat32Frac( float32 a ) +{ + + return a & 0x007FFFFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the exponent bits of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE int16 extractFloat32Exp( float32 a ) +{ + + return ( a>>23 ) & 0xFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +#if 0 /* in softfloat.h */ +INLINE flag extractFloat32Sign( float32 a ) +{ + + return a>>31; + +} +#endif + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal single-precision floating-point value represented +by the denormalized significand `aSig'. The normalized exponent and +significand are stored at the locations pointed to by `zExpPtr' and +`zSigPtr', respectively. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( aSig ) - 8; + *zSigPtr = aSig<<shiftCount; + *zExpPtr = 1 - shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Packs the sign `zSign', exponent `zExp', and significand `zSig' into a +single-precision floating-point value, returning the result. After being +shifted into the proper positions, the three fields are simply added +together to form the result. This means that any integer portion of `zSig' +will be added into the exponent. Since a properly normalized significand +will have an integer portion equal to 1, the `zExp' input should be 1 less +than the desired result exponent whenever `zSig' is a complete, normalized +significand. +------------------------------------------------------------------------------- +*/ +INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ +#if 0 + float32 f; + __asm__("@ packFloat32 \n\ + mov %0, %1, asl #31 \n\ + orr %0, %2, asl #23 \n\ + orr %0, %3" + : /* no outputs */ + : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig) + : "cc"); + return f; +#else + return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig; +#endif +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper single-precision floating- +point value corresponding to the abstract input. Ordinarily, the abstract +value is simply rounded and packed into the single-precision format, with +the inexact exception raised if the abstract input cannot be represented +exactly. If the abstract value is too large, however, the overflow and +inexact exceptions are raised and an infinity or maximal finite value is +returned. If the abstract value is too small, the input value is rounded to +a subnormal number, and the underflow and inexact exceptions are raised if +the abstract input cannot be represented exactly as a subnormal single- +precision floating-point number. + The input significand `zSig' has its binary point between bits 30 +and 29, which is 7 bits to the left of the usual location. This shifted +significand must be normalized or smaller. If `zSig' is not normalized, +`zExp' must be 0; in that case, the result returned is a subnormal number, +and it must not require rounding. In the usual case that `zSig' is +normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. +The handling of underflow and overflow follows the IEC/IEEE Standard for +Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + int8 roundingMode; + flag roundNearestEven; + int8 roundIncrement, roundBits; + flag isTiny; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + roundIncrement = 0x40; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = 0x7F; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = zSig & 0x7F; + if ( 0xFD <= (bits16) zExp ) { + if ( ( 0xFD < zExp ) + || ( ( zExp == 0xFD ) + && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) + ) { + float_raise( float_flag_overflow | float_flag_inexact ); + return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 ); + } + if ( zExp < 0 ) { + isTiny = + ( float_detect_tininess == float_tininess_before_rounding ) + || ( zExp < -1 ) + || ( zSig + roundIncrement < 0x80000000 ); + shift32RightJamming( zSig, - zExp, &zSig ); + zExp = 0; + roundBits = zSig & 0x7F; + if ( isTiny && roundBits ) float_raise( float_flag_underflow ); + } + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + zSig = ( zSig + roundIncrement )>>7; + zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper single-precision floating- +point value corresponding to the abstract input. This routine is just like +`roundAndPackFloat32' except that `zSig' does not have to be normalized in +any way. In all cases, `zExp' must be 1 less than the ``true'' floating- +point exponent. +------------------------------------------------------------------------------- +*/ +static float32 + normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( zSig ) - 1; + return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount ); + +} + +/* +------------------------------------------------------------------------------- +Returns the fraction bits of the double-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE bits64 extractFloat64Frac( float64 a ) +{ + + return a & LIT64( 0x000FFFFFFFFFFFFF ); + +} + +/* +------------------------------------------------------------------------------- +Returns the exponent bits of the double-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE int16 extractFloat64Exp( float64 a ) +{ + + return ( a>>52 ) & 0x7FF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the double-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +#if 0 /* in softfloat.h */ +INLINE flag extractFloat64Sign( float64 a ) +{ + + return a>>63; + +} +#endif + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal double-precision floating-point value represented +by the denormalized significand `aSig'. The normalized exponent and +significand are stored at the locations pointed to by `zExpPtr' and +`zSigPtr', respectively. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( aSig ) - 11; + *zSigPtr = aSig<<shiftCount; + *zExpPtr = 1 - shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Packs the sign `zSign', exponent `zExp', and significand `zSig' into a +double-precision floating-point value, returning the result. After being +shifted into the proper positions, the three fields are simply added +together to form the result. This means that any integer portion of `zSig' +will be added into the exponent. Since a properly normalized significand +will have an integer portion equal to 1, the `zExp' input should be 1 less +than the desired result exponent whenever `zSig' is a complete, normalized +significand. +------------------------------------------------------------------------------- +*/ +INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig ) +{ + + return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig; + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper double-precision floating- +point value corresponding to the abstract input. Ordinarily, the abstract +value is simply rounded and packed into the double-precision format, with +the inexact exception raised if the abstract input cannot be represented +exactly. If the abstract value is too large, however, the overflow and +inexact exceptions are raised and an infinity or maximal finite value is +returned. If the abstract value is too small, the input value is rounded to +a subnormal number, and the underflow and inexact exceptions are raised if +the abstract input cannot be represented exactly as a subnormal double- +precision floating-point number. + The input significand `zSig' has its binary point between bits 62 +and 61, which is 10 bits to the left of the usual location. This shifted +significand must be normalized or smaller. If `zSig' is not normalized, +`zExp' must be 0; in that case, the result returned is a subnormal number, +and it must not require rounding. In the usual case that `zSig' is +normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. +The handling of underflow and overflow follows the IEC/IEEE Standard for +Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) +{ + int8 roundingMode; + flag roundNearestEven; + int16 roundIncrement, roundBits; + flag isTiny; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + roundIncrement = 0x200; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = 0x3FF; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = zSig & 0x3FF; + if ( 0x7FD <= (bits16) zExp ) { + if ( ( 0x7FD < zExp ) + || ( ( zExp == 0x7FD ) + && ( (sbits64) ( zSig + roundIncrement ) < 0 ) ) + ) { + //register int lr = __builtin_return_address(0); + //printk("roundAndPackFloat64 called from 0x%08x\n",lr); + float_raise( float_flag_overflow | float_flag_inexact ); + return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 ); + } + if ( zExp < 0 ) { + isTiny = + ( float_detect_tininess == float_tininess_before_rounding ) + || ( zExp < -1 ) + || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) ); + shift64RightJamming( zSig, - zExp, &zSig ); + zExp = 0; + roundBits = zSig & 0x3FF; + if ( isTiny && roundBits ) float_raise( float_flag_underflow ); + } + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + zSig = ( zSig + roundIncrement )>>10; + zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat64( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper double-precision floating- +point value corresponding to the abstract input. This routine is just like +`roundAndPackFloat64' except that `zSig' does not have to be normalized in +any way. In all cases, `zExp' must be 1 less than the ``true'' floating- +point exponent. +------------------------------------------------------------------------------- +*/ +static float64 + normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( zSig ) - 1; + return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount ); + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the fraction bits of the extended double-precision floating-point +value `a'. +------------------------------------------------------------------------------- +*/ +INLINE bits64 extractFloatx80Frac( floatx80 a ) +{ + + return a.low; + +} + +/* +------------------------------------------------------------------------------- +Returns the exponent bits of the extended double-precision floating-point +value `a'. +------------------------------------------------------------------------------- +*/ +INLINE int32 extractFloatx80Exp( floatx80 a ) +{ + + return a.high & 0x7FFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the extended double-precision floating-point value +`a'. +------------------------------------------------------------------------------- +*/ +INLINE flag extractFloatx80Sign( floatx80 a ) +{ + + return a.high>>15; + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal extended double-precision floating-point value +represented by the denormalized significand `aSig'. The normalized exponent +and significand are stored at the locations pointed to by `zExpPtr' and +`zSigPtr', respectively. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( aSig ); + *zSigPtr = aSig<<shiftCount; + *zExpPtr = 1 - shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Packs the sign `zSign', exponent `zExp', and significand `zSig' into an +extended double-precision floating-point value, returning the result. +------------------------------------------------------------------------------- +*/ +INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) +{ + floatx80 z; + + z.low = zSig; + z.high = ( ( (bits16) zSign )<<15 ) + zExp; + return z; + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and extended significand formed by the concatenation of `zSig0' and `zSig1', +and returns the proper extended double-precision floating-point value +corresponding to the abstract input. Ordinarily, the abstract value is +rounded and packed into the extended double-precision format, with the +inexact exception raised if the abstract input cannot be represented +exactly. If the abstract value is too large, however, the overflow and +inexact exceptions are raised and an infinity or maximal finite value is +returned. If the abstract value is too small, the input value is rounded to +a subnormal number, and the underflow and inexact exceptions are raised if +the abstract input cannot be represented exactly as a subnormal extended +double-precision floating-point number. + If `roundingPrecision' is 32 or 64, the result is rounded to the same +number of bits as single or double precision, respectively. Otherwise, the +result is rounded to the full precision of the extended double-precision +format. + The input significand must be normalized or smaller. If the input +significand is not normalized, `zExp' must be 0; in that case, the result +returned is a subnormal number, and it must not require rounding. The +handling of underflow and overflow follows the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static floatx80 + roundAndPackFloatx80( + int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 + ) +{ + int8 roundingMode; + flag roundNearestEven, increment, isTiny; + int64 roundIncrement, roundMask, roundBits; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + if ( roundingPrecision == 80 ) goto precision80; + if ( roundingPrecision == 64 ) { + roundIncrement = LIT64( 0x0000000000000400 ); + roundMask = LIT64( 0x00000000000007FF ); + } + else if ( roundingPrecision == 32 ) { + roundIncrement = LIT64( 0x0000008000000000 ); + roundMask = LIT64( 0x000000FFFFFFFFFF ); + } + else { + goto precision80; + } + zSig0 |= ( zSig1 != 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = roundMask; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = zSig0 & roundMask; + if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) { + if ( ( 0x7FFE < zExp ) + || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) ) + ) { + goto overflow; + } + if ( zExp <= 0 ) { + isTiny = + ( float_detect_tininess == float_tininess_before_rounding ) + || ( zExp < 0 ) + || ( zSig0 <= zSig0 + roundIncrement ); + shift64RightJamming( zSig0, 1 - zExp, &zSig0 ); + zExp = 0; + roundBits = zSig0 & roundMask; + if ( isTiny && roundBits ) float_raise( float_flag_underflow ); + if ( roundBits ) float_exception_flags |= float_flag_inexact; + zSig0 += roundIncrement; + if ( (sbits64) zSig0 < 0 ) zExp = 1; + roundIncrement = roundMask + 1; + if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) { + roundMask |= roundIncrement; + } + zSig0 &= ~ roundMask; + return packFloatx80( zSign, zExp, zSig0 ); + } + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + zSig0 += roundIncrement; + if ( zSig0 < roundIncrement ) { + ++zExp; + zSig0 = LIT64( 0x8000000000000000 ); + } + roundIncrement = roundMask + 1; + if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) { + roundMask |= roundIncrement; + } + zSig0 &= ~ roundMask; + if ( zSig0 == 0 ) zExp = 0; + return packFloatx80( zSign, zExp, zSig0 ); + precision80: + increment = ( (sbits64) zSig1 < 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && zSig1; + } + else { + increment = ( roundingMode == float_round_up ) && zSig1; + } + } + } + if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) { + if ( ( 0x7FFE < zExp ) + || ( ( zExp == 0x7FFE ) + && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) ) + && increment + ) + ) { + roundMask = 0; + overflow: + float_raise( float_flag_overflow | float_flag_inexact ); + if ( ( roundingMode == float_round_to_zero ) + || ( zSign && ( roundingMode == float_round_up ) ) + || ( ! zSign && ( roundingMode == float_round_down ) ) + ) { + return packFloatx80( zSign, 0x7FFE, ~ roundMask ); + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( zExp <= 0 ) { + isTiny = + ( float_detect_tininess == float_tininess_before_rounding ) + || ( zExp < 0 ) + || ! increment + || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) ); + shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 ); + zExp = 0; + if ( isTiny && zSig1 ) float_raise( float_flag_underflow ); + if ( zSig1 ) float_exception_flags |= float_flag_inexact; + if ( roundNearestEven ) { + increment = ( (sbits64) zSig1 < 0 ); + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && zSig1; + } + else { + increment = ( roundingMode == float_round_up ) && zSig1; + } + } + if ( increment ) { + ++zSig0; + zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven ); + if ( (sbits64) zSig0 < 0 ) zExp = 1; + } + return packFloatx80( zSign, zExp, zSig0 ); + } + } + if ( zSig1 ) float_exception_flags |= float_flag_inexact; + if ( increment ) { + ++zSig0; + if ( zSig0 == 0 ) { + ++zExp; + zSig0 = LIT64( 0x8000000000000000 ); + } + else { + zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven ); + } + } + else { + if ( zSig0 == 0 ) zExp = 0; + } + + return packFloatx80( zSign, zExp, zSig0 ); +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent +`zExp', and significand formed by the concatenation of `zSig0' and `zSig1', +and returns the proper extended double-precision floating-point value +corresponding to the abstract input. This routine is just like +`roundAndPackFloatx80' except that the input significand does not have to be +normalized. +------------------------------------------------------------------------------- +*/ +static floatx80 + normalizeRoundAndPackFloatx80( + int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 + ) +{ + int8 shiftCount; + + if ( zSig0 == 0 ) { + zSig0 = zSig1; + zSig1 = 0; + zExp -= 64; + } + shiftCount = countLeadingZeros64( zSig0 ); + shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); + zExp -= shiftCount; + return + roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 ); + +} + +#endif + +/* +------------------------------------------------------------------------------- +Returns the result of converting the 32-bit two's complement integer `a' to +the single-precision floating-point format. The conversion is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( int32 a ) +{ + flag zSign; + + if ( a == 0 ) return 0; + if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); + zSign = ( a < 0 ); + return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the 32-bit two's complement integer `a' to +the double-precision floating-point format. The conversion is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 int32_to_float64( int32 a ) +{ + flag aSign; + uint32 absA; + int8 shiftCount; + bits64 zSig; + + if ( a == 0 ) return 0; + aSign = ( a < 0 ); + absA = aSign ? - a : a; + shiftCount = countLeadingZeros32( absA ) + 21; + zSig = absA; + return packFloat64( aSign, 0x432 - shiftCount, zSig<<shiftCount ); + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the 32-bit two's complement integer `a' +to the extended double-precision floating-point format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 int32_to_floatx80( int32 a ) +{ + flag zSign; + uint32 absA; + int8 shiftCount; + bits64 zSig; + + if ( a == 0 ) return packFloatx80( 0, 0, 0 ); + zSign = ( a < 0 ); + absA = zSign ? - a : a; + shiftCount = countLeadingZeros32( absA ) + 32; + zSig = absA; + return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount ); + +} + +#endif + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 float32_to_int32( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + if ( aExp ) aSig |= 0x00800000; + shiftCount = 0xAF - aExp; + zSig = aSig; + zSig <<= 32; + if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig ); + return roundAndPackInt32( aSign, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. Otherwise, if the +conversion overflows, the largest integer with the same sign as `a' is +returned. +------------------------------------------------------------------------------- +*/ +int32 float32_to_int32_round_to_zero( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + int32 z; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0x9E; + if ( 0 <= shiftCount ) { + if ( a == 0xCF000000 ) return 0x80000000; + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; + return 0x80000000; + } + else if ( aExp <= 0x7E ) { + if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig = ( aSig | 0x00800000 )<<8; + z = aSig>>( - shiftCount ); + if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + return aSign ? - z : z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the double-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float32_to_float64( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); + return packFloat64( aSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the extended double-precision floating-point format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 float32_to_floatx80( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + aSig |= 0x00800000; + return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); + +} + +#endif + +/* +------------------------------------------------------------------------------- +Rounds the single-precision floating-point value `a' to an integer, and +returns the result as a single-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 lastBitMask, roundBitsMask; + int8 roundingMode; + float32 z; + + aExp = extractFloat32Exp( a ); + if ( 0x96 <= aExp ) { + if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { + return propagateFloat32NaN( a, a ); + } + return a; + } + if ( aExp <= 0x7E ) { + if ( (bits32) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat32Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { + return packFloat32( aSign, 0x7F, 0 ); + } + break; + case float_round_down: + return aSign ? 0xBF800000 : 0; + case float_round_up: + return aSign ? 0x80000000 : 0x3F800000; + } + return packFloat32( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x96 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the single-precision +floating-point values `a' and `b'. If `zSign' is true, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. The +addition is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 6; + bSig <<= 6; + if ( 0 < expDiff ) { + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x20000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x20000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); + zSig = 0x40000000 + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= 0x20000000; + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits32) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the single- +precision floating-point values `a' and `b'. If `zSign' is true, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 7; + bSig <<= 7; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign ^ 1, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x40000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + bSig |= 0x40000000; + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x40000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + aSig |= 0x40000000; + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the single-precision floating-point values `a' +and `b'. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_add( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return addFloat32Sigs( a, b, aSign ); + } + else { + return subFloat32Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the single-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_sub( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return subFloat32Sigs( a, b, aSign ); + } + else { + return addFloat32Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the single-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_mul( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig; + bits64 zSig64; + bits32 zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x7F; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); + zSig = zSig64; + if ( 0 <= (sbits32) ( zSig<<1 ) ) { + zSig <<= 1; + --zExp; + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the single-precision floating-point value `a' +by the corresponding value `b'. The operation is performed according to the +IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_div( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat32( zSign, 0xFF, 0 ); + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x7D; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = ( ( (bits64) aSig )<<32 ) / bSig; + if ( ( zSig & 0x3F ) == 0 ) { + zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 ); + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the remainder of the single-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_rem( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig, bSig; + bits32 q; + bits64 aSig64, bSig64, q64; + bits32 alternateASig; + sbits32 sigMean; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig |= 0x00800000; + bSig |= 0x00800000; + if ( expDiff < 32 ) { + aSig <<= 8; + bSig <<= 8; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + if ( 0 < expDiff ) { + q = ( ( (bits64) aSig )<<32 ) / bSig; + q >>= 32 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + } + else { + if ( bSig <= aSig ) aSig -= bSig; + aSig64 = ( (bits64) aSig )<<40; + bSig64 = ( (bits64) bSig )<<40; + expDiff -= 64; + while ( 0 < expDiff ) { + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + aSig64 = - ( ( bSig * q64 )<<38 ); + expDiff -= 62; + } + expDiff += 64; + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + q = q64>>( 64 - expDiff ); + bSig <<= 6; + aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits32) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits32) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the square root of the single-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_sqrt( float32 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig, zSig; + bits64 rem, term; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, 0 ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; + aSig = ( aSig | 0x00800000 )<<8; + zSig = estimateSqrt32( aExp, aSig ) + 2; + if ( ( zSig & 0x7F ) <= 5 ) { + if ( zSig < 2 ) { + zSig = 0xFFFFFFFF; + } + else { + aSig >>= aExp & 1; + term = ( (bits64) zSig ) * zSig; + rem = ( ( (bits64) aSig )<<32 ) - term; + while ( (sbits64) rem < 0 ) { + --zSig; + rem += ( ( (bits64) zSig )<<1 ) | 1; + } + zSig |= ( rem != 0 ); + } + } + shift32RightJamming( zSig, 1, &zSig ); + return roundAndPackFloat32( 0, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is equal to the +corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_eq( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_le( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_lt( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is equal to the +corresponding value `b', and 0 otherwise. The invalid exception is raised +if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_eq_signaling( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +cause an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_le_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + //int16 aExp, bExp; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +exception. Otherwise, the comparison is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_lt_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_int32( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x42C - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. Otherwise, if the +conversion overflows, the largest integer with the same sign as `a' is +returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_int32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + shiftCount = 0x433 - aExp; + if ( shiftCount < 21 ) { + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + goto invalid; + } + else if ( 52 < shiftCount ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig |= LIT64( 0x0010000000000000 ); + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_exception_flags |= float_flag_invalid; + return aSign ? 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<<shiftCount ) != savedASig ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement unsigned integer format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest positive integer is returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_uint32( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = 0; //extractFloat64Sign( a ); + //if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x42C - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. Otherwise, if the +conversion overflows, the largest positive integer is returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_uint32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + shiftCount = 0x433 - aExp; + if ( shiftCount < 21 ) { + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + goto invalid; + } + else if ( 52 < shiftCount ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig |= LIT64( 0x0010000000000000 ); + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_exception_flags |= float_flag_invalid; + return aSign ? 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<<shiftCount ) != savedASig ) { + float_exception_flags |= float_flag_inexact; + } + return z; +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the single-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float64_to_float32( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + bits32 zSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 22, &aSig ); + zSig = aSig; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x381; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the extended double-precision floating-point format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 float64_to_floatx80( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + return + packFloatx80( + aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 ); + +} + +#endif + +/* +------------------------------------------------------------------------------- +Rounds the double-precision floating-point value `a' to an integer, and +returns the result as a double-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float64 z; + + aExp = extractFloat64Exp( a ); + if ( 0x433 <= aExp ) { + if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { + return propagateFloat64NaN( a, a ); + } + return a; + } + if ( aExp <= 0x3FE ) { + if ( (bits64) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat64Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { + return packFloat64( aSign, 0x3FF, 0 ); + } + break; + case float_round_down: + return aSign ? LIT64( 0xBFF0000000000000 ) : 0; + case float_round_up: + return + aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); + } + return packFloat64( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x433 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the double-precision +floating-point values `a' and `b'. If `zSign' is true, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. The +addition is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 9; + bSig <<= 9; + if ( 0 < expDiff ) { + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); + zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= LIT64( 0x2000000000000000 ); + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits64) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the double- +precision floating-point values `a' and `b'. If `zSign' is true, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 10; + bSig <<= 10; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign ^ 1, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + bSig |= LIT64( 0x4000000000000000 ); + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + aSig |= LIT64( 0x4000000000000000 ); + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the double-precision floating-point values `a' +and `b'. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_add( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return addFloat64Sigs( a, b, aSign ); + } + else { + return subFloat64Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the double-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_sub( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return subFloat64Sigs( a, b, aSign ); + } + else { + return addFloat64Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the double-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_mul( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FF; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + zSig0 |= ( zSig1 != 0 ); + if ( 0 <= (sbits64) ( zSig0<<1 ) ) { + zSig0 <<= 1; + --zExp; + } + return roundAndPackFloat64( zSign, zExp, zSig0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the double-precision floating-point value `a' +by the corresponding value `b'. The operation is performed according to +the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_div( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + bits64 rem0, rem1; + bits64 term0, term1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat64( zSign, 0x7FF, 0 ); + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FD; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = estimateDiv128To64( aSig, 0, bSig ); + if ( ( zSig & 0x1FF ) <= 2 ) { + mul64To128( bSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig |= ( rem1 != 0 ); + } + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the remainder of the double-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_rem( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits64 aSig, bSig; + bits64 q, alternateASig; + sbits64 sigMean; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + aSig = - ( ( bSig>>2 ) * q ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits64) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits64) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the square root of the double-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_sqrt( float64 a ) +{ + flag aSign; + int16 aExp, zExp; + bits64 aSig, zSig; + bits64 rem0, rem1, term0, term1; //, shiftedRem; + //float64 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, a ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; + aSig |= LIT64( 0x0010000000000000 ); + zSig = estimateSqrt32( aExp, aSig>>21 ); + zSig <<= 31; + aSig <<= 9 - ( aExp & 1 ); + zSig = estimateDiv128To64( aSig, 0, zSig ) + zSig + 2; + if ( ( zSig & 0x3FF ) <= 5 ) { + if ( zSig < 2 ) { + zSig = LIT64( 0xFFFFFFFFFFFFFFFF ); + } + else { + aSig <<= 2; + mul64To128( zSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + shortShift128Left( 0, zSig, 1, &term0, &term1 ); + term1 |= 1; + add128( rem0, rem1, term0, term1, &rem0, &rem1 ); + } + zSig |= ( ( rem0 | rem1 ) != 0 ); + } + } + shift64RightJamming( zSig, 1, &zSig ); + return roundAndPackFloat64( 0, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is equal to the +corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_eq( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_le( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_lt( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is equal to the +corresponding value `b', and 0 otherwise. The invalid exception is raised +if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_eq_signaling( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +cause an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_le_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + //int16 aExp, bExp; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +exception. Otherwise, the comparison is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_lt_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the 32-bit two's complement integer format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic---which means in particular that the conversion +is rounded according to the current rounding mode. If `a' is a NaN, the +largest positive integer is returned. Otherwise, if the conversion +overflows, the largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 floatx80_to_int32( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + shiftCount = 0x4037 - aExp; + if ( shiftCount <= 0 ) shiftCount = 1; + shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the 32-bit two's complement integer format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic, except that the conversion is always rounded +toward zero. If `a' is a NaN, the largest positive integer is returned. +Otherwise, if the conversion overflows, the largest integer with the same +sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 floatx80_to_int32_round_to_zero( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + shiftCount = 0x403E - aExp; + if ( shiftCount < 32 ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + goto invalid; + } + else if ( 63 < shiftCount ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_exception_flags |= float_flag_invalid; + return aSign ? 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<<shiftCount ) != savedASig ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the single-precision floating-point format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 floatx80_to_float32( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat32( floatx80ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 33, &aSig ); + if ( aExp || aSig ) aExp -= 0x3F81; + return roundAndPackFloat32( aSign, aExp, aSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the double-precision floating-point format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 floatx80_to_float64( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig, zSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat64( floatx80ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shift64RightJamming( aSig, 1, &zSig ); + if ( aExp || aSig ) aExp -= 0x3C01; + return roundAndPackFloat64( aSign, aExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Rounds the extended double-precision floating-point value `a' to an integer, +and returns the result as an extended quadruple-precision floating-point +value. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + floatx80 z; + + aExp = extractFloatx80Exp( a ); + if ( 0x403E <= aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { + return propagateFloatx80NaN( a, a ); + } + return a; + } + if ( aExp <= 0x3FFE ) { + if ( ( aExp == 0 ) + && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { + return a; + } + float_exception_flags |= float_flag_inexact; + aSign = extractFloatx80Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) + ) { + return + packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + break; + case float_round_down: + return + aSign ? + packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) ) + : packFloatx80( 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloatx80( 1, 0, 0 ) + : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + return packFloatx80( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x403E - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.low += lastBitMask>>1; + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z.low += roundBitsMask; + } + } + z.low &= ~ roundBitsMask; + if ( z.low == 0 ) { + ++z.high; + z.low = LIT64( 0x8000000000000000 ); + } + if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the extended double- +precision floating-point values `a' and `b'. If `zSign' is true, the sum is +negated before being returned. `zSign' is ignored if the result is a NaN. +The addition is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + return a; + } + zSig1 = 0; + zSig0 = aSig + bSig; + if ( aExp == 0 ) { + normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); + goto roundAndPack; + } + zExp = aExp; + goto shiftRight1; + } + + zSig0 = aSig + bSig; + + if ( (sbits64) zSig0 < 0 ) goto roundAndPack; + shiftRight1: + shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= LIT64( 0x8000000000000000 ); + ++zExp; + roundAndPack: + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the extended +double-precision floating-point values `a' and `b'. If `zSign' is true, +the difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + zSig1 = 0; + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + bBigger: + sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + aBigger: + sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + return + normalizeRoundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the extended double-precision floating-point +values `a' and `b'. The operation is performed according to the IEC/IEEE +Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_add( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return addFloatx80Sigs( a, b, aSign ); + } + else { + return subFloatx80Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the extended double-precision floating- +point values `a' and `b'. The operation is performed according to the +IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_sub( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return subFloatx80Sigs( a, b, aSign ); + } + else { + return addFloatx80Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the extended double-precision floating- +point values `a' and `b'. The operation is performed according to the +IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_mul( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) goto invalid; + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FFE; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + if ( 0 < (sbits64) zSig0 ) { + shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); + --zExp; + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the extended double-precision floating-point +value `a' by the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_div( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + bits64 rem0, rem1, rem2, term0, term1, term2; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + goto invalid; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FFE; + rem1 = 0; + if ( bSig <= aSig ) { + shift128Right( aSig, 0, 1, &aSig, &rem1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig, rem1, bSig ); + mul64To128( bSig, zSig0, &term0, &term1 ); + sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, bSig ); + if ( (bits64) ( zSig1<<1 ) <= 8 ) { + mul64To128( bSig, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); + } + zSig1 |= ( ( rem1 | rem2 ) != 0 ); + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the remainder of the extended double-precision floating-point value +`a' with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_rem( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig; + bits64 q, term0, term1, alternateASig0, alternateASig1; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( (bits64) ( aSig0<<1 ) == 0 ) return a; + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + bSig |= LIT64( 0x8000000000000000 ); + zSign = aSign; + expDiff = aExp - bExp; + aSig1 = 0; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); + expDiff = 0; + } + q = ( bSig <= aSig0 ); + if ( q ) aSig0 -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + mul64To128( bSig, q, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); + while ( le128( term0, term1, aSig0, aSig1 ) ) { + ++q; + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + } + } + else { + term1 = 0; + term0 = bSig; + } + sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); + if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) + || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) + && ( q & 1 ) ) + ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + zSign = ! zSign; + } + return + normalizeRoundAndPackFloatx80( + 80, zSign, bExp + expDiff, aSig0, aSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the square root of the extended double-precision floating-point +value `a'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_sqrt( floatx80 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + bits64 shiftedRem0, shiftedRem1; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; + zSig0 = estimateSqrt32( aExp, aSig0>>32 ); + zSig0 <<= 31; + aSig1 = 0; + shift128Right( aSig0, 0, ( aExp & 1 ) + 2, &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4; + if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF ); + shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 ); + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + shortShift128Left( 0, zSig0, 1, &term0, &term1 ); + term1 |= 1; + add128( rem0, rem1, term0, term1, &rem0, &rem1 ); + } + shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 ); + zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 ); + if ( (bits64) ( zSig1<<1 ) <= 10 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( zSig0, zSig1, &term1, &term2 ); + shortShift128Left( term1, term2, 1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 ); + term3 |= 1; + add192( + rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is +equal to the corresponding value `b', and 0 otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_eq( floatx80 a, floatx80 b ) +{ + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is +less than or equal to the corresponding value `b', and 0 otherwise. The +comparison is performed according to the IEC/IEEE Standard for Binary +Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_le( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is +less than the corresponding value `b', and 0 otherwise. The comparison +is performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_lt( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is equal +to the corresponding value `b', and 0 otherwise. The invalid exception is +raised if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_eq_signaling( floatx80 a, floatx80 b ) +{ + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is less +than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs +do not cause an exception. Otherwise, the comparison is performed according +to the IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_le_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is less +than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause +an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_lt_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif + diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h new file mode 100644 index 0000000..1e17431 --- /dev/null +++ b/arch/arm/nwfpe/softfloat.h @@ -0,0 +1,278 @@ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/softfloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these three paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +#ifndef __SOFTFLOAT_H__ +#define __SOFTFLOAT_H__ + +#include <linux/config.h> + +/* +------------------------------------------------------------------------------- +The macro `FLOATX80' must be defined to enable the extended double-precision +floating-point format `floatx80'. If this macro is not defined, the +`floatx80' type will not be defined, and none of the functions that either +input or output the `floatx80' type will be defined. +------------------------------------------------------------------------------- +*/ +#ifdef CONFIG_FPE_NWFPE_XP +#define FLOATX80 +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point types. +------------------------------------------------------------------------------- +*/ +typedef unsigned long int float32; +typedef unsigned long long float64; +typedef struct { + unsigned short high; + unsigned long long low; +} floatx80; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point underflow tininess-detection mode. +------------------------------------------------------------------------------- +*/ +extern signed char float_detect_tininess; +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point rounding mode. +------------------------------------------------------------------------------- +*/ +extern signed char float_rounding_mode; +enum { + float_round_nearest_even = 0, + float_round_to_zero = 1, + float_round_down = 2, + float_round_up = 3 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point exception flags. +------------------------------------------------------------------------------- +extern signed char float_exception_flags; +enum { + float_flag_inexact = 1, + float_flag_underflow = 2, + float_flag_overflow = 4, + float_flag_divbyzero = 8, + float_flag_invalid = 16 +}; + +ScottB: November 4, 1998 +Changed the enumeration to match the bit order in the FPA11. +*/ + +extern signed char float_exception_flags; +enum { + float_flag_invalid = 1, + float_flag_divbyzero = 2, + float_flag_overflow = 4, + float_flag_underflow = 8, + float_flag_inexact = 16 +}; + +/* +------------------------------------------------------------------------------- +Routine to raise any or all of the software IEC/IEEE floating-point +exception flags. +------------------------------------------------------------------------------- +*/ +void float_raise( signed char ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE integer-to-floating-point conversion routines. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( signed int ); +float64 int32_to_float64( signed int ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( signed int ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision conversion routines. +------------------------------------------------------------------------------- +*/ +signed int float32_to_int32( float32 ); +signed int float32_to_int32_round_to_zero( float32 ); +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision operations. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +char float32_eq( float32, float32 ); +char float32_le( float32, float32 ); +char float32_lt( float32, float32 ); +char float32_eq_signaling( float32, float32 ); +char float32_le_quiet( float32, float32 ); +char float32_lt_quiet( float32, float32 ); +char float32_is_signaling_nan( float32 ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +signed int float64_to_int32( float64 ); +signed int float64_to_int32_round_to_zero( float64 ); +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision operations. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +char float64_eq( float64, float64 ); +char float64_le( float64, float64 ); +char float64_lt( float64, float64 ); +char float64_eq_signaling( float64, float64 ); +char float64_le_quiet( float64, float64 ); +char float64_lt_quiet( float64, float64 ); +char float64_is_signaling_nan( float64 ); + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +signed int floatx80_to_int32( floatx80 ); +signed int floatx80_to_int32_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision rounding precision. Valid +values are 32, 64, and 80. +------------------------------------------------------------------------------- +*/ +extern signed char floatx80_rounding_precision; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision operations. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +char floatx80_eq( floatx80, floatx80 ); +char floatx80_le( floatx80, floatx80 ); +char floatx80_lt( floatx80, floatx80 ); +char floatx80_eq_signaling( floatx80, floatx80 ); +char floatx80_le_quiet( floatx80, floatx80 ); +char floatx80_lt_quiet( floatx80, floatx80 ); +char floatx80_is_signaling_nan( floatx80 ); + +#endif + +static inline flag extractFloat32Sign(float32 a) +{ + return a >> 31; +} + +static inline flag float32_eq_nocheck(float32 a, float32 b) +{ + return (a == b) || ((bits32) ((a | b) << 1) == 0); +} + +static inline flag float32_lt_nocheck(float32 a, float32 b) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign(a); + bSign = extractFloat32Sign(b); + if (aSign != bSign) + return aSign && ((bits32) ((a | b) << 1) != 0); + return (a != b) && (aSign ^ (a < b)); +} + +static inline flag extractFloat64Sign(float64 a) +{ + return a >> 63; +} + +static inline flag float64_eq_nocheck(float64 a, float64 b) +{ + return (a == b) || ((bits64) ((a | b) << 1) == 0); +} + +static inline flag float64_lt_nocheck(float64 a, float64 b) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign(a); + bSign = extractFloat64Sign(b); + if (aSign != bSign) + return aSign && ((bits64) ((a | b) << 1) != 0); + return (a != b) && (aSign ^ (a < b)); +} + +#endif diff --git a/arch/arm/oprofile/Kconfig b/arch/arm/oprofile/Kconfig new file mode 100644 index 0000000..19d3773 --- /dev/null +++ b/arch/arm/oprofile/Kconfig @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile new file mode 100644 index 0000000..ba1a6e9 --- /dev/null +++ b/arch/arm/oprofile/Makefile @@ -0,0 +1,11 @@ +obj-$(CONFIG_OPROFILE) += oprofile.o + +DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ + oprof.o cpu_buffer.o buffer_sync.o \ + event_buffer.o oprofile_files.o \ + oprofilefs.o oprofile_stats.o \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) init.o +oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o + diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c new file mode 100644 index 0000000..e57dde8 --- /dev/null +++ b/arch/arm/oprofile/common.c @@ -0,0 +1,156 @@ +/** + * @file common.c + * + * @remark Copyright 2004 Oprofile Authors + * @remark Read the file COPYING + * + * @author Zwane Mwaikambo + */ + +#include <linux/init.h> +#include <linux/oprofile.h> +#include <linux/errno.h> +#include <asm/semaphore.h> +#include <linux/sysdev.h> + +#include "op_counter.h" +#include "op_arm_model.h" + +static struct op_arm_model_spec *pmu_model; +static int pmu_enabled; +static struct semaphore pmu_sem; + +static int pmu_start(void); +static int pmu_setup(void); +static void pmu_stop(void); +static int pmu_create_files(struct super_block *, struct dentry *); + +#ifdef CONFIG_PM +static int pmu_suspend(struct sys_device *dev, pm_message_t state) +{ + if (pmu_enabled) + pmu_stop(); + return 0; +} + +static int pmu_resume(struct sys_device *dev) +{ + if (pmu_enabled) + pmu_start(); + return 0; +} + +static struct sysdev_class oprofile_sysclass = { + set_kset_name("oprofile"), + .resume = pmu_resume, + .suspend = pmu_suspend, +}; + +static struct sys_device device_oprofile = { + .id = 0, + .cls = &oprofile_sysclass, +}; + +static int __init init_driverfs(void) +{ + int ret; + + if (!(ret = sysdev_class_register(&oprofile_sysclass))) + ret = sysdev_register(&device_oprofile); + + return ret; +} + +static void exit_driverfs(void) +{ + sysdev_unregister(&device_oprofile); + sysdev_class_unregister(&oprofile_sysclass); +} +#else +#define init_driverfs() do { } while (0) +#define exit_driverfs() do { } while (0) +#endif /* CONFIG_PM */ + +struct op_counter_config counter_config[OP_MAX_COUNTER]; + +static int pmu_create_files(struct super_block *sb, struct dentry *root) +{ + unsigned int i; + + for (i = 0; i < pmu_model->num_counters; i++) { + struct dentry *dir; + char buf[2]; + + snprintf(buf, sizeof buf, "%d", i); + dir = oprofilefs_mkdir(sb, root, buf); + oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); + oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event); + oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count); + oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); + oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); + oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); + } + + return 0; +} + +static int pmu_setup(void) +{ + int ret; + + spin_lock(&oprofilefs_lock); + ret = pmu_model->setup_ctrs(); + spin_unlock(&oprofilefs_lock); + return ret; +} + +static int pmu_start(void) +{ + int ret = -EBUSY; + + down(&pmu_sem); + if (!pmu_enabled) { + ret = pmu_model->start(); + pmu_enabled = !ret; + } + up(&pmu_sem); + return ret; +} + +static void pmu_stop(void) +{ + down(&pmu_sem); + if (pmu_enabled) + pmu_model->stop(); + pmu_enabled = 0; + up(&pmu_sem); +} + +int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec) +{ + init_MUTEX(&pmu_sem); + + if (spec->init() < 0) + return -ENODEV; + + pmu_model = spec; + init_driverfs(); + ops->create_files = pmu_create_files; + ops->setup = pmu_setup; + ops->shutdown = pmu_stop; + ops->start = pmu_start; + ops->stop = pmu_stop; + ops->cpu_type = pmu_model->name; + printk(KERN_INFO "oprofile: using %s PMU\n", spec->name); + + return 0; +} + +void pmu_exit(void) +{ + if (pmu_model) { + exit_driverfs(); + pmu_model = NULL; + } +} + diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c new file mode 100644 index 0000000..cce3d30 --- /dev/null +++ b/arch/arm/oprofile/init.c @@ -0,0 +1,31 @@ +/** + * @file init.c + * + * @remark Copyright 2004 Oprofile Authors + * @remark Read the file COPYING + * + * @author Zwane Mwaikambo + */ + +#include <linux/oprofile.h> +#include <linux/init.h> +#include <linux/errno.h> +#include "op_arm_model.h" + +int __init oprofile_arch_init(struct oprofile_operations *ops) +{ + int ret = -ENODEV; + +#ifdef CONFIG_CPU_XSCALE + ret = pmu_init(ops, &op_xscale_spec); +#endif + + return ret; +} + +void oprofile_arch_exit(void) +{ +#ifdef CONFIG_CPU_XSCALE + pmu_exit(); +#endif +} diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h new file mode 100644 index 0000000..2d4caf4 --- /dev/null +++ b/arch/arm/oprofile/op_arm_model.h @@ -0,0 +1,29 @@ +/** + * @file op_arm_model.h + * interface to ARM machine specific operations + * + * @remark Copyright 2004 Oprofile Authors + * @remark Read the file COPYING + * + * @author Zwane Mwaikambo + */ + +#ifndef OP_ARM_MODEL_H +#define OP_ARM_MODEL_H + +struct op_arm_model_spec { + int (*init)(void); + unsigned int num_counters; + int (*setup_ctrs)(void); + int (*start)(void); + void (*stop)(void); + char *name; +}; + +#ifdef CONFIG_CPU_XSCALE +extern struct op_arm_model_spec op_xscale_spec; +#endif + +extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); +extern void pmu_exit(void); +#endif /* OP_ARM_MODEL_H */ diff --git a/arch/arm/oprofile/op_counter.h b/arch/arm/oprofile/op_counter.h new file mode 100644 index 0000000..153c1d4 --- /dev/null +++ b/arch/arm/oprofile/op_counter.h @@ -0,0 +1,29 @@ +/** + * @file op_counter.h + * + * @remark Copyright 2004 Oprofile Authors + * @remark Read the file COPYING + * + * @author Zwane Mwaikambo + */ + +#ifndef OP_COUNTER_H +#define OP_COUNTER_H + +#define OP_MAX_COUNTER 5 + +/* Per performance monitor configuration as set via + * oprofilefs. + */ +struct op_counter_config { + unsigned long count; + unsigned long enabled; + unsigned long event; + unsigned long unit_mask; + unsigned long kernel; + unsigned long user; +}; + +extern struct op_counter_config counter_config[]; + +#endif /* OP_COUNTER_H */ diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c new file mode 100644 index 0000000..e0f0b32 --- /dev/null +++ b/arch/arm/oprofile/op_model_xscale.c @@ -0,0 +1,443 @@ +/** + * @file op_model_xscale.c + * XScale Performance Monitor Driver + * + * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com> + * @remark Copyright 2000-2004 MontaVista Software Inc + * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com> + * @remark Copyright 2004 Intel Corporation + * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk> + * @remark Copyright 2004 OProfile Authors + * + * @remark Read the file COPYING + * + * @author Zwane Mwaikambo + */ + +/* #define DEBUG */ +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/oprofile.h> +#include <linux/interrupt.h> +#include <asm/irq.h> +#include <asm/system.h> + +#include "op_counter.h" +#include "op_arm_model.h" + +#define PMU_ENABLE 0x001 /* Enable counters */ +#define PMN_RESET 0x002 /* Reset event counters */ +#define CCNT_RESET 0x004 /* Reset clock counter */ +#define PMU_RESET (CCNT_RESET | PMN_RESET) +#define PMU_CNT64 0x008 /* Make CCNT count every 64th cycle */ + +/* TODO do runtime detection */ +#ifdef CONFIG_ARCH_IOP310 +#define XSCALE_PMU_IRQ IRQ_XS80200_PMU +#endif +#ifdef CONFIG_ARCH_IOP321 +#define XSCALE_PMU_IRQ IRQ_IOP321_CORE_PMU +#endif +#ifdef CONFIG_ARCH_IOP331 +#define XSCALE_PMU_IRQ IRQ_IOP331_CORE_PMU +#endif +#ifdef CONFIG_ARCH_PXA +#define XSCALE_PMU_IRQ IRQ_PMU +#endif + +/* + * Different types of events that can be counted by the XScale PMU + * as used by Oprofile userspace. Here primarily for documentation + * purposes. + */ + +#define EVT_ICACHE_MISS 0x00 +#define EVT_ICACHE_NO_DELIVER 0x01 +#define EVT_DATA_STALL 0x02 +#define EVT_ITLB_MISS 0x03 +#define EVT_DTLB_MISS 0x04 +#define EVT_BRANCH 0x05 +#define EVT_BRANCH_MISS 0x06 +#define EVT_INSTRUCTION 0x07 +#define EVT_DCACHE_FULL_STALL 0x08 +#define EVT_DCACHE_FULL_STALL_CONTIG 0x09 +#define EVT_DCACHE_ACCESS 0x0A +#define EVT_DCACHE_MISS 0x0B +#define EVT_DCACE_WRITE_BACK 0x0C +#define EVT_PC_CHANGED 0x0D +#define EVT_BCU_REQUEST 0x10 +#define EVT_BCU_FULL 0x11 +#define EVT_BCU_DRAIN 0x12 +#define EVT_BCU_ECC_NO_ELOG 0x14 +#define EVT_BCU_1_BIT_ERR 0x15 +#define EVT_RMW 0x16 +/* EVT_CCNT is not hardware defined */ +#define EVT_CCNT 0xFE +#define EVT_UNUSED 0xFF + +struct pmu_counter { + volatile unsigned long ovf; + unsigned long reset_counter; +}; + +enum { CCNT, PMN0, PMN1, PMN2, PMN3, MAX_COUNTERS }; + +static struct pmu_counter results[MAX_COUNTERS]; + +/* + * There are two versions of the PMU in current XScale processors + * with differing register layouts and number of performance counters. + * e.g. IOP321 is xsc1 whilst IOP331 is xsc2. + * We detect which register layout to use in xscale_detect_pmu() + */ +enum { PMU_XSC1, PMU_XSC2 }; + +struct pmu_type { + int id; + char *name; + int num_counters; + unsigned int int_enable; + unsigned int cnt_ovf[MAX_COUNTERS]; + unsigned int int_mask[MAX_COUNTERS]; +}; + +static struct pmu_type pmu_parms[] = { + { + .id = PMU_XSC1, + .name = "arm/xscale1", + .num_counters = 3, + .int_mask = { [PMN0] = 0x10, [PMN1] = 0x20, + [CCNT] = 0x40 }, + .cnt_ovf = { [CCNT] = 0x400, [PMN0] = 0x100, + [PMN1] = 0x200}, + }, + { + .id = PMU_XSC2, + .name = "arm/xscale2", + .num_counters = 5, + .int_mask = { [CCNT] = 0x01, [PMN0] = 0x02, + [PMN1] = 0x04, [PMN2] = 0x08, + [PMN3] = 0x10 }, + .cnt_ovf = { [CCNT] = 0x01, [PMN0] = 0x02, + [PMN1] = 0x04, [PMN2] = 0x08, + [PMN3] = 0x10 }, + }, +}; + +static struct pmu_type *pmu; + +static void write_pmnc(u32 val) +{ + if (pmu->id == PMU_XSC1) { + /* upper 4bits and 7, 11 are write-as-0 */ + val &= 0xffff77f; + __asm__ __volatile__ ("mcr p14, 0, %0, c0, c0, 0" : : "r" (val)); + } else { + /* bits 4-23 are write-as-0, 24-31 are write ignored */ + val &= 0xf; + __asm__ __volatile__ ("mcr p14, 0, %0, c0, c1, 0" : : "r" (val)); + } +} + +static u32 read_pmnc(void) +{ + u32 val; + + if (pmu->id == PMU_XSC1) + __asm__ __volatile__ ("mrc p14, 0, %0, c0, c0, 0" : "=r" (val)); + else { + __asm__ __volatile__ ("mrc p14, 0, %0, c0, c1, 0" : "=r" (val)); + /* bits 1-2 and 4-23 are read-unpredictable */ + val &= 0xff000009; + } + + return val; +} + +static u32 __xsc1_read_counter(int counter) +{ + u32 val = 0; + + switch (counter) { + case CCNT: + __asm__ __volatile__ ("mrc p14, 0, %0, c1, c0, 0" : "=r" (val)); + break; + case PMN0: + __asm__ __volatile__ ("mrc p14, 0, %0, c2, c0, 0" : "=r" (val)); + break; + case PMN1: + __asm__ __volatile__ ("mrc p14, 0, %0, c3, c0, 0" : "=r" (val)); + break; + } + return val; +} + +static u32 __xsc2_read_counter(int counter) +{ + u32 val = 0; + + switch (counter) { + case CCNT: + __asm__ __volatile__ ("mrc p14, 0, %0, c1, c1, 0" : "=r" (val)); + break; + case PMN0: + __asm__ __volatile__ ("mrc p14, 0, %0, c0, c2, 0" : "=r" (val)); + break; + case PMN1: + __asm__ __volatile__ ("mrc p14, 0, %0, c1, c2, 0" : "=r" (val)); + break; + case PMN2: + __asm__ __volatile__ ("mrc p14, 0, %0, c2, c2, 0" : "=r" (val)); + break; + case PMN3: + __asm__ __volatile__ ("mrc p14, 0, %0, c3, c2, 0" : "=r" (val)); + break; + } + return val; +} + +static u32 read_counter(int counter) +{ + u32 val; + + if (pmu->id == PMU_XSC1) + val = __xsc1_read_counter(counter); + else + val = __xsc2_read_counter(counter); + + return val; +} + +static void __xsc1_write_counter(int counter, u32 val) +{ + switch (counter) { + case CCNT: + __asm__ __volatile__ ("mcr p14, 0, %0, c1, c0, 0" : : "r" (val)); + break; + case PMN0: + __asm__ __volatile__ ("mcr p14, 0, %0, c2, c0, 0" : : "r" (val)); + break; + case PMN1: + __asm__ __volatile__ ("mcr p14, 0, %0, c3, c0, 0" : : "r" (val)); + break; + } +} + +static void __xsc2_write_counter(int counter, u32 val) +{ + switch (counter) { + case CCNT: + __asm__ __volatile__ ("mcr p14, 0, %0, c1, c1, 0" : : "r" (val)); + break; + case PMN0: + __asm__ __volatile__ ("mcr p14, 0, %0, c0, c2, 0" : : "r" (val)); + break; + case PMN1: + __asm__ __volatile__ ("mcr p14, 0, %0, c1, c2, 0" : : "r" (val)); + break; + case PMN2: + __asm__ __volatile__ ("mcr p14, 0, %0, c2, c2, 0" : : "r" (val)); + break; + case PMN3: + __asm__ __volatile__ ("mcr p14, 0, %0, c3, c2, 0" : : "r" (val)); + break; + } +} + +static void write_counter(int counter, u32 val) +{ + if (pmu->id == PMU_XSC1) + __xsc1_write_counter(counter, val); + else + __xsc2_write_counter(counter, val); +} + +static int xscale_setup_ctrs(void) +{ + u32 evtsel, pmnc; + int i; + + for (i = CCNT; i < MAX_COUNTERS; i++) { + if (counter_config[i].enabled) + continue; + + counter_config[i].event = EVT_UNUSED; + } + + switch (pmu->id) { + case PMU_XSC1: + pmnc = (counter_config[PMN1].event << 20) | (counter_config[PMN0].event << 12); + pr_debug("xscale_setup_ctrs: pmnc: %#08x\n", pmnc); + write_pmnc(pmnc); + break; + + case PMU_XSC2: + evtsel = counter_config[PMN0].event | (counter_config[PMN1].event << 8) | + (counter_config[PMN2].event << 16) | (counter_config[PMN3].event << 24); + + pr_debug("xscale_setup_ctrs: evtsel %#08x\n", evtsel); + __asm__ __volatile__ ("mcr p14, 0, %0, c8, c1, 0" : : "r" (evtsel)); + break; + } + + for (i = CCNT; i < MAX_COUNTERS; i++) { + if (counter_config[i].event == EVT_UNUSED) { + counter_config[i].event = 0; + pmu->int_enable &= ~pmu->int_mask[i]; + continue; + } + + results[i].reset_counter = counter_config[i].count; + write_counter(i, -(u32)counter_config[i].count); + pmu->int_enable |= pmu->int_mask[i]; + pr_debug("xscale_setup_ctrs: counter%d %#08x from %#08lx\n", i, + read_counter(i), counter_config[i].count); + } + + return 0; +} + +static void inline __xsc1_check_ctrs(void) +{ + int i; + u32 pmnc = read_pmnc(); + + /* NOTE: there's an A stepping errata that states if an overflow */ + /* bit already exists and another occurs, the previous */ + /* Overflow bit gets cleared. There's no workaround. */ + /* Fixed in B stepping or later */ + + /* Write the value back to clear the overflow flags. Overflow */ + /* flags remain in pmnc for use below */ + write_pmnc(pmnc & ~PMU_ENABLE); + + for (i = CCNT; i <= PMN1; i++) { + if (!(pmu->int_mask[i] & pmu->int_enable)) + continue; + + if (pmnc & pmu->cnt_ovf[i]) + results[i].ovf++; + } +} + +static void inline __xsc2_check_ctrs(void) +{ + int i; + u32 flag = 0, pmnc = read_pmnc(); + + pmnc &= ~PMU_ENABLE; + write_pmnc(pmnc); + + /* read overflow flag register */ + __asm__ __volatile__ ("mrc p14, 0, %0, c5, c1, 0" : "=r" (flag)); + + for (i = CCNT; i <= PMN3; i++) { + if (!(pmu->int_mask[i] & pmu->int_enable)) + continue; + + if (flag & pmu->cnt_ovf[i]) + results[i].ovf++; + } + + /* writeback clears overflow bits */ + __asm__ __volatile__ ("mcr p14, 0, %0, c5, c1, 0" : : "r" (flag)); +} + +static irqreturn_t xscale_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) +{ + int i; + u32 pmnc; + + if (pmu->id == PMU_XSC1) + __xsc1_check_ctrs(); + else + __xsc2_check_ctrs(); + + for (i = CCNT; i < MAX_COUNTERS; i++) { + if (!results[i].ovf) + continue; + + write_counter(i, -(u32)results[i].reset_counter); + oprofile_add_sample(regs, i); + results[i].ovf--; + } + + pmnc = read_pmnc() | PMU_ENABLE; + write_pmnc(pmnc); + + return IRQ_HANDLED; +} + +static void xscale_pmu_stop(void) +{ + u32 pmnc = read_pmnc(); + + pmnc &= ~PMU_ENABLE; + write_pmnc(pmnc); + + free_irq(XSCALE_PMU_IRQ, results); +} + +static int xscale_pmu_start(void) +{ + int ret; + u32 pmnc = read_pmnc(); + + ret = request_irq(XSCALE_PMU_IRQ, xscale_pmu_interrupt, SA_INTERRUPT, + "XScale PMU", (void *)results); + + if (ret < 0) { + printk(KERN_ERR "oprofile: unable to request IRQ%d for XScale PMU\n", + XSCALE_PMU_IRQ); + return ret; + } + + if (pmu->id == PMU_XSC1) + pmnc |= pmu->int_enable; + else { + __asm__ __volatile__ ("mcr p14, 0, %0, c4, c1, 0" : : "r" (pmu->int_enable)); + pmnc &= ~PMU_CNT64; + } + + pmnc |= PMU_ENABLE; + write_pmnc(pmnc); + pr_debug("xscale_pmu_start: pmnc: %#08x mask: %08x\n", pmnc, pmu->int_enable); + return 0; +} + +static int xscale_detect_pmu(void) +{ + int ret = 0; + u32 id; + + id = (read_cpuid(CPUID_ID) >> 13) & 0x7; + + switch (id) { + case 1: + pmu = &pmu_parms[PMU_XSC1]; + break; + case 2: + pmu = &pmu_parms[PMU_XSC2]; + break; + default: + ret = -ENODEV; + break; + } + + if (!ret) { + op_xscale_spec.name = pmu->name; + op_xscale_spec.num_counters = pmu->num_counters; + pr_debug("xscale_detect_pmu: detected %s PMU\n", pmu->name); + } + + return ret; +} + +struct op_arm_model_spec op_xscale_spec = { + .init = xscale_detect_pmu, + .setup_ctrs = xscale_setup_ctrs, + .start = xscale_pmu_start, + .stop = xscale_pmu_stop, +}; + diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile new file mode 100644 index 0000000..c2a4993 --- /dev/null +++ b/arch/arm/tools/Makefile @@ -0,0 +1,9 @@ +# +# linux/arch/arm/tools/Makefile +# +# Copyright (C) 2001 Russell King +# + +include/asm-arm/mach-types.h: $(src)/gen-mach-types $(src)/mach-types + @echo ' Generating $@' + $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/arch/arm/tools/gen-mach-types b/arch/arm/tools/gen-mach-types new file mode 100644 index 0000000..2f9c9b5 --- /dev/null +++ b/arch/arm/tools/gen-mach-types @@ -0,0 +1,73 @@ +#!/bin/awk +# +# Awk script to generate include/asm-arm/mach-types.h +# +BEGIN { nr = 0 } +/^#/ { next } +/^[ ]*$/ { next } + +NF == 4 { + machine_is[nr] = "machine_is_"$1; + config[nr] = "CONFIG_"$2; + mach_type[nr] = "MACH_TYPE_"$3; + num[nr] = $4; nr++ + } + +NF == 3 { + machine_is[nr] = "machine_is_"$1; + config[nr] = "CONFIG_"$2; + mach_type[nr] = "MACH_TYPE_"$3; + num[nr] = ""; nr++ + } + + +END { + printf("/*\n"); + printf(" * This was automagically generated from %s!\n", FILENAME); + printf(" * Do NOT edit\n"); + printf(" */\n\n"); + printf("#ifndef __ASM_ARM_MACH_TYPE_H\n"); + printf("#define __ASM_ARM_MACH_TYPE_H\n\n"); + printf("#include <linux/config.h>\n\n"); + printf("#ifndef __ASSEMBLY__\n"); + printf("/* The type of machine we're running on */\n"); + printf("extern unsigned int __machine_arch_type;\n"); + printf("#endif\n\n"); + + printf("/* see arch/arm/kernel/arch.c for a description of these */\n"); + for (i = 0; i < nr; i++) + if (num[i] ~ /..*/) + printf("#define %-30s %d\n", mach_type[i], num[i]); + + printf("\n"); + + for (i = 0; i < nr; i++) + if (num[i] ~ /..*/) { + printf("#ifdef %s\n", config[i]); + printf("# ifdef machine_arch_type\n"); + printf("# undef machine_arch_type\n"); + printf("# define machine_arch_type\t__machine_arch_type\n"); + printf("# else\n"); + printf("# define machine_arch_type\t%s\n", mach_type[i]); + printf("# endif\n"); + printf("# define %s()\t(machine_arch_type == %s)\n", machine_is[i], mach_type[i]); + printf("#else\n"); + printf("# define %s()\t(0)\n", machine_is[i]); + printf("#endif\n\n"); + } + + printf("/*\n * These have not yet been registered\n */\n"); + for (i = 0; i < nr; i++) + if (num[i] !~ /..*/) + printf("/* #define %-30s <<not registered>> */\n", mach_type[i]); + + for (i = 0; i < nr; i++) + if (num[i] !~ /..*/) { + printf("#define %s()\t(0)\n", machine_is[i]); + } + + printf("\n#ifndef machine_arch_type\n"); + printf("#define machine_arch_type\t__machine_arch_type\n"); + printf("#endif\n\n"); + printf("#endif\n"); + } diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types new file mode 100644 index 0000000..30c1dfb --- /dev/null +++ b/arch/arm/tools/mach-types @@ -0,0 +1,726 @@ +# Database of machine macros and numbers +# +# This file is linux/arch/arm/tools/mach-types +# +# Please do not send patches to this file; it is automatically generated! +# To add an entry into this database, please see Documentation/arm/README, +# or contact rmk@arm.linux.org.uk +# +# Last update: Thu Mar 24 14:34:50 2005 +# +# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number +# +ebsa110 ARCH_EBSA110 EBSA110 0 +riscpc ARCH_RPC RISCPC 1 +nexuspci ARCH_NEXUSPCI NEXUSPCI 3 +ebsa285 ARCH_EBSA285 EBSA285 4 +netwinder ARCH_NETWINDER NETWINDER 5 +cats ARCH_CATS CATS 6 +tbox ARCH_TBOX TBOX 7 +co285 ARCH_CO285 CO285 8 +clps7110 ARCH_CLPS7110 CLPS7110 9 +archimedes ARCH_ARC ARCHIMEDES 10 +a5k ARCH_A5K A5K 11 +etoile ARCH_ETOILE ETOILE 12 +lacie_nas ARCH_LACIE_NAS LACIE_NAS 13 +clps7500 ARCH_CLPS7500 CLPS7500 14 +shark ARCH_SHARK SHARK 15 +brutus SA1100_BRUTUS BRUTUS 16 +personal_server ARCH_PERSONAL_SERVER PERSONAL_SERVER 17 +itsy SA1100_ITSY ITSY 18 +l7200 ARCH_L7200 L7200 19 +pleb SA1100_PLEB PLEB 20 +integrator ARCH_INTEGRATOR INTEGRATOR 21 +h3600 SA1100_H3600 H3600 22 +ixp1200 ARCH_IXP1200 IXP1200 23 +p720t ARCH_P720T P720T 24 +assabet SA1100_ASSABET ASSABET 25 +victor SA1100_VICTOR VICTOR 26 +lart SA1100_LART LART 27 +ranger SA1100_RANGER RANGER 28 +graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29 +xp860 SA1100_XP860 XP860 30 +cerf SA1100_CERF CERF 31 +nanoengine SA1100_NANOENGINE NANOENGINE 32 +fpic SA1100_FPIC FPIC 33 +extenex1 SA1100_EXTENEX1 EXTENEX1 34 +sherman SA1100_SHERMAN SHERMAN 35 +accelent_sa SA1100_ACCELENT ACCELENT_SA 36 +accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37 +netport SA1100_NETPORT NETPORT 38 +pangolin SA1100_PANGOLIN PANGOLIN 39 +yopy SA1100_YOPY YOPY 40 +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 SA1100_FLEXANET FLEXANET 54 +webpal ARCH_WEBPAL WEBPAL 55 +linpda SA1100_LINPDA LINPDA 56 +anakin ARCH_ANAKIN ANAKIN 57 +mvi SA1100_MVI MVI 58 +jupiter SA1100_JUPITER JUPITER 59 +psionw ARCH_PSIONW PSIONW 60 +aln SA1100_ALN ALN 61 +epxa ARCH_CAMELOT CAMELOT 62 +gds2200 SA1100_GDS2200 GDS2200 63 +psion_series7 SA1100_PSION_SERIES7 PSION_SERIES7 64 +xfile SA1100_XFILE XFILE 65 +accelent_ep9312 ARCH_ACCELENT_EP9312 ACCELENT_EP9312 66 +ic200 ARCH_IC200 IC200 67 +creditlart SA1100_CREDITLART CREDITLART 68 +htm SA1100_HTM HTM 69 +iq80310 ARCH_IQ80310 IQ80310 70 +freebot SA1100_FREEBOT FREEBOT 71 +entel ARCH_ENTEL ENTEL 72 +enp3510 ARCH_ENP3510 ENP3510 73 +trizeps SA1100_TRIZEPS TRIZEPS 74 +nesa SA1100_NESA NESA 75 +venus ARCH_VENUS VENUS 76 +tardis ARCH_TARDIS TARDIS 77 +mercury ARCH_MERCURY MERCURY 78 +empeg SA1100_EMPEG EMPEG 79 +adi_evb ARCH_I80200FCC I80200FCC 80 +itt_cpb SA1100_ITT_CPB ITT_CPB 81 +svc SA1100_SVC SVC 82 +alpha2 SA1100_ALPHA2 ALPHA2 84 +alpha1 SA1100_ALPHA1 ALPHA1 85 +netarm ARCH_NETARM NETARM 86 +simpad SA1100_SIMPAD SIMPAD 87 +pda1 ARCH_PDA1 PDA1 88 +lubbock ARCH_LUBBOCK LUBBOCK 89 +aniko ARCH_ANIKO ANIKO 90 +clep7212 ARCH_CLEP7212 CLEP7212 91 +cs89712 ARCH_CS89712 CS89712 92 +weararm SA1100_WEARARM WEARARM 93 +possio_px SA1100_POSSIO_PX POSSIO_PX 94 +sidearm SA1100_SIDEARM SIDEARM 95 +stork SA1100_STORK STORK 96 +shannon SA1100_SHANNON SHANNON 97 +ace ARCH_ACE ACE 98 +ballyarm SA1100_BALLYARM BALLYARM 99 +simputer SA1100_SIMPUTER SIMPUTER 100 +nexterm SA1100_NEXTERM NEXTERM 101 +sa1100_elf SA1100_SA1100_ELF SA1100_ELF 102 +gator SA1100_GATOR GATOR 103 +granite ARCH_GRANITE GRANITE 104 +consus SA1100_CONSUS CONSUS 105 +aaed2000 ARCH_AAED2000 AAED2000 106 +cdb89712 ARCH_CDB89712 CDB89712 107 +graphicsmaster SA1100_GRAPHICSMASTER GRAPHICSMASTER 108 +adsbitsy SA1100_ADSBITSY ADSBITSY 109 +pxa_idp ARCH_PXA_IDP PXA_IDP 110 +plce ARCH_PLCE PLCE 111 +pt_system3 SA1100_PT_SYSTEM3 PT_SYSTEM3 112 +murphy ARCH_MEDALB MEDALB 113 +eagle ARCH_EAGLE EAGLE 114 +dsc21 ARCH_DSC21 DSC21 115 +dsc24 ARCH_DSC24 DSC24 116 +ti5472 ARCH_TI5472 TI5472 117 +autcpu12 ARCH_AUTCPU12 AUTCPU12 118 +uengine ARCH_UENGINE UENGINE 119 +bluestem SA1100_BLUESTEM BLUESTEM 120 +xingu8 ARCH_XINGU8 XINGU8 121 +bushstb ARCH_BUSHSTB BUSHSTB 122 +epsilon1 SA1100_EPSILON1 EPSILON1 123 +balloon SA1100_BALLOON BALLOON 124 +puppy ARCH_PUPPY PUPPY 125 +elroy SA1100_ELROY ELROY 126 +gms720 ARCH_GMS720 GMS720 127 +s24x ARCH_S24X S24X 128 +jtel_clep7312 ARCH_JTEL_CLEP7312 JTEL_CLEP7312 129 +cx821xx ARCH_CX821XX CX821XX 130 +edb7312 ARCH_EDB7312 EDB7312 131 +bsa1110 SA1100_BSA1110 BSA1110 132 +powerpin ARCH_POWERPIN POWERPIN 133 +openarm ARCH_OPENARM OPENARM 134 +whitechapel SA1100_WHITECHAPEL WHITECHAPEL 135 +h3100 SA1100_H3100 H3100 136 +h3800 SA1100_H3800 H3800 137 +blue_v1 ARCH_BLUE_V1 BLUE_V1 138 +pxa_cerf ARCH_PXA_CERF PXA_CERF 139 +arm7tevb ARCH_ARM7TEVB ARM7TEVB 140 +d7400 SA1100_D7400 D7400 141 +piranha ARCH_PIRANHA PIRANHA 142 +sbcamelot SA1100_SBCAMELOT SBCAMELOT 143 +kings SA1100_KINGS KINGS 144 +smdk2400 ARCH_SMDK2400 SMDK2400 145 +collie SA1100_COLLIE COLLIE 146 +idr ARCH_IDR IDR 147 +badge4 SA1100_BADGE4 BADGE4 148 +webnet ARCH_WEBNET WEBNET 149 +d7300 SA1100_D7300 D7300 150 +cep SA1100_CEP CEP 151 +fortunet ARCH_FORTUNET FORTUNET 152 +vc547x ARCH_VC547X VC547X 153 +filewalker SA1100_FILEWALKER FILEWALKER 154 +netgateway SA1100_NETGATEWAY NETGATEWAY 155 +symbol2800 SA1100_SYMBOL2800 SYMBOL2800 156 +suns SA1100_SUNS SUNS 157 +frodo SA1100_FRODO FRODO 158 +ms301 SA1100_MACH_TYTE_MS301 MACH_TYTE_MS301 159 +mx1ads ARCH_MX1ADS MX1ADS 160 +h7201 ARCH_H7201 H7201 161 +h7202 ARCH_H7202 H7202 162 +amico ARCH_AMICO AMICO 163 +iam SA1100_IAM IAM 164 +tt530 SA1100_TT530 TT530 165 +sam2400 ARCH_SAM2400 SAM2400 166 +jornada56x SA1100_JORNADA56X JORNADA56X 167 +active SA1100_ACTIVE ACTIVE 168 +iq80321 ARCH_IQ80321 IQ80321 169 +wid SA1100_WID WID 170 +sabinal ARCH_SABINAL SABINAL 171 +ixp425_matacumbe ARCH_IXP425_MATACUMBE IXP425_MATACUMBE 172 +miniprint SA1100_MINIPRINT MINIPRINT 173 +adm510x ARCH_ADM510X ADM510X 174 +svs200 SA1100_SVS200 SVS200 175 +atg_tcu ARCH_ATG_TCU ATG_TCU 176 +jornada820 SA1100_JORNADA820 JORNADA820 177 +s3c44b0 ARCH_S3C44B0 S3C44B0 178 +margis2 ARCH_MARGIS2 MARGIS2 179 +ks8695 ARCH_KS8695 KS8695 180 +brh ARCH_BRH BRH 181 +s3c2410 ARCH_S3C2410 S3C2410 182 +possio_px30 ARCH_POSSIO_PX30 POSSIO_PX30 183 +s3c2800 ARCH_S3C2800 S3C2800 184 +fleetwood SA1100_FLEETWOOD FLEETWOOD 185 +omaha ARCH_OMAHA OMAHA 186 +ta7 ARCH_TA7 TA7 187 +nova SA1100_NOVA NOVA 188 +hmk ARCH_HMK HMK 189 +karo ARCH_KARO KARO 190 +fester SA1100_FESTER FESTER 191 +gpi ARCH_GPI GPI 192 +smdk2410 ARCH_SMDK2410 SMDK2410 193 +i519 ARCH_I519 I519 194 +nexio SA1100_NEXIO NEXIO 195 +bitbox SA1100_BITBOX BITBOX 196 +g200 SA1100_G200 G200 197 +gill SA1100_GILL GILL 198 +pxa_mercury ARCH_PXA_MERCURY PXA_MERCURY 199 +ceiva ARCH_CEIVA CEIVA 200 +fret SA1100_FRET FRET 201 +emailphone SA1100_EMAILPHONE EMAILPHONE 202 +h3900 ARCH_H3900 H3900 203 +pxa1 ARCH_PXA1 PXA1 204 +koan369 SA1100_KOAN369 KOAN369 205 +cogent ARCH_COGENT COGENT 206 +esl_simputer ARCH_ESL_SIMPUTER ESL_SIMPUTER 207 +esl_simputer_clr ARCH_ESL_SIMPUTER_CLR ESL_SIMPUTER_CLR 208 +esl_simputer_bw ARCH_ESL_SIMPUTER_BW ESL_SIMPUTER_BW 209 +hhp_cradle ARCH_HHP_CRADLE HHP_CRADLE 210 +he500 ARCH_HE500 HE500 211 +inhandelf2 SA1100_INHANDELF2 INHANDELF2 212 +inhandftip SA1100_INHANDFTIP INHANDFTIP 213 +dnp1110 SA1100_DNP1110 DNP1110 214 +pnp1110 SA1100_PNP1110 PNP1110 215 +csb226 ARCH_CSB226 CSB226 216 +arnold SA1100_ARNOLD ARNOLD 217 +voiceblue MACH_VOICEBLUE VOICEBLUE 218 +jz8028 ARCH_JZ8028 JZ8028 219 +h5400 ARCH_H5400 H5400 220 +forte SA1100_FORTE FORTE 221 +acam SA1100_ACAM ACAM 222 +abox SA1100_ABOX ABOX 223 +atmel ARCH_ATMEL ATMEL 224 +sitsang ARCH_SITSANG SITSANG 225 +cpu1110lcdnet SA1100_CPU1110LCDNET CPU1110LCDNET 226 +mpl_vcma9 ARCH_MPL_VCMA9 MPL_VCMA9 227 +opus_a1 ARCH_OPUS_A1 OPUS_A1 228 +daytona ARCH_DAYTONA DAYTONA 229 +killbear SA1100_KILLBEAR KILLBEAR 230 +yoho ARCH_YOHO YOHO 231 +jasper ARCH_JASPER JASPER 232 +dsc25 ARCH_DSC25 DSC25 233 +omap_innovator MACH_OMAP_INNOVATOR OMAP_INNOVATOR 234 +ramses ARCH_RAMSES RAMSES 235 +s28x ARCH_S28X S28X 236 +mport3 ARCH_MPORT3 MPORT3 237 +pxa_eagle250 ARCH_PXA_EAGLE250 PXA_EAGLE250 238 +pdb ARCH_PDB PDB 239 +blue_2g SA1100_BLUE_2G BLUE_2G 240 +bluearch SA1100_BLUEARCH BLUEARCH 241 +ixdp2400 ARCH_IXDP2400 IXDP2400 242 +ixdp2800 ARCH_IXDP2800 IXDP2800 243 +explorer SA1100_EXPLORER EXPLORER 244 +ixdp425 ARCH_IXDP425 IXDP425 245 +chimp ARCH_CHIMP CHIMP 246 +stork_nest ARCH_STORK_NEST STORK_NEST 247 +stork_egg ARCH_STORK_EGG STORK_EGG 248 +wismo SA1100_WISMO WISMO 249 +ezlinx ARCH_EZLINX EZLINX 250 +at91rm9200 ARCH_AT91RM9200 AT91RM9200 251 +orion ARCH_ORION ORION 252 +neptune ARCH_NEPTUNE NEPTUNE 253 +hackkit SA1100_HACKKIT HACKKIT 254 +pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255 +lavinna SA1100_LAVINNA LAVINNA 256 +pxa_uengine ARCH_PXA_UENGINE PXA_UENGINE 257 +innokom ARCH_INNOKOM INNOKOM 258 +bms ARCH_BMS BMS 259 +ixcdp1100 ARCH_IXCDP1100 IXCDP1100 260 +prpmc1100 ARCH_PRPMC1100 PRPMC1100 261 +at91rm9200dk ARCH_AT91RM9200DK AT91RM9200DK 262 +armstick ARCH_ARMSTICK ARMSTICK 263 +armonie ARCH_ARMONIE ARMONIE 264 +mport1 ARCH_MPORT1 MPORT1 265 +s3c5410 ARCH_S3C5410 S3C5410 266 +zcp320a ARCH_ZCP320A ZCP320A 267 +i_box ARCH_I_BOX I_BOX 268 +stlc1502 ARCH_STLC1502 STLC1502 269 +siren ARCH_SIREN SIREN 270 +greenlake ARCH_GREENLAKE GREENLAKE 271 +argus ARCH_ARGUS ARGUS 272 +combadge SA1100_COMBADGE COMBADGE 273 +rokepxa ARCH_ROKEPXA ROKEPXA 274 +cintegrator ARCH_CINTEGRATOR CINTEGRATOR 275 +guidea07 ARCH_GUIDEA07 GUIDEA07 276 +tat257 ARCH_TAT257 TAT257 277 +igp2425 ARCH_IGP2425 IGP2425 278 +bluegrama ARCH_BLUEGRAMMA BLUEGRAMMA 279 +ipod ARCH_IPOD IPOD 280 +adsbitsyx ARCH_ADSBITSYX ADSBITSYX 281 +trizeps2 ARCH_TRIZEPS2 TRIZEPS2 282 +viper ARCH_VIPER VIPER 283 +adsbitsyplus SA1100_ADSBITSYPLUS ADSBITSYPLUS 284 +adsagc SA1100_ADSAGC ADSAGC 285 +stp7312 ARCH_STP7312 STP7312 286 +nx_phnx MACH_NX_PHNX NX_PHNX 287 +wep_ep250 ARCH_WEP_EP250 WEP_EP250 288 +inhandelf3 ARCH_INHANDELF3 INHANDELF3 289 +adi_coyote ARCH_ADI_COYOTE ADI_COYOTE 290 +iyonix ARCH_IYONIX IYONIX 291 +damicam1 ARCH_DAMICAM_SA1110 DAMICAM_SA1110 292 +meg03 ARCH_MEG03 MEG03 293 +pxa_whitechapel ARCH_PXA_WHITECHAPEL PXA_WHITECHAPEL 294 +nwsc ARCH_NWSC NWSC 295 +nwlarm ARCH_NWLARM NWLARM 296 +ixp425_mguard ARCH_IXP425_MGUARD IXP425_MGUARD 297 +pxa_netdcu4 ARCH_PXA_NETDCU4 PXA_NETDCU4 298 +ixdp2401 ARCH_IXDP2401 IXDP2401 299 +ixdp2801 ARCH_IXDP2801 IXDP2801 300 +zodiac ARCH_ZODIAC ZODIAC 301 +armmodul ARCH_ARMMODUL ARMMODUL 302 +ketop SA1100_KETOP KETOP 303 +av7200 ARCH_AV7200 AV7200 304 +arch_ti925 ARCH_ARCH_TI925 ARCH_TI925 305 +acq200 ARCH_ACQ200 ACQ200 306 +pt_dafit SA1100_PT_DAFIT PT_DAFIT 307 +ihba ARCH_IHBA IHBA 308 +quinque ARCH_QUINQUE QUINQUE 309 +nimbraone ARCH_NIMBRAONE NIMBRAONE 310 +nimbra29x ARCH_NIMBRA29X NIMBRA29X 311 +nimbra210 ARCH_NIMBRA210 NIMBRA210 312 +hhp_d95xx ARCH_HHP_D95XX HHP_D95XX 313 +labarm ARCH_LABARM LABARM 314 +m825xx ARCH_M825XX M825XX 315 +m7100 SA1100_M7100 M7100 316 +nipc2 ARCH_NIPC2 NIPC2 317 +fu7202 ARCH_FU7202 FU7202 318 +adsagx ARCH_ADSAGX ADSAGX 319 +pxa_pooh ARCH_PXA_POOH PXA_POOH 320 +bandon ARCH_BANDON BANDON 321 +pcm7210 ARCH_PCM7210 PCM7210 322 +nms9200 ARCH_NMS9200 NMS9200 323 +logodl ARCH_LOGODL LOGODL 324 +m7140 SA1100_M7140 M7140 325 +korebot ARCH_KOREBOT KOREBOT 326 +iq31244 ARCH_IQ31244 IQ31244 327 +koan393 SA1100_KOAN393 KOAN393 328 +inhandftip3 ARCH_INHANDFTIP3 INHANDFTIP3 329 +gonzo ARCH_GONZO GONZO 330 +bast ARCH_BAST BAST 331 +scanpass ARCH_SCANPASS SCANPASS 332 +ep7312_pooh ARCH_EP7312_POOH EP7312_POOH 333 +ta7s ARCH_TA7S TA7S 334 +ta7v ARCH_TA7V TA7V 335 +icarus SA1100_ICARUS ICARUS 336 +h1900 ARCH_H1900 H1900 337 +gemini SA1100_GEMINI GEMINI 338 +axim ARCH_AXIM AXIM 339 +audiotron ARCH_AUDIOTRON AUDIOTRON 340 +h2200 ARCH_H2200 H2200 341 +loox600 ARCH_LOOX600 LOOX600 342 +niop ARCH_NIOP NIOP 343 +dm310 ARCH_DM310 DM310 344 +seedpxa_c2 ARCH_SEEDPXA_C2 SEEDPXA_C2 345 +ixp4xx_mguardpci ARCH_IXP4XX_MGUARD_PCI IXP4XX_MGUARD_PCI 346 +h1940 ARCH_H1940 H1940 347 +scorpio ARCH_SCORPIO SCORPIO 348 +viva ARCH_VIVA VIVA 349 +pxa_xcard ARCH_PXA_XCARD PXA_XCARD 350 +csb335 ARCH_CSB335 CSB335 351 +ixrd425 ARCH_IXRD425 IXRD425 352 +iq80315 ARCH_IQ80315 IQ80315 353 +nmp7312 ARCH_NMP7312 NMP7312 354 +cx861xx ARCH_CX861XX CX861XX 355 +enp2611 ARCH_ENP2611 ENP2611 356 +xda SA1100_XDA XDA 357 +csir_ims ARCH_CSIR_IMS CSIR_IMS 358 +ixp421_dnaeeth ARCH_IXP421_DNAEETH IXP421_DNAEETH 359 +pocketserv9200 ARCH_POCKETSERV9200 POCKETSERV9200 360 +toto ARCH_TOTO TOTO 361 +s3c2440 ARCH_S3C2440 S3C2440 362 +ks8695p ARCH_KS8695P KS8695P 363 +se4000 ARCH_SE4000 SE4000 364 +quadriceps ARCH_QUADRICEPS QUADRICEPS 365 +bronco ARCH_BRONCO BRONCO 366 +esl_wireless_tab ARCH_ESL_WIRELESS_TABLETESL_WIRELESS_TABLET 367 +esl_sofcomp ARCH_ESL_SOFCOMP ESL_SOFCOMP 368 +s5c7375 ARCH_S5C7375 S5C7375 369 +spearhead ARCH_SPEARHEAD SPEARHEAD 370 +pantera ARCH_PANTERA PANTERA 371 +prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372 +gumstix ARCH_GUMSTIK GUMSTIK 373 +rcube ARCH_RCUBE RCUBE 374 +rea_olv ARCH_REA_OLV REA_OLV 375 +pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376 +s3c3410 ARCH_S3C3410 S3C3410 377 +espd_4510b ARCH_ESPD_4510B ESPD_4510B 378 +mp1x ARCH_MP1X MP1X 379 +at91rm9200tb ARCH_AT91RM9200TB AT91RM9200TB 380 +adsvgx ARCH_ADSVGX ADSVGX 381 +omap_h2 MACH_OMAP_H2 OMAP_H2 382 +pelee ARCH_PELEE PELEE 383 +e740 MACH_E740 E740 384 +iq80331 ARCH_IQ80331 IQ80331 385 +versatile_pb ARCH_VERSATILE_PB VERSATILE_PB 387 +kev7a400 MACH_KEV7A400 KEV7A400 388 +lpd7a400 MACH_LPD7A400 LPD7A400 389 +lpd7a404 MACH_LPD7A404 LPD7A404 390 +fujitsu_camelot ARCH_FUJITSU_CAMELOT FUJITSU_CAMELOT 391 +janus2m ARCH_JANUS2M JANUS2M 392 +embtf MACH_EMBTF EMBTF 393 +hpm MACH_HPM HPM 394 +smdk2410tk MACH_SMDK2410TK SMDK2410TK 395 +smdk2410aj MACH_SMDK2410AJ SMDK2410AJ 396 +streetracer MACH_STREETRACER STREETRACER 397 +eframe MACH_EFRAME EFRAME 398 +csb337 MACH_CSB337 CSB337 399 +pxa_lark MACH_PXA_LARK PXA_LARK 400 +pxa_pnp2110 MACH_PNP2110 PNP2110 401 +tcc72x MACH_TCC72X TCC72X 402 +altair MACH_ALTAIR ALTAIR 403 +kc3 MACH_KC3 KC3 404 +sinteftd MACH_SINTEFTD SINTEFTD 405 +mainstone MACH_MAINSTONE MAINSTONE 406 +aday4x MACH_ADAY4X ADAY4X 407 +lite300 MACH_LITE300 LITE300 408 +s5c7376 MACH_S5C7376 S5C7376 409 +mt02 MACH_MT02 MT02 410 +mport3s MACH_MPORT3S MPORT3S 411 +ra_alpha MACH_RA_ALPHA RA_ALPHA 412 +xcep MACH_XCEP XCEP 413 +arcom_mercury MACH_ARCOM_MERCURY ARCOM_MERCURY 414 +stargate MACH_STARGATE STARGATE 415 +armadilloj MACH_ARMADILLOJ ARMADILLOJ 416 +elroy_jack MACH_ELROY_JACK ELROY_JACK 417 +backend MACH_BACKEND BACKEND 418 +s5linbox MACH_S5LINBOX S5LINBOX 419 +nomadik MACH_NOMADIK NOMADIK 420 +ia_cpu_9200 MACH_IA_CPU_9200 IA_CPU_9200 421 +at91_bja1 MACH_AT91_BJA1 AT91_BJA1 422 +corgi MACH_CORGI CORGI 423 +poodle MACH_POODLE POODLE 424 +ten MACH_TEN TEN 425 +roverp5p MACH_ROVERP5P ROVERP5P 426 +sc2700 MACH_SC2700 SC2700 427 +ex_eagle MACH_EX_EAGLE EX_EAGLE 428 +nx_pxa12 MACH_NX_PXA12 NX_PXA12 429 +nx_pxa5 MACH_NX_PXA5 NX_PXA5 430 +blackboard2 MACH_BLACKBOARD2 BLACKBOARD2 431 +i819 MACH_I819 I819 432 +ixmb995e MACH_IXMB995E IXMB995E 433 +skyrider MACH_SKYRIDER SKYRIDER 434 +skyhawk MACH_SKYHAWK SKYHAWK 435 +enterprise MACH_ENTERPRISE ENTERPRISE 436 +dep2410 MACH_DEP2410 DEP2410 437 +armcore MACH_ARMCORE ARMCORE 438 +hobbit MACH_HOBBIT HOBBIT 439 +h7210 MACH_H7210 H7210 440 +pxa_netdcu5 MACH_PXA_NETDCU5 PXA_NETDCU5 441 +acc MACH_ACC ACC 442 +esl_sarva MACH_ESL_SARVA ESL_SARVA 443 +xm250 MACH_XM250 XM250 444 +t6tc1xb MACH_T6TC1XB T6TC1XB 445 +ess710 MACH_ESS710 ESS710 446 +mx3ads MACH_MX3ADS MX3ADS 447 +himalaya MACH_HIMALAYA HIMALAYA 448 +bolfenk MACH_BOLFENK BOLFENK 449 +at91rm9200kr MACH_AT91RM9200KR AT91RM9200KR 450 +edb9312 MACH_EDB9312 EDB9312 451 +omap_generic MACH_OMAP_GENERIC OMAP_GENERIC 452 +aximx3 MACH_AXIMX3 AXIMX3 453 +eb67xdip MACH_EB67XDIP EB67XDIP 454 +webtxs MACH_WEBTXS WEBTXS 455 +hawk MACH_HAWK HAWK 456 +ccat91sbc001 MACH_CCAT91SBC001 CCAT91SBC001 457 +expresso MACH_EXPRESSO EXPRESSO 458 +h4000 MACH_H4000 H4000 459 +dino MACH_DINO DINO 460 +ml675k MACH_ML675K ML675K 461 +edb9301 MACH_EDB9301 EDB9301 462 +edb9315 MACH_EDB9315 EDB9315 463 +reciva_tt MACH_RECIVA_TT RECIVA_TT 464 +cstcb01 MACH_CSTCB01 CSTCB01 465 +cstcb1 MACH_CSTCB1 CSTCB1 466 +shadwell MACH_SHADWELL SHADWELL 467 +goepel263 MACH_GOEPEL263 GOEPEL263 468 +acq100 MACH_ACQ100 ACQ100 469 +mx1fs2 MACH_MX1FS2 MX1FS2 470 +hiptop_g1 MACH_HIPTOP_G1 HIPTOP_G1 471 +sparky MACH_SPARKY SPARKY 472 +ns9750 MACH_NS9750 NS9750 473 +phoenix MACH_PHOENIX PHOENIX 474 +vr1000 MACH_VR1000 VR1000 475 +deisterpxa MACH_DEISTERPXA DEISTERPXA 476 +bcm1160 MACH_BCM1160 BCM1160 477 +pcm022 MACH_PCM022 PCM022 478 +adsgcx MACH_ADSGCX ADSGCX 479 +dreadnaught MACH_DREADNAUGHT DREADNAUGHT 480 +dm320 MACH_DM320 DM320 481 +markov MACH_MARKOV MARKOV 482 +cos7a400 MACH_COS7A400 COS7A400 483 +milano MACH_MILANO MILANO 484 +ue9328 MACH_UE9328 UE9328 485 +uex255 MACH_UEX255 UEX255 486 +ue2410 MACH_UE2410 UE2410 487 +a620 MACH_A620 A620 488 +ocelot MACH_OCELOT OCELOT 489 +cheetah MACH_CHEETAH CHEETAH 490 +omap_perseus2 MACH_OMAP_PERSEUS2 OMAP_PERSEUS2 491 +zvue MACH_ZVUE ZVUE 492 +roverp1 MACH_ROVERP1 ROVERP1 493 +asidial2 MACH_ASIDIAL2 ASIDIAL2 494 +s3c24a0 MACH_S3C24A0 S3C24A0 495 +e800 MACH_E800 E800 496 +e750 MACH_E750 E750 497 +s3c5500 MACH_S3C5500 S3C5500 498 +smdk5500 MACH_SMDK5500 SMDK5500 499 +signalsync MACH_SIGNALSYNC SIGNALSYNC 500 +nbc MACH_NBC NBC 501 +kodiak MACH_KODIAK KODIAK 502 +netbookpro MACH_NETBOOKPRO NETBOOKPRO 503 +hw90200 MACH_HW90200 HW90200 504 +condor MACH_CONDOR CONDOR 505 +cup MACH_CUP CUP 506 +kite MACH_KITE KITE 507 +scb9328 MACH_SCB9328 SCB9328 508 +omap_h3 MACH_OMAP_H3 OMAP_H3 509 +omap_h4 MACH_OMAP_H4 OMAP_H4 510 +n10 MACH_N10 N10 511 +montejade MACH_MONTAJADE MONTAJADE 512 +sg560 MACH_SG560 SG560 513 +dp1000 MACH_DP1000 DP1000 514 +omap_osk MACH_OMAP_OSK OMAP_OSK 515 +rg100v3 MACH_RG100V3 RG100V3 516 +mx2ads MACH_MX2ADS MX2ADS 517 +pxa_kilo MACH_PXA_KILO PXA_KILO 518 +ixp4xx_eagle MACH_IXP4XX_EAGLE IXP4XX_EAGLE 519 +tosa MACH_TOSA TOSA 520 +mb2520f MACH_MB2520F MB2520F 521 +emc1000 MACH_EMC1000 EMC1000 522 +tidsc25 MACH_TIDSC25 TIDSC25 523 +akcpmxl MACH_AKCPMXL AKCPMXL 524 +av3xx MACH_AV3XX AV3XX 525 +avila MACH_AVILA AVILA 526 +pxa_mpm10 MACH_PXA_MPM10 PXA_MPM10 527 +pxa_kyanite MACH_PXA_KYANITE PXA_KYANITE 528 +sgold MACH_SGOLD SGOLD 529 +oscar MACH_OSCAR OSCAR 530 +epxa4usb2 MACH_EPXA4USB2 EPXA4USB2 531 +xsengine MACH_XSENGINE XSENGINE 532 +ip600 MACH_IP600 IP600 533 +mcan2 MACH_MCAN2 MCAN2 534 +ddi_blueridge MACH_DDI_BLUERIDGE DDI_BLUERIDGE 535 +skyminder MACH_SKYMINDER SKYMINDER 536 +lpd79520 MACH_LPD79520 LPD79520 537 +edb9302 MACH_EDB9302 EDB9302 538 +hw90340 MACH_HW90340 HW90340 539 +cip_box MACH_CIP_BOX CIP_BOX 540 +ivpn MACH_IVPN IVPN 541 +rsoc2 MACH_RSOC2 RSOC2 542 +husky MACH_HUSKY HUSKY 543 +boxer MACH_BOXER BOXER 544 +shepherd MACH_SHEPHERD SHEPHERD 545 +aml42800aa MACH_AML42800AA AML42800AA 546 +ml674001 MACH_MACH_TYPE_ML674001 MACH_TYPE_ML674001 547 +lpc2294 MACH_LPC2294 LPC2294 548 +switchgrass MACH_SWITCHGRASS SWITCHGRASS 549 +ens_cmu MACH_ENS_CMU ENS_CMU 550 +mm6_sdb MACH_MM6_SDB MM6_SDB 551 +saturn MACH_SATURN SATURN 552 +argonplusevb MACH_ARGONPLUSEVB ARGONPLUSEVB 553 +scma11evb MACH_SCMA11EVB SCMA11EVB 554 +smdk2800 MACH_SMDK2800 SMDK2800 555 +mtwilson MACH_MTWILSON MTWILSON 556 +ziti MACH_ZITI ZITI 557 +grandfather MACH_GRANDFATHER GRANDFATHER 558 +tengine MACH_TENGINE TENGINE 559 +s3c2460 MACH_S3C2460 S3C2460 560 +pdm MACH_PDM PDM 561 +h4700 MACH_H4700 H4700 562 +h6300 MACH_H6300 H6300 563 +rz1700 MACH_RZ1700 RZ1700 564 +a716 MACH_A716 A716 565 +estk2440a MACH_ESTK2440A ESTK2440A 566 +atwixp425 MACH_ATWIXP425 ATWIXP425 567 +csb336 MACH_CSB336 CSB336 568 +rirm2 MACH_RIRM2 RIRM2 569 +cx23518 MACH_CX23518 CX23518 570 +cx2351x MACH_CX2351X CX2351X 571 +computime MACH_COMPUTIME COMPUTIME 572 +izarus MACH_IZARUS IZARUS 573 +pxa_rts MACH_RTS RTS 574 +se5100 MACH_SE5100 SE5100 575 +s3c2510 MACH_S3C2510 S3C2510 576 +csb437tl MACH_CSB437TL CSB437TL 577 +slauson MACH_SLAUSON SLAUSON 578 +pearlriver MACH_PEARLRIVER PEARLRIVER 579 +tdc_p210 MACH_TDC_P210 TDC_P210 580 +sg580 MACH_SG580 SG580 581 +wrsbcarm7 MACH_WRSBCARM7 WRSBCARM7 582 +ipd MACH_IPD IPD 583 +pxa_dnp2110 MACH_PXA_DNP2110 PXA_DNP2110 584 +xaeniax MACH_XAENIAX XAENIAX 585 +somn4250 MACH_SOMN4250 SOMN4250 586 +pleb2 MACH_PLEB2 PLEB2 587 +cornwallis MACH_CORNWALLIS CORNWALLIS 588 +gurney_drv MACH_GURNEY_DRV GURNEY_DRV 589 +chaffee MACH_CHAFFEE CHAFFEE 590 +rms101 MACH_RMS101 RMS101 591 +rx3715 MACH_RX3715 RX3715 592 +swift MACH_SWIFT SWIFT 593 +roverp7 MACH_ROVERP7 ROVERP7 594 +pr818s MACH_PR818S PR818S 595 +trxpro MACH_TRXPRO TRXPRO 596 +nslu2 MACH_NSLU2 NSLU2 597 +e400 MACH_E400 E400 598 +trab MACH_TRAB TRAB 599 +cmc_pu2 MACH_CMC_PU2 CMC_PU2 600 +fulcrum MACH_FULCRUM FULCRUM 601 +netgate42x MACH_NETGATE42X NETGATE42X 602 +str710 MACH_STR710 STR710 603 +ixdpg425 MACH_IXDPG425 IXDPG425 604 +tomtomgo MACH_TOMTOMGO TOMTOMGO 605 +versatile_ab MACH_VERSATILE_AB VERSATILE_AB 606 +edb9307 MACH_EDB9307 EDB9307 607 +sg565 MACH_SG565 SG565 608 +lpd79524 MACH_LPD79524 LPD79524 609 +lpd79525 MACH_LPD79525 LPD79525 610 +rms100 MACH_RMS100 RMS100 611 +kb9200 MACH_KB9200 KB9200 612 +sx1 MACH_SX1 SX1 613 +hms39c7092 MACH_HMS39C7092 HMS39C7092 614 +armadillo MACH_ARMADILLO ARMADILLO 615 +ipcu MACH_IPCU IPCU 616 +loox720 MACH_LOOX720 LOOX720 617 +ixdp465 MACH_IXDP465 IXDP465 618 +ixdp2351 MACH_IXDP2351 IXDP2351 619 +adsvix MACH_ADSVIX ADSVIX 620 +dm270 MACH_DM270 DM270 621 +socltplus MACH_SOCLTPLUS SOCLTPLUS 622 +ecia MACH_ECIA ECIA 623 +cm4008 MACH_CM4008 CM4008 624 +p2001 MACH_P2001 P2001 625 +twister MACH_TWISTER TWISTER 626 +mudshark MACH_MUDSHARK MUDSHARK 627 +hb2 MACH_HB2 HB2 628 +iq80332 MACH_IQ80332 IQ80332 629 +sendt MACH_SENDT SENDT 630 +mx2jazz MACH_MX2JAZZ MX2JAZZ 631 +multiio MACH_MULTIIO MULTIIO 632 +hrdisplay MACH_HRDISPLAY HRDISPLAY 633 +scma11bb MACH_SCMA11BB SCMA11BB 634 +trizeps3 MACH_TRIZEPS3 TRIZEPS3 635 +zefeerdza MACH_ZEFEERDZA ZEFEERDZA 636 +zefeerdzb MACH_ZEFEERDZB ZEFEERDZB 637 +zefeerdzg MACH_ZEFEERDZG ZEFEERDZG 638 +zefeerdzn MACH_ZEFEERDZN ZEFEERDZN 639 +zefeerdzq MACH_ZEFEERDZQ ZEFEERDZQ 640 +gtwx5715 MACH_GTWX5715 GTWX5715 641 +astro_jack MACH_ASTRO_JACK ASTRO_JACK 643 +tip03 MACH_TIP03 TIP03 644 +a9200ec MACH_A9200EC A9200EC 645 +pnx0105 MACH_PNX0105 PNX0105 646 +adcpoecpu MACH_ADCPOECPU ADCPOECPU 647 +csb637 MACH_CSB637 CSB637 648 +ml69q6203 MACH_ML69Q6203 ML69Q6203 649 +mb9200 MACH_MB9200 MB9200 650 +kulun MACH_KULUN KULUN 651 +snapper MACH_SNAPPER SNAPPER 652 +optima MACH_OPTIMA OPTIMA 653 +dlhsbc MACH_DLHSBC DLHSBC 654 +x30 MACH_X30 X30 655 +n30 MACH_N30 N30 656 +manga_ks8695 MACH_MANGA_KS8695 MANGA_KS8695 657 +ajax MACH_AJAX AJAX 658 +nec_mp900 MACH_NEC_MP900 NEC_MP900 659 +vvtk1000 MACH_VVTK1000 VVTK1000 661 +kafa MACH_KAFA KAFA 662 +vvtk3000 MACH_VVTK3000 VVTK3000 663 +pimx1 MACH_PIMX1 PIMX1 664 +ollie MACH_OLLIE OLLIE 665 +skymax MACH_SKYMAX SKYMAX 666 +jazz MACH_JAZZ JAZZ 667 +tel_t3 MACH_TEL_T3 TEL_T3 668 +aisino_fcr255 MACH_AISINO_FCR255 AISINO_FCR255 669 +btweb MACH_BTWEB BTWEB 670 +dbg_lh79520 MACH_DBG_LH79520 DBG_LH79520 671 +cm41xx MACH_CM41XX CM41XX 672 +ts72xx MACH_TS72XX TS72XX 673 +nggpxa MACH_NGGPXA NGGPXA 674 +csb535 MACH_CSB535 CSB535 675 +csb536 MACH_CSB536 CSB536 676 +pxa_trakpod MACH_PXA_TRAKPOD PXA_TRAKPOD 677 +praxis MACH_PRAXIS PRAXIS 678 +lh75411 MACH_LH75411 LH75411 679 +otom MACH_OTOM OTOM 680 +nexcoder_2440 MACH_NEXCODER_2440 NEXCODER_2440 681 +loox410 MACH_LOOX410 LOOX410 682 +westlake MACH_WESTLAKE WESTLAKE 683 +nsb MACH_NSB NSB 684 +esl_sarva_stn MACH_ESL_SARVA_STN ESL_SARVA_STN 685 +esl_sarva_tft MACH_ESL_SARVA_TFT ESL_SARVA_TFT 686 +esl_sarva_iad MACH_ESL_SARVA_IAD ESL_SARVA_IAD 687 +esl_sarva_acc MACH_ESL_SARVA_ACC ESL_SARVA_ACC 688 +typhoon MACH_TYPHOON TYPHOON 689 +cnav MACH_CNAV CNAV 690 +a730 MACH_A730 A730 691 +netstar MACH_NETSTAR NETSTAR 692 +supercon MACH_PHASEFALE_SUPERCON PHASEFALE_SUPERCON 693 +shiva1100 MACH_SHIVA1100 SHIVA1100 694 +etexsc MACH_ETEXSC ETEXSC 695 +ixdpg465 MACH_IXDPG465 IXDPG465 696 +a9m2410 MACH_A9M2410 A9M2410 697 +a9m2440 MACH_A9M2440 A9M2440 698 +a9m9750 MACH_A9M9750 A9M9750 699 +a9m9360 MACH_A9M9360 A9M9360 700 +unc90 MACH_UNC90 UNC90 701 +eco920 MACH_ECO920 ECO920 702 +satview MACH_SATVIEW SATVIEW 703 +roadrunner MACH_ROADRUNNER ROADRUNNER 704 +at91rm9200ek MACH_AT91RM9200EK AT91RM9200EK 705 +gp32 MACH_GP32 GP32 706 +gem MACH_GEM GEM 707 +i858 MACH_I858 I858 708 +hx2750 MACH_HX2750 HX2750 709 +zeusevb MACH_ZEUSEVB ZEUSEVB 710 +p700 MACH_P700 P700 711 +cpe MACH_CPE CPE 712 +spitz MACH_SPITZ SPITZ 713 +nimbra340 MACH_NIMBRA340 NIMBRA340 714 +lpc22xx MACH_LPC22XX LPC22XX 715 +omap_comet3 MACH_COMET3 COMET3 716 +omap_comet4 MACH_COMET4 COMET4 717 +csb625 MACH_CSB625 CSB625 718 diff --git a/arch/arm/vfp/Makefile b/arch/arm/vfp/Makefile new file mode 100644 index 0000000..afabac3 --- /dev/null +++ b/arch/arm/vfp/Makefile @@ -0,0 +1,12 @@ +# +# linux/arch/arm/vfp/Makefile +# +# Copyright (C) 2001 ARM Limited +# + +# EXTRA_CFLAGS := -DDEBUG +# EXTRA_AFLAGS := -DDEBUG + +obj-y += vfp.o + +vfp-$(CONFIG_VFP) += entry.o vfpmodule.o vfphw.o vfpsingle.o vfpdouble.o diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S new file mode 100644 index 0000000..e73c8de --- /dev/null +++ b/arch/arm/vfp/entry.S @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/vfp/entry.S + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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. + * + * Basic entry code, called from the kernel's undefined instruction trap. + * r0 = faulted instruction + * r5 = faulted PC+4 + * r9 = successful return + * r10 = thread_info structure + * lr = failure return + */ +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/constants.h> +#include <asm/vfpmacros.h> + + .globl do_vfp +do_vfp: + ldr r4, .LCvfp + add r10, r10, #TI_VFPSTATE @ r10 = workspace + ldr pc, [r4] @ call VFP entry point + +.LCvfp: + .word vfp_vector + +@ This code is called if the VFP does not exist. It needs to flag the +@ failure to the VFP initialisation code. + + __INIT + .globl vfp_testing_entry +vfp_testing_entry: + ldr r0, VFP_arch_address + str r5, [r0] @ known non-zero value + mov pc, r9 @ we have handled the fault + +VFP_arch_address: + .word VFP_arch + + __FINIT diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h new file mode 100644 index 0000000..55a02bc --- /dev/null +++ b/arch/arm/vfp/vfp.h @@ -0,0 +1,344 @@ +/* + * linux/arch/arm/vfp/vfp.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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. + */ + +static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift) +{ + if (shift) { + if (shift < 32) + val = val >> shift | ((val << (32 - shift)) != 0); + else + val = val != 0; + } + return val; +} + +static inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift) +{ + if (shift) { + if (shift < 64) + val = val >> shift | ((val << (64 - shift)) != 0); + else + val = val != 0; + } + return val; +} + +static inline u32 vfp_hi64to32jamming(u64 val) +{ + u32 v; + + asm( + "cmp %Q1, #1 @ vfp_hi64to32jamming\n\t" + "movcc %0, %R1\n\t" + "orrcs %0, %R1, #1" + : "=r" (v) : "r" (val) : "cc"); + + return v; +} + +static inline void add128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml) +{ + asm( "adds %Q0, %Q2, %Q4\n\t" + "adcs %R0, %R2, %R4\n\t" + "adcs %Q1, %Q3, %Q5\n\t" + "adc %R1, %R3, %R5" + : "=r" (nl), "=r" (nh) + : "0" (nl), "1" (nh), "r" (ml), "r" (mh) + : "cc"); + *resh = nh; + *resl = nl; +} + +static inline void sub128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml) +{ + asm( "subs %Q0, %Q2, %Q4\n\t" + "sbcs %R0, %R2, %R4\n\t" + "sbcs %Q1, %Q3, %Q5\n\t" + "sbc %R1, %R3, %R5\n\t" + : "=r" (nl), "=r" (nh) + : "0" (nl), "1" (nh), "r" (ml), "r" (mh) + : "cc"); + *resh = nh; + *resl = nl; +} + +static inline void mul64to128(u64 *resh, u64 *resl, u64 n, u64 m) +{ + u32 nh, nl, mh, ml; + u64 rh, rma, rmb, rl; + + nl = n; + ml = m; + rl = (u64)nl * ml; + + nh = n >> 32; + rma = (u64)nh * ml; + + mh = m >> 32; + rmb = (u64)nl * mh; + rma += rmb; + + rh = (u64)nh * mh; + rh += ((u64)(rma < rmb) << 32) + (rma >> 32); + + rma <<= 32; + rl += rma; + rh += (rl < rma); + + *resl = rl; + *resh = rh; +} + +static inline void shift64left(u64 *resh, u64 *resl, u64 n) +{ + *resh = n >> 63; + *resl = n << 1; +} + +static inline u64 vfp_hi64multiply64(u64 n, u64 m) +{ + u64 rh, rl; + mul64to128(&rh, &rl, n, m); + return rh | (rl != 0); +} + +static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) +{ + u64 mh, ml, remh, reml, termh, terml, z; + + if (nh >= m) + return ~0ULL; + mh = m >> 32; + z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32; + mul64to128(&termh, &terml, m, z); + sub128(&remh, &reml, nh, nl, termh, terml); + ml = m << 32; + while ((s64)remh < 0) { + z -= 0x100000000ULL; + add128(&remh, &reml, remh, reml, mh, ml); + } + remh = (remh << 32) | (reml >> 32); + z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh; + return z; +} + +/* + * Operations on unpacked elements + */ +#define vfp_sign_negate(sign) (sign ^ 0x8000) + +/* + * Single-precision + */ +struct vfp_single { + s16 exponent; + u16 sign; + u32 significand; +}; + +extern s32 vfp_get_float(unsigned int reg); +extern void vfp_put_float(unsigned int reg, s32 val); + +/* + * VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa + * VFP_SINGLE_EXPONENT_BITS - number of bits in the exponent + * VFP_SINGLE_LOW_BITS - number of low bits in the unpacked significand + * which are not propagated to the float upon packing. + */ +#define VFP_SINGLE_MANTISSA_BITS (23) +#define VFP_SINGLE_EXPONENT_BITS (8) +#define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2) +#define VFP_SINGLE_LOW_BITS_MASK ((1 << VFP_SINGLE_LOW_BITS) - 1) + +/* + * The bit in an unpacked float which indicates that it is a quiet NaN + */ +#define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS)) + +/* + * Operations on packed single-precision numbers + */ +#define vfp_single_packed_sign(v) ((v) & 0x80000000) +#define vfp_single_packed_negate(v) ((v) ^ 0x80000000) +#define vfp_single_packed_abs(v) ((v) & ~0x80000000) +#define vfp_single_packed_exponent(v) (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1)) +#define vfp_single_packed_mantissa(v) ((v) & ((1 << VFP_SINGLE_MANTISSA_BITS) - 1)) + +/* + * Unpack a single-precision float. Note that this returns the magnitude + * of the single-precision float mantissa with the 1. if necessary, + * aligned to bit 30. + */ +static inline void vfp_single_unpack(struct vfp_single *s, s32 val) +{ + u32 significand; + + s->sign = vfp_single_packed_sign(val) >> 16, + s->exponent = vfp_single_packed_exponent(val); + + significand = (u32) val; + significand = (significand << (32 - VFP_SINGLE_MANTISSA_BITS)) >> 2; + if (s->exponent && s->exponent != 255) + significand |= 0x40000000; + s->significand = significand; +} + +/* + * Re-pack a single-precision float. This assumes that the float is + * already normalised such that the MSB is bit 30, _not_ bit 31. + */ +static inline s32 vfp_single_pack(struct vfp_single *s) +{ + u32 val; + val = (s->sign << 16) + + (s->exponent << VFP_SINGLE_MANTISSA_BITS) + + (s->significand >> VFP_SINGLE_LOW_BITS); + return (s32)val; +} + +#define VFP_NUMBER (1<<0) +#define VFP_ZERO (1<<1) +#define VFP_DENORMAL (1<<2) +#define VFP_INFINITY (1<<3) +#define VFP_NAN (1<<4) +#define VFP_NAN_SIGNAL (1<<5) + +#define VFP_QNAN (VFP_NAN) +#define VFP_SNAN (VFP_NAN|VFP_NAN_SIGNAL) + +static inline int vfp_single_type(struct vfp_single *s) +{ + int type = VFP_NUMBER; + if (s->exponent == 255) { + if (s->significand == 0) + type = VFP_INFINITY; + else if (s->significand & VFP_SINGLE_SIGNIFICAND_QNAN) + type = VFP_QNAN; + else + type = VFP_SNAN; + } else if (s->exponent == 0) { + if (s->significand == 0) + type |= VFP_ZERO; + else + type |= VFP_DENORMAL; + } + return type; +} + +#ifndef DEBUG +#define vfp_single_normaliseround(sd,vsd,fpscr,except,func) __vfp_single_normaliseround(sd,vsd,fpscr,except) +u32 __vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions); +#else +u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func); +#endif + +/* + * Double-precision + */ +struct vfp_double { + s16 exponent; + u16 sign; + u64 significand; +}; + +/* + * VFP_REG_ZERO is a special register number for vfp_get_double + * which returns (double)0.0. This is useful for the compare with + * zero instructions. + */ +#define VFP_REG_ZERO 16 +extern u64 vfp_get_double(unsigned int reg); +extern void vfp_put_double(unsigned int reg, u64 val); + +#define VFP_DOUBLE_MANTISSA_BITS (52) +#define VFP_DOUBLE_EXPONENT_BITS (11) +#define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2) +#define VFP_DOUBLE_LOW_BITS_MASK ((1 << VFP_DOUBLE_LOW_BITS) - 1) + +/* + * The bit in an unpacked double which indicates that it is a quiet NaN + */ +#define VFP_DOUBLE_SIGNIFICAND_QNAN (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1 + VFP_DOUBLE_LOW_BITS)) + +/* + * Operations on packed single-precision numbers + */ +#define vfp_double_packed_sign(v) ((v) & (1ULL << 63)) +#define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63)) +#define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63)) +#define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1)) +#define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1)) + +/* + * Unpack a double-precision float. Note that this returns the magnitude + * of the double-precision float mantissa with the 1. if necessary, + * aligned to bit 62. + */ +static inline void vfp_double_unpack(struct vfp_double *s, s64 val) +{ + u64 significand; + + s->sign = vfp_double_packed_sign(val) >> 48; + s->exponent = vfp_double_packed_exponent(val); + + significand = (u64) val; + significand = (significand << (64 - VFP_DOUBLE_MANTISSA_BITS)) >> 2; + if (s->exponent && s->exponent != 2047) + significand |= (1ULL << 62); + s->significand = significand; +} + +/* + * Re-pack a double-precision float. This assumes that the float is + * already normalised such that the MSB is bit 30, _not_ bit 31. + */ +static inline s64 vfp_double_pack(struct vfp_double *s) +{ + u64 val; + val = ((u64)s->sign << 48) + + ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) + + (s->significand >> VFP_DOUBLE_LOW_BITS); + return (s64)val; +} + +static inline int vfp_double_type(struct vfp_double *s) +{ + int type = VFP_NUMBER; + if (s->exponent == 2047) { + if (s->significand == 0) + type = VFP_INFINITY; + else if (s->significand & VFP_DOUBLE_SIGNIFICAND_QNAN) + type = VFP_QNAN; + else + type = VFP_SNAN; + } else if (s->exponent == 0) { + if (s->significand == 0) + type |= VFP_ZERO; + else + type |= VFP_DENORMAL; + } + return type; +} + +u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func); + +/* + * System registers + */ +extern u32 vfp_get_sys(unsigned int reg); +extern void vfp_put_sys(unsigned int reg, u32 val); + +u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); + +/* + * A special flag to tell the normalisation code not to normalise. + */ +#define VFP_NAN_FLAG 0x100 diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c new file mode 100644 index 0000000..fa3053e --- /dev/null +++ b/arch/arm/vfp/vfpdouble.c @@ -0,0 +1,1186 @@ +/* + * linux/arch/arm/vfp/vfpdouble.c + * + * This code is derived in part from John R. Housers softfloat library, which + * carries the following notice: + * + * =========================================================================== + * This C source file is part of the SoftFloat IEC/IEEE Floating-point + * Arithmetic Package, Release 2. + * + * Written by John R. Hauser. This work was made possible in part by the + * International Computer Science Institute, located at Suite 600, 1947 Center + * Street, Berkeley, California 94704. Funding was partially provided by the + * National Science Foundation under grant MIP-9311980. The original version + * of this code was written as part of a project to build a fixed-point vector + * processor in collaboration with the University of California at Berkeley, + * overseen by Profs. Nelson Morgan and John Wawrzynek. More information + * is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ + * arithmetic/softfloat.html'. + * + * THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort + * has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT + * TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO + * PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY + * AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + * + * Derivative works are acceptable, even for commercial purposes, so long as + * (1) they include prominent notice that the work is derivative, and (2) they + * include prominent notice akin to these three paragraphs for those parts of + * this code that are retained. + * =========================================================================== + */ +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <asm/ptrace.h> +#include <asm/vfp.h> + +#include "vfpinstr.h" +#include "vfp.h" + +static struct vfp_double vfp_double_default_qnan = { + .exponent = 2047, + .sign = 0, + .significand = VFP_DOUBLE_SIGNIFICAND_QNAN, +}; + +static void vfp_double_dump(const char *str, struct vfp_double *d) +{ + pr_debug("VFP: %s: sign=%d exponent=%d significand=%016llx\n", + str, d->sign != 0, d->exponent, d->significand); +} + +static void vfp_double_normalise_denormal(struct vfp_double *vd) +{ + int bits = 31 - fls(vd->significand >> 32); + if (bits == 31) + bits = 62 - fls(vd->significand); + + vfp_double_dump("normalise_denormal: in", vd); + + if (bits) { + vd->exponent -= bits - 1; + vd->significand <<= bits; + } + + vfp_double_dump("normalise_denormal: out", vd); +} + +u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func) +{ + u64 significand, incr; + int exponent, shift, underflow; + u32 rmode; + + vfp_double_dump("pack: in", vd); + + /* + * Infinities and NaNs are a special case. + */ + if (vd->exponent == 2047 && (vd->significand == 0 || exceptions)) + goto pack; + + /* + * Special-case zero. + */ + if (vd->significand == 0) { + vd->exponent = 0; + goto pack; + } + + exponent = vd->exponent; + significand = vd->significand; + + shift = 32 - fls(significand >> 32); + if (shift == 32) + shift = 64 - fls(significand); + if (shift) { + exponent -= shift; + significand <<= shift; + } + +#ifdef DEBUG + vd->exponent = exponent; + vd->significand = significand; + vfp_double_dump("pack: normalised", vd); +#endif + + /* + * Tiny number? + */ + underflow = exponent < 0; + if (underflow) { + significand = vfp_shiftright64jamming(significand, -exponent); + exponent = 0; +#ifdef DEBUG + vd->exponent = exponent; + vd->significand = significand; + vfp_double_dump("pack: tiny number", vd); +#endif + if (!(significand & ((1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1))) + underflow = 0; + } + + /* + * Select rounding increment. + */ + incr = 0; + rmode = fpscr & FPSCR_RMODE_MASK; + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 1ULL << VFP_DOUBLE_LOW_BITS; + if ((significand & (1ULL << (VFP_DOUBLE_LOW_BITS + 1))) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0)) + incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1; + + pr_debug("VFP: rounding increment = 0x%08llx\n", incr); + + /* + * Is our rounding going to overflow? + */ + if ((significand + incr) < significand) { + exponent += 1; + significand = (significand >> 1) | (significand & 1); + incr >>= 1; +#ifdef DEBUG + vd->exponent = exponent; + vd->significand = significand; + vfp_double_dump("pack: overflow", vd); +#endif + } + + /* + * If any of the low bits (which will be shifted out of the + * number) are non-zero, the result is inexact. + */ + if (significand & ((1 << (VFP_DOUBLE_LOW_BITS + 1)) - 1)) + exceptions |= FPSCR_IXC; + + /* + * Do our rounding. + */ + significand += incr; + + /* + * Infinity? + */ + if (exponent >= 2046) { + exceptions |= FPSCR_OFC | FPSCR_IXC; + if (incr == 0) { + vd->exponent = 2045; + vd->significand = 0x7fffffffffffffffULL; + } else { + vd->exponent = 2047; /* infinity */ + vd->significand = 0; + } + } else { + if (significand >> (VFP_DOUBLE_LOW_BITS + 1) == 0) + exponent = 0; + if (exponent || significand > 0x8000000000000000ULL) + underflow = 0; + if (underflow) + exceptions |= FPSCR_UFC; + vd->exponent = exponent; + vd->significand = significand >> 1; + } + + pack: + vfp_double_dump("pack: final", vd); + { + s64 d = vfp_double_pack(vd); + pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func, + dd, d, exceptions); + vfp_put_double(dd, d); + } + return exceptions & ~VFP_NAN_FLAG; +} + +/* + * Propagate the NaN, setting exceptions if it is signalling. + * 'n' is always a NaN. 'm' may be a number, NaN or infinity. + */ +static u32 +vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn, + struct vfp_double *vdm, u32 fpscr) +{ + struct vfp_double *nan; + int tn, tm = 0; + + tn = vfp_double_type(vdn); + + if (vdm) + tm = vfp_double_type(vdm); + + if (fpscr & FPSCR_DEFAULT_NAN) + /* + * Default NaN mode - always returns a quiet NaN + */ + nan = &vfp_double_default_qnan; + else { + /* + * Contemporary mode - select the first signalling + * NAN, or if neither are signalling, the first + * quiet NAN. + */ + if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN)) + nan = vdn; + else + nan = vdm; + /* + * Make the NaN quiet. + */ + nan->significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; + } + + *vdd = *nan; + + /* + * If one was a signalling NAN, raise invalid operation. + */ + return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG; +} + +/* + * Extended operations + */ +static u32 vfp_double_fabs(int dd, int unused, int dm, u32 fpscr) +{ + vfp_put_double(dd, vfp_double_packed_abs(vfp_get_double(dm))); + return 0; +} + +static u32 vfp_double_fcpy(int dd, int unused, int dm, u32 fpscr) +{ + vfp_put_double(dd, vfp_get_double(dm)); + return 0; +} + +static u32 vfp_double_fneg(int dd, int unused, int dm, u32 fpscr) +{ + vfp_put_double(dd, vfp_double_packed_negate(vfp_get_double(dm))); + return 0; +} + +static u32 vfp_double_fsqrt(int dd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm, vdd; + int ret, tm; + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + tm = vfp_double_type(&vdm); + if (tm & (VFP_NAN|VFP_INFINITY)) { + struct vfp_double *vdp = &vdd; + + if (tm & VFP_NAN) + ret = vfp_propagate_nan(vdp, &vdm, NULL, fpscr); + else if (vdm.sign == 0) { + sqrt_copy: + vdp = &vdm; + ret = 0; + } else { + sqrt_invalid: + vdp = &vfp_double_default_qnan; + ret = FPSCR_IOC; + } + vfp_put_double(dd, vfp_double_pack(vdp)); + return ret; + } + + /* + * sqrt(+/- 0) == +/- 0 + */ + if (tm & VFP_ZERO) + goto sqrt_copy; + + /* + * Normalise a denormalised number + */ + if (tm & VFP_DENORMAL) + vfp_double_normalise_denormal(&vdm); + + /* + * sqrt(<0) = invalid + */ + if (vdm.sign) + goto sqrt_invalid; + + vfp_double_dump("sqrt", &vdm); + + /* + * Estimate the square root. + */ + vdd.sign = 0; + vdd.exponent = ((vdm.exponent - 1023) >> 1) + 1023; + vdd.significand = (u64)vfp_estimate_sqrt_significand(vdm.exponent, vdm.significand >> 32) << 31; + + vfp_double_dump("sqrt estimate1", &vdd); + + vdm.significand >>= 1 + (vdm.exponent & 1); + vdd.significand += 2 + vfp_estimate_div128to64(vdm.significand, 0, vdd.significand); + + vfp_double_dump("sqrt estimate2", &vdd); + + /* + * And now adjust. + */ + if ((vdd.significand & VFP_DOUBLE_LOW_BITS_MASK) <= 5) { + if (vdd.significand < 2) { + vdd.significand = ~0ULL; + } else { + u64 termh, terml, remh, reml; + vdm.significand <<= 2; + mul64to128(&termh, &terml, vdd.significand, vdd.significand); + sub128(&remh, &reml, vdm.significand, 0, termh, terml); + while ((s64)remh < 0) { + vdd.significand -= 1; + shift64left(&termh, &terml, vdd.significand); + terml |= 1; + add128(&remh, &reml, remh, reml, termh, terml); + } + vdd.significand |= (remh | reml) != 0; + } + } + vdd.significand = vfp_shiftright64jamming(vdd.significand, 1); + + return vfp_double_normaliseround(dd, &vdd, fpscr, 0, "fsqrt"); +} + +/* + * Equal := ZC + * Less than := N + * Greater than := C + * Unordered := CV + */ +static u32 vfp_compare(int dd, int signal_on_qnan, int dm, u32 fpscr) +{ + s64 d, m; + u32 ret = 0; + + m = vfp_get_double(dm); + if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) { + ret |= FPSCR_C | FPSCR_V; + if (signal_on_qnan || !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) + /* + * Signalling NaN, or signalling on quiet NaN + */ + ret |= FPSCR_IOC; + } + + d = vfp_get_double(dd); + if (vfp_double_packed_exponent(d) == 2047 && vfp_double_packed_mantissa(d)) { + ret |= FPSCR_C | FPSCR_V; + if (signal_on_qnan || !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) + /* + * Signalling NaN, or signalling on quiet NaN + */ + ret |= FPSCR_IOC; + } + + if (ret == 0) { + if (d == m || vfp_double_packed_abs(d | m) == 0) { + /* + * equal + */ + ret |= FPSCR_Z | FPSCR_C; + } else if (vfp_double_packed_sign(d ^ m)) { + /* + * different signs + */ + if (vfp_double_packed_sign(d)) + /* + * d is negative, so d < m + */ + ret |= FPSCR_N; + else + /* + * d is positive, so d > m + */ + ret |= FPSCR_C; + } else if ((vfp_double_packed_sign(d) != 0) ^ (d < m)) { + /* + * d < m + */ + ret |= FPSCR_N; + } else if ((vfp_double_packed_sign(d) != 0) ^ (d > m)) { + /* + * d > m + */ + ret |= FPSCR_C; + } + } + + return ret; +} + +static u32 vfp_double_fcmp(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_compare(dd, 0, dm, fpscr); +} + +static u32 vfp_double_fcmpe(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_compare(dd, 1, dm, fpscr); +} + +static u32 vfp_double_fcmpz(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_compare(dd, 0, VFP_REG_ZERO, fpscr); +} + +static u32 vfp_double_fcmpez(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_compare(dd, 1, VFP_REG_ZERO, fpscr); +} + +static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + struct vfp_single vsd; + int tm; + u32 exceptions = 0; + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + + tm = vfp_double_type(&vdm); + + /* + * If we have a signalling NaN, signal invalid operation. + */ + if (tm == VFP_SNAN) + exceptions = FPSCR_IOC; + + if (tm & VFP_DENORMAL) + vfp_double_normalise_denormal(&vdm); + + vsd.sign = vdm.sign; + vsd.significand = vfp_hi64to32jamming(vdm.significand); + + /* + * If we have an infinity or a NaN, the exponent must be 255 + */ + if (tm & (VFP_INFINITY|VFP_NAN)) { + vsd.exponent = 255; + if (tm & VFP_NAN) + vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN; + goto pack_nan; + } else if (tm & VFP_ZERO) + vsd.exponent = 0; + else + vsd.exponent = vdm.exponent - (1023 - 127); + + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fcvts"); + + pack_nan: + vfp_put_float(sd, vfp_single_pack(&vsd)); + return exceptions; +} + +static u32 vfp_double_fuito(int dd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + u32 m = vfp_get_float(dm); + + vdm.sign = 0; + vdm.exponent = 1023 + 63 - 1; + vdm.significand = (u64)m; + + return vfp_double_normaliseround(dd, &vdm, fpscr, 0, "fuito"); +} + +static u32 vfp_double_fsito(int dd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + u32 m = vfp_get_float(dm); + + vdm.sign = (m & 0x80000000) >> 16; + vdm.exponent = 1023 + 63 - 1; + vdm.significand = vdm.sign ? -m : m; + + return vfp_double_normaliseround(dd, &vdm, fpscr, 0, "fsito"); +} + +static u32 vfp_double_ftoui(int sd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + u32 d, exceptions = 0; + int rmode = fpscr & FPSCR_RMODE_MASK; + int tm; + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + + /* + * Do we have a denormalised number? + */ + tm = vfp_double_type(&vdm); + if (tm & VFP_DENORMAL) + exceptions |= FPSCR_IDC; + + if (tm & VFP_NAN) + vdm.sign = 0; + + if (vdm.exponent >= 1023 + 32) { + d = vdm.sign ? 0 : 0xffffffff; + exceptions = FPSCR_IOC; + } else if (vdm.exponent >= 1023 - 1) { + int shift = 1023 + 63 - vdm.exponent; + u64 rem, incr = 0; + + /* + * 2^0 <= m < 2^32-2^8 + */ + d = (vdm.significand << 1) >> shift; + rem = vdm.significand << (65 - shift); + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 0x8000000000000000ULL; + if ((d & 1) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) { + incr = ~0ULL; + } + + if ((rem + incr) < rem) { + if (d < 0xffffffff) + d += 1; + else + exceptions |= FPSCR_IOC; + } + + if (d && vdm.sign) { + d = 0; + exceptions |= FPSCR_IOC; + } else if (rem) + exceptions |= FPSCR_IXC; + } else { + d = 0; + if (vdm.exponent | vdm.significand) { + exceptions |= FPSCR_IXC; + if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) + d = 1; + else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) { + d = 0; + exceptions |= FPSCR_IOC; + } + } + } + + pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + + vfp_put_float(sd, d); + + return exceptions; +} + +static u32 vfp_double_ftouiz(int sd, int unused, int dm, u32 fpscr) +{ + return vfp_double_ftoui(sd, unused, dm, FPSCR_ROUND_TOZERO); +} + +static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr) +{ + struct vfp_double vdm; + u32 d, exceptions = 0; + int rmode = fpscr & FPSCR_RMODE_MASK; + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + vfp_double_dump("VDM", &vdm); + + /* + * Do we have denormalised number? + */ + if (vfp_double_type(&vdm) & VFP_DENORMAL) + exceptions |= FPSCR_IDC; + + if (vdm.exponent >= 1023 + 32) { + d = 0x7fffffff; + if (vdm.sign) + d = ~d; + exceptions |= FPSCR_IOC; + } else if (vdm.exponent >= 1023 - 1) { + int shift = 1023 + 63 - vdm.exponent; /* 58 */ + u64 rem, incr = 0; + + d = (vdm.significand << 1) >> shift; + rem = vdm.significand << (65 - shift); + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 0x8000000000000000ULL; + if ((d & 1) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) { + incr = ~0ULL; + } + + if ((rem + incr) < rem && d < 0xffffffff) + d += 1; + if (d > 0x7fffffff + (vdm.sign != 0)) { + d = 0x7fffffff + (vdm.sign != 0); + exceptions |= FPSCR_IOC; + } else if (rem) + exceptions |= FPSCR_IXC; + + if (vdm.sign) + d = -d; + } else { + d = 0; + if (vdm.exponent | vdm.significand) { + exceptions |= FPSCR_IXC; + if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0) + d = 1; + else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) + d = -1; + } + } + + pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + + vfp_put_float(sd, (s32)d); + + return exceptions; +} + +static u32 vfp_double_ftosiz(int dd, int unused, int dm, u32 fpscr) +{ + return vfp_double_ftosi(dd, unused, dm, FPSCR_ROUND_TOZERO); +} + + +static u32 (* const fop_extfns[32])(int dd, int unused, int dm, u32 fpscr) = { + [FEXT_TO_IDX(FEXT_FCPY)] = vfp_double_fcpy, + [FEXT_TO_IDX(FEXT_FABS)] = vfp_double_fabs, + [FEXT_TO_IDX(FEXT_FNEG)] = vfp_double_fneg, + [FEXT_TO_IDX(FEXT_FSQRT)] = vfp_double_fsqrt, + [FEXT_TO_IDX(FEXT_FCMP)] = vfp_double_fcmp, + [FEXT_TO_IDX(FEXT_FCMPE)] = vfp_double_fcmpe, + [FEXT_TO_IDX(FEXT_FCMPZ)] = vfp_double_fcmpz, + [FEXT_TO_IDX(FEXT_FCMPEZ)] = vfp_double_fcmpez, + [FEXT_TO_IDX(FEXT_FCVT)] = vfp_double_fcvts, + [FEXT_TO_IDX(FEXT_FUITO)] = vfp_double_fuito, + [FEXT_TO_IDX(FEXT_FSITO)] = vfp_double_fsito, + [FEXT_TO_IDX(FEXT_FTOUI)] = vfp_double_ftoui, + [FEXT_TO_IDX(FEXT_FTOUIZ)] = vfp_double_ftouiz, + [FEXT_TO_IDX(FEXT_FTOSI)] = vfp_double_ftosi, + [FEXT_TO_IDX(FEXT_FTOSIZ)] = vfp_double_ftosiz, +}; + + + + +static u32 +vfp_double_fadd_nonnumber(struct vfp_double *vdd, struct vfp_double *vdn, + struct vfp_double *vdm, u32 fpscr) +{ + struct vfp_double *vdp; + u32 exceptions = 0; + int tn, tm; + + tn = vfp_double_type(vdn); + tm = vfp_double_type(vdm); + + if (tn & tm & VFP_INFINITY) { + /* + * Two infinities. Are they different signs? + */ + if (vdn->sign ^ vdm->sign) { + /* + * different signs -> invalid + */ + exceptions = FPSCR_IOC; + vdp = &vfp_double_default_qnan; + } else { + /* + * same signs -> valid + */ + vdp = vdn; + } + } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) { + /* + * One infinity and one number -> infinity + */ + vdp = vdn; + } else { + /* + * 'n' is a NaN of some type + */ + return vfp_propagate_nan(vdd, vdn, vdm, fpscr); + } + *vdd = *vdp; + return exceptions; +} + +static u32 +vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn, + struct vfp_double *vdm, u32 fpscr) +{ + u32 exp_diff; + u64 m_sig; + + if (vdn->significand & (1ULL << 63) || + vdm->significand & (1ULL << 63)) { + pr_info("VFP: bad FP values in %s\n", __func__); + vfp_double_dump("VDN", vdn); + vfp_double_dump("VDM", vdm); + } + + /* + * Ensure that 'n' is the largest magnitude number. Note that + * if 'n' and 'm' have equal exponents, we do not swap them. + * This ensures that NaN propagation works correctly. + */ + if (vdn->exponent < vdm->exponent) { + struct vfp_double *t = vdn; + vdn = vdm; + vdm = t; + } + + /* + * Is 'n' an infinity or a NaN? Note that 'm' may be a number, + * infinity or a NaN here. + */ + if (vdn->exponent == 2047) + return vfp_double_fadd_nonnumber(vdd, vdn, vdm, fpscr); + + /* + * We have two proper numbers, where 'vdn' is the larger magnitude. + * + * Copy 'n' to 'd' before doing the arithmetic. + */ + *vdd = *vdn; + + /* + * Align 'm' with the result. + */ + exp_diff = vdn->exponent - vdm->exponent; + m_sig = vfp_shiftright64jamming(vdm->significand, exp_diff); + + /* + * If the signs are different, we are really subtracting. + */ + if (vdn->sign ^ vdm->sign) { + m_sig = vdn->significand - m_sig; + if ((s64)m_sig < 0) { + vdd->sign = vfp_sign_negate(vdd->sign); + m_sig = -m_sig; + } + } else { + m_sig += vdn->significand; + } + vdd->significand = m_sig; + + return 0; +} + +static u32 +vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, + struct vfp_double *vdm, u32 fpscr) +{ + vfp_double_dump("VDN", vdn); + vfp_double_dump("VDM", vdm); + + /* + * Ensure that 'n' is the largest magnitude number. Note that + * if 'n' and 'm' have equal exponents, we do not swap them. + * This ensures that NaN propagation works correctly. + */ + if (vdn->exponent < vdm->exponent) { + struct vfp_double *t = vdn; + vdn = vdm; + vdm = t; + pr_debug("VFP: swapping M <-> N\n"); + } + + vdd->sign = vdn->sign ^ vdm->sign; + + /* + * If 'n' is an infinity or NaN, handle it. 'm' may be anything. + */ + if (vdn->exponent == 2047) { + if (vdn->significand || (vdm->exponent == 2047 && vdm->significand)) + return vfp_propagate_nan(vdd, vdn, vdm, fpscr); + if ((vdm->exponent | vdm->significand) == 0) { + *vdd = vfp_double_default_qnan; + return FPSCR_IOC; + } + vdd->exponent = vdn->exponent; + vdd->significand = 0; + return 0; + } + + /* + * If 'm' is zero, the result is always zero. In this case, + * 'n' may be zero or a number, but it doesn't matter which. + */ + if ((vdm->exponent | vdm->significand) == 0) { + vdd->exponent = 0; + vdd->significand = 0; + return 0; + } + + /* + * We add 2 to the destination exponent for the same reason + * as the addition case - though this time we have +1 from + * each input operand. + */ + vdd->exponent = vdn->exponent + vdm->exponent - 1023 + 2; + vdd->significand = vfp_hi64multiply64(vdn->significand, vdm->significand); + + vfp_double_dump("VDD", vdd); + return 0; +} + +#define NEG_MULTIPLY (1 << 0) +#define NEG_SUBTRACT (1 << 1) + +static u32 +vfp_double_multiply_accumulate(int dd, int dn, int dm, u32 fpscr, u32 negate, char *func) +{ + struct vfp_double vdd, vdp, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + exceptions = vfp_double_multiply(&vdp, &vdn, &vdm, fpscr); + if (negate & NEG_MULTIPLY) + vdp.sign = vfp_sign_negate(vdp.sign); + + vfp_double_unpack(&vdn, vfp_get_double(dd)); + if (negate & NEG_SUBTRACT) + vdn.sign = vfp_sign_negate(vdn.sign); + + exceptions |= vfp_double_add(&vdd, &vdn, &vdp, fpscr); + + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, func); +} + +/* + * Standard operations + */ + +/* + * sd = sd + (sn * sm) + */ +static u32 vfp_double_fmac(int dd, int dn, int dm, u32 fpscr) +{ + return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, 0, "fmac"); +} + +/* + * sd = sd - (sn * sm) + */ +static u32 vfp_double_fnmac(int dd, int dn, int dm, u32 fpscr) +{ + return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_MULTIPLY, "fnmac"); +} + +/* + * sd = -sd + (sn * sm) + */ +static u32 vfp_double_fmsc(int dd, int dn, int dm, u32 fpscr) +{ + return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_SUBTRACT, "fmsc"); +} + +/* + * sd = -sd - (sn * sm) + */ +static u32 vfp_double_fnmsc(int dd, int dn, int dm, u32 fpscr) +{ + return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); +} + +/* + * sd = sn * sm + */ +static u32 vfp_double_fmul(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr); + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fmul"); +} + +/* + * sd = -(sn * sm) + */ +static u32 vfp_double_fnmul(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr); + vdd.sign = vfp_sign_negate(vdd.sign); + + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fnmul"); +} + +/* + * sd = sn + sm + */ +static u32 vfp_double_fadd(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr); + + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fadd"); +} + +/* + * sd = sn - sm + */ +static u32 vfp_double_fsub(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); + + vfp_double_unpack(&vdm, vfp_get_double(dm)); + if (vdm.exponent == 0 && vdm.significand) + vfp_double_normalise_denormal(&vdm); + + /* + * Subtraction is like addition, but with a negated operand. + */ + vdm.sign = vfp_sign_negate(vdm.sign); + + exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr); + + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fsub"); +} + +/* + * sd = sn / sm + */ +static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr) +{ + struct vfp_double vdd, vdn, vdm; + u32 exceptions = 0; + int tm, tn; + + vfp_double_unpack(&vdn, vfp_get_double(dn)); + vfp_double_unpack(&vdm, vfp_get_double(dm)); + + vdd.sign = vdn.sign ^ vdm.sign; + + tn = vfp_double_type(&vdn); + tm = vfp_double_type(&vdm); + + /* + * Is n a NAN? + */ + if (tn & VFP_NAN) + goto vdn_nan; + + /* + * Is m a NAN? + */ + if (tm & VFP_NAN) + goto vdm_nan; + + /* + * If n and m are infinity, the result is invalid + * If n and m are zero, the result is invalid + */ + if (tm & tn & (VFP_INFINITY|VFP_ZERO)) + goto invalid; + + /* + * If n is infinity, the result is infinity + */ + if (tn & VFP_INFINITY) + goto infinity; + + /* + * If m is zero, raise div0 exceptions + */ + if (tm & VFP_ZERO) + goto divzero; + + /* + * If m is infinity, or n is zero, the result is zero + */ + if (tm & VFP_INFINITY || tn & VFP_ZERO) + goto zero; + + if (tn & VFP_DENORMAL) + vfp_double_normalise_denormal(&vdn); + if (tm & VFP_DENORMAL) + vfp_double_normalise_denormal(&vdm); + + /* + * Ok, we have two numbers, we can perform division. + */ + vdd.exponent = vdn.exponent - vdm.exponent + 1023 - 1; + vdm.significand <<= 1; + if (vdm.significand <= (2 * vdn.significand)) { + vdn.significand >>= 1; + vdd.exponent++; + } + vdd.significand = vfp_estimate_div128to64(vdn.significand, 0, vdm.significand); + if ((vdd.significand & 0x1ff) <= 2) { + u64 termh, terml, remh, reml; + mul64to128(&termh, &terml, vdm.significand, vdd.significand); + sub128(&remh, &reml, vdn.significand, 0, termh, terml); + while ((s64)remh < 0) { + vdd.significand -= 1; + add128(&remh, &reml, remh, reml, 0, vdm.significand); + } + vdd.significand |= (reml != 0); + } + return vfp_double_normaliseround(dd, &vdd, fpscr, 0, "fdiv"); + + vdn_nan: + exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr); + pack: + vfp_put_double(dd, vfp_double_pack(&vdd)); + return exceptions; + + vdm_nan: + exceptions = vfp_propagate_nan(&vdd, &vdm, &vdn, fpscr); + goto pack; + + zero: + vdd.exponent = 0; + vdd.significand = 0; + goto pack; + + divzero: + exceptions = FPSCR_DZC; + infinity: + vdd.exponent = 2047; + vdd.significand = 0; + goto pack; + + invalid: + vfp_put_double(dd, vfp_double_pack(&vfp_double_default_qnan)); + return FPSCR_IOC; +} + +static u32 (* const fop_fns[16])(int dd, int dn, int dm, u32 fpscr) = { + [FOP_TO_IDX(FOP_FMAC)] = vfp_double_fmac, + [FOP_TO_IDX(FOP_FNMAC)] = vfp_double_fnmac, + [FOP_TO_IDX(FOP_FMSC)] = vfp_double_fmsc, + [FOP_TO_IDX(FOP_FNMSC)] = vfp_double_fnmsc, + [FOP_TO_IDX(FOP_FMUL)] = vfp_double_fmul, + [FOP_TO_IDX(FOP_FNMUL)] = vfp_double_fnmul, + [FOP_TO_IDX(FOP_FADD)] = vfp_double_fadd, + [FOP_TO_IDX(FOP_FSUB)] = vfp_double_fsub, + [FOP_TO_IDX(FOP_FDIV)] = vfp_double_fdiv, +}; + +#define FREG_BANK(x) ((x) & 0x0c) +#define FREG_IDX(x) ((x) & 3) + +u32 vfp_double_cpdo(u32 inst, u32 fpscr) +{ + u32 op = inst & FOP_MASK; + u32 exceptions = 0; + unsigned int dd = vfp_get_sd(inst); + unsigned int dn = vfp_get_sn(inst); + unsigned int dm = vfp_get_sm(inst); + unsigned int vecitr, veclen, vecstride; + u32 (*fop)(int, int, s32, u32); + + veclen = fpscr & FPSCR_LENGTH_MASK; + vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2; + + /* + * If destination bank is zero, vector length is always '1'. + * ARM DDI0100F C5.1.3, C5.3.2. + */ + if (FREG_BANK(dd) == 0) + veclen = 0; + + pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, + (veclen >> FPSCR_LENGTH_BIT) + 1); + + fop = (op == FOP_EXT) ? fop_extfns[dn] : fop_fns[FOP_TO_IDX(op)]; + if (!fop) + goto invalid; + + for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { + u32 except; + + if (op == FOP_EXT) + pr_debug("VFP: itr%d (d%u.%u) = op[%u] (d%u.%u)\n", + vecitr >> FPSCR_LENGTH_BIT, + dd >> 1, dd & 1, dn, + dm >> 1, dm & 1); + else + pr_debug("VFP: itr%d (d%u.%u) = (d%u.%u) op[%u] (d%u.%u)\n", + vecitr >> FPSCR_LENGTH_BIT, + dd >> 1, dd & 1, + dn >> 1, dn & 1, + FOP_TO_IDX(op), + dm >> 1, dm & 1); + + except = fop(dd, dn, dm, fpscr); + pr_debug("VFP: itr%d: exceptions=%08x\n", + vecitr >> FPSCR_LENGTH_BIT, except); + + exceptions |= except; + + /* + * This ensures that comparisons only operate on scalars; + * comparisons always return with one FPSCR status bit set. + */ + if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) + break; + + /* + * CHECK: It appears to be undefined whether we stop when + * we encounter an exception. We continue. + */ + + dd = FREG_BANK(dd) + ((FREG_IDX(dd) + vecstride) & 6); + dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6); + if (FREG_BANK(dm) != 0) + dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6); + } + return exceptions; + + invalid: + return ~0; +} diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S new file mode 100644 index 0000000..de4ca12 --- /dev/null +++ b/arch/arm/vfp/vfphw.S @@ -0,0 +1,215 @@ +/* + * linux/arch/arm/vfp/vfphw.S + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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. + * + * This code is called from the kernel's undefined instruction trap. + * r9 holds the return address for successful handling. + * lr holds the return address for unrecognised instructions. + * r10 points at the start of the private FP workspace in the thread structure + * sp points to a struct pt_regs (as defined in include/asm/proc/ptrace.h) + */ +#include <asm/thread_info.h> +#include <asm/vfpmacros.h> +#include "../kernel/entry-header.S" + + .macro DBGSTR, str +#ifdef DEBUG + stmfd sp!, {r0-r3, ip, lr} + add r0, pc, #4 + bl printk + b 1f + .asciz "<7>VFP: \str\n" + .balign 4 +1: ldmfd sp!, {r0-r3, ip, lr} +#endif + .endm + + .macro DBGSTR1, str, arg +#ifdef DEBUG + stmfd sp!, {r0-r3, ip, lr} + mov r1, \arg + add r0, pc, #4 + bl printk + b 1f + .asciz "<7>VFP: \str\n" + .balign 4 +1: ldmfd sp!, {r0-r3, ip, lr} +#endif + .endm + + .macro DBGSTR3, str, arg1, arg2, arg3 +#ifdef DEBUG + stmfd sp!, {r0-r3, ip, lr} + mov r3, \arg3 + mov r2, \arg2 + mov r1, \arg1 + add r0, pc, #4 + bl printk + b 1f + .asciz "<7>VFP: \str\n" + .balign 4 +1: ldmfd sp!, {r0-r3, ip, lr} +#endif + .endm + + +@ VFP hardware support entry point. +@ +@ r0 = faulted instruction +@ r2 = faulted PC+4 +@ r9 = successful return +@ r10 = vfp_state union +@ lr = failure return + + .globl vfp_support_entry +vfp_support_entry: + DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 + + VFPFMRX r1, FPEXC @ Is the VFP enabled? + DBGSTR1 "fpexc %08x", r1 + tst r1, #FPEXC_ENABLE + bne look_for_VFP_exceptions @ VFP is already enabled + + DBGSTR1 "enable %x", r10 + ldr r3, last_VFP_context_address + orr r1, r1, #FPEXC_ENABLE @ user FPEXC has the enable bit set + ldr r4, [r3] @ last_VFP_context pointer + bic r5, r1, #FPEXC_EXCEPTION @ make sure exceptions are disabled + cmp r4, r10 + beq check_for_exception @ we are returning to the same + @ process, so the registers are + @ still there. In this case, we do + @ not want to drop a pending exception. + + VFPFMXR FPEXC, r5 @ enable VFP, disable any pending + @ exceptions, so we can get at the + @ rest of it + + @ Save out the current registers to the old thread state + + DBGSTR1 "save old state %p", r4 + cmp r4, #0 + beq no_old_VFP_process + VFPFMRX r5, FPSCR @ current status + VFPFMRX r6, FPINST @ FPINST (always there, rev0 onwards) + tst r1, #FPEXC_FPV2 @ is there an FPINST2 to read? + VFPFMRX r8, FPINST2, NE @ FPINST2 if needed - avoids reading + @ nonexistant reg on rev0 + VFPFSTMIA r4 @ save the working registers + add r4, r4, #8*16+4 + stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2 + @ and point r4 at the word at the + @ start of the register dump + +no_old_VFP_process: + DBGSTR1 "load state %p", r10 + str r10, [r3] @ update the last_VFP_context pointer + @ Load the saved state back into the VFP + add r4, r10, #8*16+4 + ldmia r4, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2 + VFPFLDMIA r10 @ reload the working registers while + @ FPEXC is in a safe state + tst r1, #FPEXC_FPV2 @ is there an FPINST2 to write? + VFPFMXR FPINST2, r8, NE @ FPINST2 if needed - avoids writing + @ nonexistant reg on rev0 + VFPFMXR FPINST, r6 + VFPFMXR FPSCR, r5 @ restore status + +check_for_exception: + tst r1, #FPEXC_EXCEPTION + bne process_exception @ might as well handle the pending + @ exception before retrying branch + @ out before setting an FPEXC that + @ stops us reading stuff + VFPFMXR FPEXC, r1 @ restore FPEXC last + sub r2, r2, #4 + str r2, [sp, #S_PC] @ retry the instruction + mov pc, r9 @ we think we have handled things + + +look_for_VFP_exceptions: + tst r1, #FPEXC_EXCEPTION + bne process_exception + VFPFMRX r5, FPSCR + tst r5, #FPSCR_IXE @ IXE doesn't set FPEXC_EXCEPTION ! + bne process_exception + + @ Fall into hand on to next handler - appropriate coproc instr + @ not recognised by VFP + + DBGSTR "not VFP" + mov pc, lr + +process_exception: + DBGSTR "bounce" + sub r2, r2, #4 + str r2, [sp, #S_PC] @ retry the instruction on exit from + @ the imprecise exception handling in + @ the support code + mov r2, sp @ nothing stacked - regdump is at TOS + mov lr, r9 @ setup for a return to the user code. + + @ Now call the C code to package up the bounce to the support code + @ r0 holds the trigger instruction + @ r1 holds the FPEXC value + @ r2 pointer to register dump + b VFP9_bounce @ we have handled this - the support + @ code will raise an exception if + @ required. If not, the user code will + @ retry the faulted instruction + +last_VFP_context_address: + .word last_VFP_context + + .globl vfp_get_float +vfp_get_float: + add pc, pc, r0, lsl #3 + mov r0, r0 + .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + mrc p10, 0, r0, c\dr, c0, 0 @ fmrs r0, s0 + mov pc, lr + mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1 + mov pc, lr + .endr + + .globl vfp_put_float +vfp_put_float: + add pc, pc, r0, lsl #3 + mov r0, r0 + .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + mcr p10, 0, r1, c\dr, c0, 0 @ fmsr r0, s0 + mov pc, lr + mcr p10, 0, r1, c\dr, c0, 4 @ fmsr r0, s1 + mov pc, lr + .endr + + .globl vfp_get_double +vfp_get_double: + mov r0, r0, lsr #1 + add pc, pc, r0, lsl #3 + mov r0, r0 + .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + mrrc p10, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr + mov pc, lr + .endr + + @ virtual register 16 for compare with zero + mov r0, #0 + mov r1, #0 + mov pc, lr + + .globl vfp_put_double +vfp_put_double: + mov r0, r0, lsr #1 + add pc, pc, r0, lsl #3 + mov r0, r0 + .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + mcrr p10, 1, r1, r2, c\dr @ fmrrd r1, r2, d\dr + mov pc, lr + .endr diff --git a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h new file mode 100644 index 0000000..6c819ae --- /dev/null +++ b/arch/arm/vfp/vfpinstr.h @@ -0,0 +1,88 @@ +/* + * linux/arch/arm/vfp/vfpinstr.h + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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. + * + * VFP instruction masks. + */ +#define INST_CPRTDO(inst) (((inst) & 0x0f000000) == 0x0e000000) +#define INST_CPRT(inst) ((inst) & (1 << 4)) +#define INST_CPRT_L(inst) ((inst) & (1 << 20)) +#define INST_CPRT_Rd(inst) (((inst) & (15 << 12)) >> 12) +#define INST_CPRT_OP(inst) (((inst) >> 21) & 7) +#define INST_CPNUM(inst) ((inst) & 0xf00) +#define CPNUM(cp) ((cp) << 8) + +#define FOP_MASK (0x00b00040) +#define FOP_FMAC (0x00000000) +#define FOP_FNMAC (0x00000040) +#define FOP_FMSC (0x00100000) +#define FOP_FNMSC (0x00100040) +#define FOP_FMUL (0x00200000) +#define FOP_FNMUL (0x00200040) +#define FOP_FADD (0x00300000) +#define FOP_FSUB (0x00300040) +#define FOP_FDIV (0x00800000) +#define FOP_EXT (0x00b00040) + +#define FOP_TO_IDX(inst) ((inst & 0x00b00000) >> 20 | (inst & (1 << 6)) >> 4) + +#define FEXT_MASK (0x000f0080) +#define FEXT_FCPY (0x00000000) +#define FEXT_FABS (0x00000080) +#define FEXT_FNEG (0x00010000) +#define FEXT_FSQRT (0x00010080) +#define FEXT_FCMP (0x00040000) +#define FEXT_FCMPE (0x00040080) +#define FEXT_FCMPZ (0x00050000) +#define FEXT_FCMPEZ (0x00050080) +#define FEXT_FCVT (0x00070080) +#define FEXT_FUITO (0x00080000) +#define FEXT_FSITO (0x00080080) +#define FEXT_FTOUI (0x000c0000) +#define FEXT_FTOUIZ (0x000c0080) +#define FEXT_FTOSI (0x000d0000) +#define FEXT_FTOSIZ (0x000d0080) + +#define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) + +#define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) +#define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12) +#define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) +#define vfp_get_dm(inst) ((inst & 0x0000000f)) +#define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) +#define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16) + +#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) + +#define FPSCR_N (1 << 31) +#define FPSCR_Z (1 << 30) +#define FPSCR_C (1 << 29) +#define FPSCR_V (1 << 28) + +/* + * Since we aren't building with -mfpu=vfp, we need to code + * these instructions using their MRC/MCR equivalents. + */ +#define vfpreg(_vfp_) #_vfp_ + +#define fmrx(_vfp_) ({ \ + u32 __v; \ + asm("mrc%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ + : "=r" (__v)); \ + __v; \ + }) + +#define fmxr(_vfp_,_var_) \ + asm("mcr%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ + : : "r" (_var_)) + +u32 vfp_single_cpdo(u32 inst, u32 fpscr); +u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs); + +u32 vfp_double_cpdo(u32 inst, u32 fpscr); diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c new file mode 100644 index 0000000..3aeedd2 --- /dev/null +++ b/arch/arm/vfp/vfpmodule.c @@ -0,0 +1,288 @@ +/* + * linux/arch/arm/vfp/vfpmodule.c + * + * Copyright (C) 2004 ARM Limited. + * Written by Deep Blue Solutions Limited. + * + * 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/module.h> +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <asm/vfp.h> + +#include "vfpinstr.h" +#include "vfp.h" + +/* + * Our undef handlers (in entry.S) + */ +void vfp_testing_entry(void); +void vfp_support_entry(void); + +void (*vfp_vector)(void) = vfp_testing_entry; +union vfp_state *last_VFP_context; + +/* + * Dual-use variable. + * Used in startup: set to non-zero if VFP checks fail + * After startup, holds VFP architecture + */ +unsigned int VFP_arch; + +/* + * Per-thread VFP initialisation. + */ +void vfp_flush_thread(union vfp_state *vfp) +{ + memset(vfp, 0, sizeof(union vfp_state)); + + vfp->hard.fpexc = FPEXC_ENABLE; + vfp->hard.fpscr = FPSCR_ROUND_NEAREST; + + /* + * Disable VFP to ensure we initialise it first. + */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); + + /* + * Ensure we don't try to overwrite our newly initialised + * state information on the first fault. + */ + if (last_VFP_context == vfp) + last_VFP_context = NULL; +} + +/* + * Per-thread VFP cleanup. + */ +void vfp_release_thread(union vfp_state *vfp) +{ + if (last_VFP_context == vfp) + last_VFP_context = NULL; +} + +/* + * Raise a SIGFPE for the current process. + * sicode describes the signal being raised. + */ +void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) +{ + siginfo_t info; + + memset(&info, 0, sizeof(info)); + + info.si_signo = SIGFPE; + info.si_code = sicode; + info.si_addr = (void *)(instruction_pointer(regs) - 4); + + /* + * This is the same as NWFPE, because it's not clear what + * this is used for + */ + current->thread.error_code = 0; + current->thread.trap_no = 6; + + force_sig_info(SIGFPE, &info, current); +} + +static void vfp_panic(char *reason) +{ + int i; + + printk(KERN_ERR "VFP: Error: %s\n", reason); + printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n", + fmrx(FPEXC), fmrx(FPSCR), fmrx(FPINST)); + for (i = 0; i < 32; i += 2) + printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n", + i, vfp_get_float(i), i+1, vfp_get_float(i+1)); +} + +/* + * Process bitmask of exception conditions. + */ +static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_regs *regs) +{ + int si_code = 0; + + pr_debug("VFP: raising exceptions %08x\n", exceptions); + + if (exceptions == (u32)-1) { + vfp_panic("unhandled bounce"); + vfp_raise_sigfpe(0, regs); + return; + } + + /* + * If any of the status flags are set, update the FPSCR. + * Comparison instructions always return at least one of + * these flags set. + */ + if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) + fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V); + + fpscr |= exceptions; + + fmxr(FPSCR, fpscr); + +#define RAISE(stat,en,sig) \ + if (exceptions & stat && fpscr & en) \ + si_code = sig; + + /* + * These are arranged in priority order, least to highest. + */ + RAISE(FPSCR_IXC, FPSCR_IXE, FPE_FLTRES); + RAISE(FPSCR_UFC, FPSCR_UFE, FPE_FLTUND); + RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF); + RAISE(FPSCR_IOC, FPSCR_IOE, FPE_FLTINV); + + if (si_code) + vfp_raise_sigfpe(si_code, regs); +} + +/* + * Emulate a VFP instruction. + */ +static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) +{ + u32 exceptions = (u32)-1; + + pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr); + + if (INST_CPRTDO(inst)) { + if (!INST_CPRT(inst)) { + /* + * CPDO + */ + if (vfp_single(inst)) { + exceptions = vfp_single_cpdo(inst, fpscr); + } else { + exceptions = vfp_double_cpdo(inst, fpscr); + } + } else { + /* + * A CPRT instruction can not appear in FPINST2, nor + * can it cause an exception. Therefore, we do not + * have to emulate it. + */ + } + } else { + /* + * A CPDT instruction can not appear in FPINST2, nor can + * it cause an exception. Therefore, we do not have to + * emulate it. + */ + } + return exceptions; +} + +/* + * Package up a bounce condition. + */ +void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) +{ + u32 fpscr, orig_fpscr, exceptions, inst; + + pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc); + + /* + * Enable access to the VFP so we can handle the bounce. + */ + fmxr(FPEXC, fpexc & ~(FPEXC_EXCEPTION|FPEXC_INV|FPEXC_UFC|FPEXC_IOC)); + + orig_fpscr = fpscr = fmrx(FPSCR); + + /* + * If we are running with inexact exceptions enabled, we need to + * emulate the trigger instruction. Note that as we're emulating + * the trigger instruction, we need to increment PC. + */ + if (fpscr & FPSCR_IXE) { + regs->ARM_pc += 4; + goto emulate; + } + + barrier(); + + /* + * Modify fpscr to indicate the number of iterations remaining + */ + if (fpexc & FPEXC_EXCEPTION) { + u32 len; + + len = fpexc + (1 << FPEXC_LENGTH_BIT); + + fpscr &= ~FPSCR_LENGTH_MASK; + fpscr |= (len & FPEXC_LENGTH_MASK) << (FPSCR_LENGTH_BIT - FPEXC_LENGTH_BIT); + } + + /* + * Handle the first FP instruction. We used to take note of the + * FPEXC bounce reason, but this appears to be unreliable. + * Emulate the bounced instruction instead. + */ + inst = fmrx(FPINST); + exceptions = vfp_emulate_instruction(inst, fpscr, regs); + if (exceptions) + vfp_raise_exceptions(exceptions, inst, orig_fpscr, regs); + + /* + * If there isn't a second FP instruction, exit now. + */ + if (!(fpexc & FPEXC_FPV2)) + return; + + /* + * The barrier() here prevents fpinst2 being read + * before the condition above. + */ + barrier(); + trigger = fmrx(FPINST2); + fpscr = fmrx(FPSCR); + + emulate: + exceptions = vfp_emulate_instruction(trigger, fpscr, regs); + if (exceptions) + vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); +} + +/* + * VFP support code initialisation. + */ +static int __init vfp_init(void) +{ + unsigned int vfpsid; + + /* + * First check that there is a VFP that we can use. + * The handler is already setup to just log calls, so + * we just need to read the VFPSID register. + */ + vfpsid = fmrx(FPSID); + + printk(KERN_INFO "VFP support v0.3: "); + if (VFP_arch) { + printk("not present\n"); + } else if (vfpsid & FPSID_NODOUBLE) { + printk("no double precision support\n"); + } else { + VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ + printk("implementor %02x architecture %d part %02x variant %x rev %x\n", + (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, + (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT, + (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, + (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, + (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); + vfp_vector = vfp_support_entry; + } + return 0; +} + +late_initcall(vfp_init); diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c new file mode 100644 index 0000000..6849fe3 --- /dev/null +++ b/arch/arm/vfp/vfpsingle.c @@ -0,0 +1,1224 @@ +/* + * linux/arch/arm/vfp/vfpsingle.c + * + * This code is derived in part from John R. Housers softfloat library, which + * carries the following notice: + * + * =========================================================================== + * This C source file is part of the SoftFloat IEC/IEEE Floating-point + * Arithmetic Package, Release 2. + * + * Written by John R. Hauser. This work was made possible in part by the + * International Computer Science Institute, located at Suite 600, 1947 Center + * Street, Berkeley, California 94704. Funding was partially provided by the + * National Science Foundation under grant MIP-9311980. The original version + * of this code was written as part of a project to build a fixed-point vector + * processor in collaboration with the University of California at Berkeley, + * overseen by Profs. Nelson Morgan and John Wawrzynek. More information + * is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ + * arithmetic/softfloat.html'. + * + * THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort + * has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT + * TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO + * PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY + * AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + * + * Derivative works are acceptable, even for commercial purposes, so long as + * (1) they include prominent notice that the work is derivative, and (2) they + * include prominent notice akin to these three paragraphs for those parts of + * this code that are retained. + * =========================================================================== + */ +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <asm/ptrace.h> +#include <asm/vfp.h> + +#include "vfpinstr.h" +#include "vfp.h" + +static struct vfp_single vfp_single_default_qnan = { + .exponent = 255, + .sign = 0, + .significand = VFP_SINGLE_SIGNIFICAND_QNAN, +}; + +static void vfp_single_dump(const char *str, struct vfp_single *s) +{ + pr_debug("VFP: %s: sign=%d exponent=%d significand=%08x\n", + str, s->sign != 0, s->exponent, s->significand); +} + +static void vfp_single_normalise_denormal(struct vfp_single *vs) +{ + int bits = 31 - fls(vs->significand); + + vfp_single_dump("normalise_denormal: in", vs); + + if (bits) { + vs->exponent -= bits - 1; + vs->significand <<= bits; + } + + vfp_single_dump("normalise_denormal: out", vs); +} + +#ifndef DEBUG +#define vfp_single_normaliseround(sd,vsd,fpscr,except,func) __vfp_single_normaliseround(sd,vsd,fpscr,except) +u32 __vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions) +#else +u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func) +#endif +{ + u32 significand, incr, rmode; + int exponent, shift, underflow; + + vfp_single_dump("pack: in", vs); + + /* + * Infinities and NaNs are a special case. + */ + if (vs->exponent == 255 && (vs->significand == 0 || exceptions)) + goto pack; + + /* + * Special-case zero. + */ + if (vs->significand == 0) { + vs->exponent = 0; + goto pack; + } + + exponent = vs->exponent; + significand = vs->significand; + + /* + * Normalise first. Note that we shift the significand up to + * bit 31, so we have VFP_SINGLE_LOW_BITS + 1 below the least + * significant bit. + */ + shift = 32 - fls(significand); + if (shift < 32 && shift) { + exponent -= shift; + significand <<= shift; + } + +#ifdef DEBUG + vs->exponent = exponent; + vs->significand = significand; + vfp_single_dump("pack: normalised", vs); +#endif + + /* + * Tiny number? + */ + underflow = exponent < 0; + if (underflow) { + significand = vfp_shiftright32jamming(significand, -exponent); + exponent = 0; +#ifdef DEBUG + vs->exponent = exponent; + vs->significand = significand; + vfp_single_dump("pack: tiny number", vs); +#endif + if (!(significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1))) + underflow = 0; + } + + /* + * Select rounding increment. + */ + incr = 0; + rmode = fpscr & FPSCR_RMODE_MASK; + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 1 << VFP_SINGLE_LOW_BITS; + if ((significand & (1 << (VFP_SINGLE_LOW_BITS + 1))) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vs->sign != 0)) + incr = (1 << (VFP_SINGLE_LOW_BITS + 1)) - 1; + + pr_debug("VFP: rounding increment = 0x%08x\n", incr); + + /* + * Is our rounding going to overflow? + */ + if ((significand + incr) < significand) { + exponent += 1; + significand = (significand >> 1) | (significand & 1); + incr >>= 1; +#ifdef DEBUG + vs->exponent = exponent; + vs->significand = significand; + vfp_single_dump("pack: overflow", vs); +#endif + } + + /* + * If any of the low bits (which will be shifted out of the + * number) are non-zero, the result is inexact. + */ + if (significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1)) + exceptions |= FPSCR_IXC; + + /* + * Do our rounding. + */ + significand += incr; + + /* + * Infinity? + */ + if (exponent >= 254) { + exceptions |= FPSCR_OFC | FPSCR_IXC; + if (incr == 0) { + vs->exponent = 253; + vs->significand = 0x7fffffff; + } else { + vs->exponent = 255; /* infinity */ + vs->significand = 0; + } + } else { + if (significand >> (VFP_SINGLE_LOW_BITS + 1) == 0) + exponent = 0; + if (exponent || significand > 0x80000000) + underflow = 0; + if (underflow) + exceptions |= FPSCR_UFC; + vs->exponent = exponent; + vs->significand = significand >> 1; + } + + pack: + vfp_single_dump("pack: final", vs); + { + s32 d = vfp_single_pack(vs); + pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, + sd, d, exceptions); + vfp_put_float(sd, d); + } + + return exceptions & ~VFP_NAN_FLAG; +} + +/* + * Propagate the NaN, setting exceptions if it is signalling. + * 'n' is always a NaN. 'm' may be a number, NaN or infinity. + */ +static u32 +vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn, + struct vfp_single *vsm, u32 fpscr) +{ + struct vfp_single *nan; + int tn, tm = 0; + + tn = vfp_single_type(vsn); + + if (vsm) + tm = vfp_single_type(vsm); + + if (fpscr & FPSCR_DEFAULT_NAN) + /* + * Default NaN mode - always returns a quiet NaN + */ + nan = &vfp_single_default_qnan; + else { + /* + * Contemporary mode - select the first signalling + * NAN, or if neither are signalling, the first + * quiet NAN. + */ + if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN)) + nan = vsn; + else + nan = vsm; + /* + * Make the NaN quiet. + */ + nan->significand |= VFP_SINGLE_SIGNIFICAND_QNAN; + } + + *vsd = *nan; + + /* + * If one was a signalling NAN, raise invalid operation. + */ + return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG; +} + + +/* + * Extended operations + */ +static u32 vfp_single_fabs(int sd, int unused, s32 m, u32 fpscr) +{ + vfp_put_float(sd, vfp_single_packed_abs(m)); + return 0; +} + +static u32 vfp_single_fcpy(int sd, int unused, s32 m, u32 fpscr) +{ + vfp_put_float(sd, m); + return 0; +} + +static u32 vfp_single_fneg(int sd, int unused, s32 m, u32 fpscr) +{ + vfp_put_float(sd, vfp_single_packed_negate(m)); + return 0; +} + +static const u16 sqrt_oddadjust[] = { + 0x0004, 0x0022, 0x005d, 0x00b1, 0x011d, 0x019f, 0x0236, 0x02e0, + 0x039c, 0x0468, 0x0545, 0x0631, 0x072b, 0x0832, 0x0946, 0x0a67 +}; + +static const u16 sqrt_evenadjust[] = { + 0x0a2d, 0x08af, 0x075a, 0x0629, 0x051a, 0x0429, 0x0356, 0x029e, + 0x0200, 0x0179, 0x0109, 0x00af, 0x0068, 0x0034, 0x0012, 0x0002 +}; + +u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) +{ + int index; + u32 z, a; + + if ((significand & 0xc0000000) != 0x40000000) { + printk(KERN_WARNING "VFP: estimate_sqrt: invalid significand\n"); + } + + a = significand << 1; + index = (a >> 27) & 15; + if (exponent & 1) { + z = 0x4000 + (a >> 17) - sqrt_oddadjust[index]; + z = ((a / z) << 14) + (z << 15); + a >>= 1; + } else { + z = 0x8000 + (a >> 17) - sqrt_evenadjust[index]; + z = a / z + z; + z = (z >= 0x20000) ? 0xffff8000 : (z << 15); + if (z <= a) + return (s32)a >> 1; + } + return (u32)(((u64)a << 31) / z) + (z >> 1); +} + +static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vsm, vsd; + int ret, tm; + + vfp_single_unpack(&vsm, m); + tm = vfp_single_type(&vsm); + if (tm & (VFP_NAN|VFP_INFINITY)) { + struct vfp_single *vsp = &vsd; + + if (tm & VFP_NAN) + ret = vfp_propagate_nan(vsp, &vsm, NULL, fpscr); + else if (vsm.sign == 0) { + sqrt_copy: + vsp = &vsm; + ret = 0; + } else { + sqrt_invalid: + vsp = &vfp_single_default_qnan; + ret = FPSCR_IOC; + } + vfp_put_float(sd, vfp_single_pack(vsp)); + return ret; + } + + /* + * sqrt(+/- 0) == +/- 0 + */ + if (tm & VFP_ZERO) + goto sqrt_copy; + + /* + * Normalise a denormalised number + */ + if (tm & VFP_DENORMAL) + vfp_single_normalise_denormal(&vsm); + + /* + * sqrt(<0) = invalid + */ + if (vsm.sign) + goto sqrt_invalid; + + vfp_single_dump("sqrt", &vsm); + + /* + * Estimate the square root. + */ + vsd.sign = 0; + vsd.exponent = ((vsm.exponent - 127) >> 1) + 127; + vsd.significand = vfp_estimate_sqrt_significand(vsm.exponent, vsm.significand) + 2; + + vfp_single_dump("sqrt estimate", &vsd); + + /* + * And now adjust. + */ + if ((vsd.significand & VFP_SINGLE_LOW_BITS_MASK) <= 5) { + if (vsd.significand < 2) { + vsd.significand = 0xffffffff; + } else { + u64 term; + s64 rem; + vsm.significand <<= !(vsm.exponent & 1); + term = (u64)vsd.significand * vsd.significand; + rem = ((u64)vsm.significand << 32) - term; + + pr_debug("VFP: term=%016llx rem=%016llx\n", term, rem); + + while (rem < 0) { + vsd.significand -= 1; + rem += ((u64)vsd.significand << 1) | 1; + } + vsd.significand |= rem != 0; + } + } + vsd.significand = vfp_shiftright32jamming(vsd.significand, 1); + + return vfp_single_normaliseround(sd, &vsd, fpscr, 0, "fsqrt"); +} + +/* + * Equal := ZC + * Less than := N + * Greater than := C + * Unordered := CV + */ +static u32 vfp_compare(int sd, int signal_on_qnan, s32 m, u32 fpscr) +{ + s32 d; + u32 ret = 0; + + d = vfp_get_float(sd); + if (vfp_single_packed_exponent(m) == 255 && vfp_single_packed_mantissa(m)) { + ret |= FPSCR_C | FPSCR_V; + if (signal_on_qnan || !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) + /* + * Signalling NaN, or signalling on quiet NaN + */ + ret |= FPSCR_IOC; + } + + if (vfp_single_packed_exponent(d) == 255 && vfp_single_packed_mantissa(d)) { + ret |= FPSCR_C | FPSCR_V; + if (signal_on_qnan || !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) + /* + * Signalling NaN, or signalling on quiet NaN + */ + ret |= FPSCR_IOC; + } + + if (ret == 0) { + if (d == m || vfp_single_packed_abs(d | m) == 0) { + /* + * equal + */ + ret |= FPSCR_Z | FPSCR_C; + } else if (vfp_single_packed_sign(d ^ m)) { + /* + * different signs + */ + if (vfp_single_packed_sign(d)) + /* + * d is negative, so d < m + */ + ret |= FPSCR_N; + else + /* + * d is positive, so d > m + */ + ret |= FPSCR_C; + } else if ((vfp_single_packed_sign(d) != 0) ^ (d < m)) { + /* + * d < m + */ + ret |= FPSCR_N; + } else if ((vfp_single_packed_sign(d) != 0) ^ (d > m)) { + /* + * d > m + */ + ret |= FPSCR_C; + } + } + return ret; +} + +static u32 vfp_single_fcmp(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_compare(sd, 0, m, fpscr); +} + +static u32 vfp_single_fcmpe(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_compare(sd, 1, m, fpscr); +} + +static u32 vfp_single_fcmpz(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_compare(sd, 0, 0, fpscr); +} + +static u32 vfp_single_fcmpez(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_compare(sd, 1, 0, fpscr); +} + +static u32 vfp_single_fcvtd(int dd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vsm; + struct vfp_double vdd; + int tm; + u32 exceptions = 0; + + vfp_single_unpack(&vsm, m); + + tm = vfp_single_type(&vsm); + + /* + * If we have a signalling NaN, signal invalid operation. + */ + if (tm == VFP_SNAN) + exceptions = FPSCR_IOC; + + if (tm & VFP_DENORMAL) + vfp_single_normalise_denormal(&vsm); + + vdd.sign = vsm.sign; + vdd.significand = (u64)vsm.significand << 32; + + /* + * If we have an infinity or NaN, the exponent must be 2047. + */ + if (tm & (VFP_INFINITY|VFP_NAN)) { + vdd.exponent = 2047; + if (tm & VFP_NAN) + vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; + goto pack_nan; + } else if (tm & VFP_ZERO) + vdd.exponent = 0; + else + vdd.exponent = vsm.exponent + (1023 - 127); + + /* + * Technically, if bit 0 of dd is set, this is an invalid + * instruction. However, we ignore this for efficiency. + */ + return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd"); + + pack_nan: + vfp_put_double(dd, vfp_double_pack(&vdd)); + return exceptions; +} + +static u32 vfp_single_fuito(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vs; + + vs.sign = 0; + vs.exponent = 127 + 31 - 1; + vs.significand = (u32)m; + + return vfp_single_normaliseround(sd, &vs, fpscr, 0, "fuito"); +} + +static u32 vfp_single_fsito(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vs; + + vs.sign = (m & 0x80000000) >> 16; + vs.exponent = 127 + 31 - 1; + vs.significand = vs.sign ? -m : m; + + return vfp_single_normaliseround(sd, &vs, fpscr, 0, "fsito"); +} + +static u32 vfp_single_ftoui(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vsm; + u32 d, exceptions = 0; + int rmode = fpscr & FPSCR_RMODE_MASK; + int tm; + + vfp_single_unpack(&vsm, m); + vfp_single_dump("VSM", &vsm); + + /* + * Do we have a denormalised number? + */ + tm = vfp_single_type(&vsm); + if (tm & VFP_DENORMAL) + exceptions |= FPSCR_IDC; + + if (tm & VFP_NAN) + vsm.sign = 0; + + if (vsm.exponent >= 127 + 32) { + d = vsm.sign ? 0 : 0xffffffff; + exceptions = FPSCR_IOC; + } else if (vsm.exponent >= 127 - 1) { + int shift = 127 + 31 - vsm.exponent; + u32 rem, incr = 0; + + /* + * 2^0 <= m < 2^32-2^8 + */ + d = (vsm.significand << 1) >> shift; + rem = vsm.significand << (33 - shift); + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 0x80000000; + if ((d & 1) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) { + incr = ~0; + } + + if ((rem + incr) < rem) { + if (d < 0xffffffff) + d += 1; + else + exceptions |= FPSCR_IOC; + } + + if (d && vsm.sign) { + d = 0; + exceptions |= FPSCR_IOC; + } else if (rem) + exceptions |= FPSCR_IXC; + } else { + d = 0; + if (vsm.exponent | vsm.significand) { + exceptions |= FPSCR_IXC; + if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) + d = 1; + else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) { + d = 0; + exceptions |= FPSCR_IOC; + } + } + } + + pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + + vfp_put_float(sd, d); + + return exceptions; +} + +static u32 vfp_single_ftouiz(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_single_ftoui(sd, unused, m, FPSCR_ROUND_TOZERO); +} + +static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) +{ + struct vfp_single vsm; + u32 d, exceptions = 0; + int rmode = fpscr & FPSCR_RMODE_MASK; + + vfp_single_unpack(&vsm, m); + vfp_single_dump("VSM", &vsm); + + /* + * Do we have a denormalised number? + */ + if (vfp_single_type(&vsm) & VFP_DENORMAL) + exceptions |= FPSCR_IDC; + + if (vsm.exponent >= 127 + 32) { + /* + * m >= 2^31-2^7: invalid + */ + d = 0x7fffffff; + if (vsm.sign) + d = ~d; + exceptions |= FPSCR_IOC; + } else if (vsm.exponent >= 127 - 1) { + int shift = 127 + 31 - vsm.exponent; + u32 rem, incr = 0; + + /* 2^0 <= m <= 2^31-2^7 */ + d = (vsm.significand << 1) >> shift; + rem = vsm.significand << (33 - shift); + + if (rmode == FPSCR_ROUND_NEAREST) { + incr = 0x80000000; + if ((d & 1) == 0) + incr -= 1; + } else if (rmode == FPSCR_ROUND_TOZERO) { + incr = 0; + } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) { + incr = ~0; + } + + if ((rem + incr) < rem && d < 0xffffffff) + d += 1; + if (d > 0x7fffffff + (vsm.sign != 0)) { + d = 0x7fffffff + (vsm.sign != 0); + exceptions |= FPSCR_IOC; + } else if (rem) + exceptions |= FPSCR_IXC; + + if (vsm.sign) + d = -d; + } else { + d = 0; + if (vsm.exponent | vsm.significand) { + exceptions |= FPSCR_IXC; + if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0) + d = 1; + else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) + d = -1; + } + } + + pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions); + + vfp_put_float(sd, (s32)d); + + return exceptions; +} + +static u32 vfp_single_ftosiz(int sd, int unused, s32 m, u32 fpscr) +{ + return vfp_single_ftosi(sd, unused, m, FPSCR_ROUND_TOZERO); +} + +static u32 (* const fop_extfns[32])(int sd, int unused, s32 m, u32 fpscr) = { + [FEXT_TO_IDX(FEXT_FCPY)] = vfp_single_fcpy, + [FEXT_TO_IDX(FEXT_FABS)] = vfp_single_fabs, + [FEXT_TO_IDX(FEXT_FNEG)] = vfp_single_fneg, + [FEXT_TO_IDX(FEXT_FSQRT)] = vfp_single_fsqrt, + [FEXT_TO_IDX(FEXT_FCMP)] = vfp_single_fcmp, + [FEXT_TO_IDX(FEXT_FCMPE)] = vfp_single_fcmpe, + [FEXT_TO_IDX(FEXT_FCMPZ)] = vfp_single_fcmpz, + [FEXT_TO_IDX(FEXT_FCMPEZ)] = vfp_single_fcmpez, + [FEXT_TO_IDX(FEXT_FCVT)] = vfp_single_fcvtd, + [FEXT_TO_IDX(FEXT_FUITO)] = vfp_single_fuito, + [FEXT_TO_IDX(FEXT_FSITO)] = vfp_single_fsito, + [FEXT_TO_IDX(FEXT_FTOUI)] = vfp_single_ftoui, + [FEXT_TO_IDX(FEXT_FTOUIZ)] = vfp_single_ftouiz, + [FEXT_TO_IDX(FEXT_FTOSI)] = vfp_single_ftosi, + [FEXT_TO_IDX(FEXT_FTOSIZ)] = vfp_single_ftosiz, +}; + + + + + +static u32 +vfp_single_fadd_nonnumber(struct vfp_single *vsd, struct vfp_single *vsn, + struct vfp_single *vsm, u32 fpscr) +{ + struct vfp_single *vsp; + u32 exceptions = 0; + int tn, tm; + + tn = vfp_single_type(vsn); + tm = vfp_single_type(vsm); + + if (tn & tm & VFP_INFINITY) { + /* + * Two infinities. Are they different signs? + */ + if (vsn->sign ^ vsm->sign) { + /* + * different signs -> invalid + */ + exceptions = FPSCR_IOC; + vsp = &vfp_single_default_qnan; + } else { + /* + * same signs -> valid + */ + vsp = vsn; + } + } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) { + /* + * One infinity and one number -> infinity + */ + vsp = vsn; + } else { + /* + * 'n' is a NaN of some type + */ + return vfp_propagate_nan(vsd, vsn, vsm, fpscr); + } + *vsd = *vsp; + return exceptions; +} + +static u32 +vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn, + struct vfp_single *vsm, u32 fpscr) +{ + u32 exp_diff, m_sig; + + if (vsn->significand & 0x80000000 || + vsm->significand & 0x80000000) { + pr_info("VFP: bad FP values in %s\n", __func__); + vfp_single_dump("VSN", vsn); + vfp_single_dump("VSM", vsm); + } + + /* + * Ensure that 'n' is the largest magnitude number. Note that + * if 'n' and 'm' have equal exponents, we do not swap them. + * This ensures that NaN propagation works correctly. + */ + if (vsn->exponent < vsm->exponent) { + struct vfp_single *t = vsn; + vsn = vsm; + vsm = t; + } + + /* + * Is 'n' an infinity or a NaN? Note that 'm' may be a number, + * infinity or a NaN here. + */ + if (vsn->exponent == 255) + return vfp_single_fadd_nonnumber(vsd, vsn, vsm, fpscr); + + /* + * We have two proper numbers, where 'vsn' is the larger magnitude. + * + * Copy 'n' to 'd' before doing the arithmetic. + */ + *vsd = *vsn; + + /* + * Align both numbers. + */ + exp_diff = vsn->exponent - vsm->exponent; + m_sig = vfp_shiftright32jamming(vsm->significand, exp_diff); + + /* + * If the signs are different, we are really subtracting. + */ + if (vsn->sign ^ vsm->sign) { + m_sig = vsn->significand - m_sig; + if ((s32)m_sig < 0) { + vsd->sign = vfp_sign_negate(vsd->sign); + m_sig = -m_sig; + } else if (m_sig == 0) { + vsd->sign = (fpscr & FPSCR_RMODE_MASK) == + FPSCR_ROUND_MINUSINF ? 0x8000 : 0; + } + } else { + m_sig = vsn->significand + m_sig; + } + vsd->significand = m_sig; + + return 0; +} + +static u32 +vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_single *vsm, u32 fpscr) +{ + vfp_single_dump("VSN", vsn); + vfp_single_dump("VSM", vsm); + + /* + * Ensure that 'n' is the largest magnitude number. Note that + * if 'n' and 'm' have equal exponents, we do not swap them. + * This ensures that NaN propagation works correctly. + */ + if (vsn->exponent < vsm->exponent) { + struct vfp_single *t = vsn; + vsn = vsm; + vsm = t; + pr_debug("VFP: swapping M <-> N\n"); + } + + vsd->sign = vsn->sign ^ vsm->sign; + + /* + * If 'n' is an infinity or NaN, handle it. 'm' may be anything. + */ + if (vsn->exponent == 255) { + if (vsn->significand || (vsm->exponent == 255 && vsm->significand)) + return vfp_propagate_nan(vsd, vsn, vsm, fpscr); + if ((vsm->exponent | vsm->significand) == 0) { + *vsd = vfp_single_default_qnan; + return FPSCR_IOC; + } + vsd->exponent = vsn->exponent; + vsd->significand = 0; + return 0; + } + + /* + * If 'm' is zero, the result is always zero. In this case, + * 'n' may be zero or a number, but it doesn't matter which. + */ + if ((vsm->exponent | vsm->significand) == 0) { + vsd->exponent = 0; + vsd->significand = 0; + return 0; + } + + /* + * We add 2 to the destination exponent for the same reason as + * the addition case - though this time we have +1 from each + * input operand. + */ + vsd->exponent = vsn->exponent + vsm->exponent - 127 + 2; + vsd->significand = vfp_hi64to32jamming((u64)vsn->significand * vsm->significand); + + vfp_single_dump("VSD", vsd); + return 0; +} + +#define NEG_MULTIPLY (1 << 0) +#define NEG_SUBTRACT (1 << 1) + +static u32 +vfp_single_multiply_accumulate(int sd, int sn, s32 m, u32 fpscr, u32 negate, char *func) +{ + struct vfp_single vsd, vsp, vsn, vsm; + u32 exceptions; + s32 v; + + v = vfp_get_float(sn); + pr_debug("VFP: s%u = %08x\n", sn, v); + vfp_single_unpack(&vsn, v); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); + + exceptions = vfp_single_multiply(&vsp, &vsn, &vsm, fpscr); + if (negate & NEG_MULTIPLY) + vsp.sign = vfp_sign_negate(vsp.sign); + + v = vfp_get_float(sd); + pr_debug("VFP: s%u = %08x\n", sd, v); + vfp_single_unpack(&vsn, v); + if (negate & NEG_SUBTRACT) + vsn.sign = vfp_sign_negate(vsn.sign); + + exceptions |= vfp_single_add(&vsd, &vsn, &vsp, fpscr); + + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, func); +} + +/* + * Standard operations + */ + +/* + * sd = sd + (sn * sm) + */ +static u32 vfp_single_fmac(int sd, int sn, s32 m, u32 fpscr) +{ + return vfp_single_multiply_accumulate(sd, sn, m, fpscr, 0, "fmac"); +} + +/* + * sd = sd - (sn * sm) + */ +static u32 vfp_single_fnmac(int sd, int sn, s32 m, u32 fpscr) +{ + return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_MULTIPLY, "fnmac"); +} + +/* + * sd = -sd + (sn * sm) + */ +static u32 vfp_single_fmsc(int sd, int sn, s32 m, u32 fpscr) +{ + return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_SUBTRACT, "fmsc"); +} + +/* + * sd = -sd - (sn * sm) + */ +static u32 vfp_single_fnmsc(int sd, int sn, s32 m, u32 fpscr) +{ + return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); +} + +/* + * sd = sn * sm + */ +static u32 vfp_single_fmul(int sd, int sn, s32 m, u32 fpscr) +{ + struct vfp_single vsd, vsn, vsm; + u32 exceptions; + s32 n = vfp_get_float(sn); + + pr_debug("VFP: s%u = %08x\n", sn, n); + + vfp_single_unpack(&vsn, n); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); + + exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr); + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fmul"); +} + +/* + * sd = -(sn * sm) + */ +static u32 vfp_single_fnmul(int sd, int sn, s32 m, u32 fpscr) +{ + struct vfp_single vsd, vsn, vsm; + u32 exceptions; + s32 n = vfp_get_float(sn); + + pr_debug("VFP: s%u = %08x\n", sn, n); + + vfp_single_unpack(&vsn, n); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); + + exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr); + vsd.sign = vfp_sign_negate(vsd.sign); + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fnmul"); +} + +/* + * sd = sn + sm + */ +static u32 vfp_single_fadd(int sd, int sn, s32 m, u32 fpscr) +{ + struct vfp_single vsd, vsn, vsm; + u32 exceptions; + s32 n = vfp_get_float(sn); + + pr_debug("VFP: s%u = %08x\n", sn, n); + + /* + * Unpack and normalise denormals. + */ + vfp_single_unpack(&vsn, n); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); + + vfp_single_unpack(&vsm, m); + if (vsm.exponent == 0 && vsm.significand) + vfp_single_normalise_denormal(&vsm); + + exceptions = vfp_single_add(&vsd, &vsn, &vsm, fpscr); + + return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fadd"); +} + +/* + * sd = sn - sm + */ +static u32 vfp_single_fsub(int sd, int sn, s32 m, u32 fpscr) +{ + /* + * Subtraction is addition with one sign inverted. + */ + return vfp_single_fadd(sd, sn, vfp_single_packed_negate(m), fpscr); +} + +/* + * sd = sn / sm + */ +static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) +{ + struct vfp_single vsd, vsn, vsm; + u32 exceptions = 0; + s32 n = vfp_get_float(sn); + int tm, tn; + + pr_debug("VFP: s%u = %08x\n", sn, n); + + vfp_single_unpack(&vsn, n); + vfp_single_unpack(&vsm, m); + + vsd.sign = vsn.sign ^ vsm.sign; + + tn = vfp_single_type(&vsn); + tm = vfp_single_type(&vsm); + + /* + * Is n a NAN? + */ + if (tn & VFP_NAN) + goto vsn_nan; + + /* + * Is m a NAN? + */ + if (tm & VFP_NAN) + goto vsm_nan; + + /* + * If n and m are infinity, the result is invalid + * If n and m are zero, the result is invalid + */ + if (tm & tn & (VFP_INFINITY|VFP_ZERO)) + goto invalid; + + /* + * If n is infinity, the result is infinity + */ + if (tn & VFP_INFINITY) + goto infinity; + + /* + * If m is zero, raise div0 exception + */ + if (tm & VFP_ZERO) + goto divzero; + + /* + * If m is infinity, or n is zero, the result is zero + */ + if (tm & VFP_INFINITY || tn & VFP_ZERO) + goto zero; + + if (tn & VFP_DENORMAL) + vfp_single_normalise_denormal(&vsn); + if (tm & VFP_DENORMAL) + vfp_single_normalise_denormal(&vsm); + + /* + * Ok, we have two numbers, we can perform division. + */ + vsd.exponent = vsn.exponent - vsm.exponent + 127 - 1; + vsm.significand <<= 1; + if (vsm.significand <= (2 * vsn.significand)) { + vsn.significand >>= 1; + vsd.exponent++; + } + vsd.significand = ((u64)vsn.significand << 32) / vsm.significand; + if ((vsd.significand & 0x3f) == 0) + vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); + + return vfp_single_normaliseround(sd, &vsd, fpscr, 0, "fdiv"); + + vsn_nan: + exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr); + pack: + vfp_put_float(sd, vfp_single_pack(&vsd)); + return exceptions; + + vsm_nan: + exceptions = vfp_propagate_nan(&vsd, &vsm, &vsn, fpscr); + goto pack; + + zero: + vsd.exponent = 0; + vsd.significand = 0; + goto pack; + + divzero: + exceptions = FPSCR_DZC; + infinity: + vsd.exponent = 255; + vsd.significand = 0; + goto pack; + + invalid: + vfp_put_float(sd, vfp_single_pack(&vfp_single_default_qnan)); + return FPSCR_IOC; +} + +static u32 (* const fop_fns[16])(int sd, int sn, s32 m, u32 fpscr) = { + [FOP_TO_IDX(FOP_FMAC)] = vfp_single_fmac, + [FOP_TO_IDX(FOP_FNMAC)] = vfp_single_fnmac, + [FOP_TO_IDX(FOP_FMSC)] = vfp_single_fmsc, + [FOP_TO_IDX(FOP_FNMSC)] = vfp_single_fnmsc, + [FOP_TO_IDX(FOP_FMUL)] = vfp_single_fmul, + [FOP_TO_IDX(FOP_FNMUL)] = vfp_single_fnmul, + [FOP_TO_IDX(FOP_FADD)] = vfp_single_fadd, + [FOP_TO_IDX(FOP_FSUB)] = vfp_single_fsub, + [FOP_TO_IDX(FOP_FDIV)] = vfp_single_fdiv, +}; + +#define FREG_BANK(x) ((x) & 0x18) +#define FREG_IDX(x) ((x) & 7) + +u32 vfp_single_cpdo(u32 inst, u32 fpscr) +{ + u32 op = inst & FOP_MASK; + u32 exceptions = 0; + unsigned int sd = vfp_get_sd(inst); + unsigned int sn = vfp_get_sn(inst); + unsigned int sm = vfp_get_sm(inst); + unsigned int vecitr, veclen, vecstride; + u32 (*fop)(int, int, s32, u32); + + veclen = fpscr & FPSCR_LENGTH_MASK; + vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK); + + /* + * If destination bank is zero, vector length is always '1'. + * ARM DDI0100F C5.1.3, C5.3.2. + */ + if (FREG_BANK(sd) == 0) + veclen = 0; + + pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, + (veclen >> FPSCR_LENGTH_BIT) + 1); + + fop = (op == FOP_EXT) ? fop_extfns[sn] : fop_fns[FOP_TO_IDX(op)]; + if (!fop) + goto invalid; + + for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { + s32 m = vfp_get_float(sm); + u32 except; + + if (op == FOP_EXT) + pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, sd, sn, sm, m); + else + pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, sd, sn, + FOP_TO_IDX(op), sm, m); + + except = fop(sd, sn, m, fpscr); + pr_debug("VFP: itr%d: exceptions=%08x\n", + vecitr >> FPSCR_LENGTH_BIT, except); + + exceptions |= except; + + /* + * This ensures that comparisons only operate on scalars; + * comparisons always return with one FPSCR status bit set. + */ + if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) + break; + + /* + * CHECK: It appears to be undefined whether we stop when + * we encounter an exception. We continue. + */ + + sd = FREG_BANK(sd) + ((FREG_IDX(sd) + vecstride) & 7); + sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7); + if (FREG_BANK(sm) != 0) + sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7); + } + return exceptions; + + invalid: + return (u32)-1; +} |