Commit 65a6ec0d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (95 commits)
  [ARM] 4578/1: CM-x270: PCMCIA support
  [ARM] 4577/1: ITE 8152 PCI bridge support
  [ARM] 4576/1: CM-X270 machine support
  [ARM] pxa: Avoid pxa_gpio_mode() in gpio_direction_{in,out}put()
  [ARM] pxa: move pxa_set_mode() from pxa2xx_mainstone.c to mainstone.c
  [ARM] pxa: move pxa_set_mode() from pxa2xx_lubbock.c to lubbock.c
  [ARM] pxa: Make cpu_is_pxaXXX dependent on configuration symbols
  [ARM] pxa: PXA3xx base support
  [NET] smc91x: fix PXA DMA support code
  [SERIAL] Fix console initialisation ordering
  [ARM] pxa: tidy up arch/arm/mach-pxa/Makefile
  [ARM] Update arch/arm/Kconfig for drivers/Kconfig changes
  [ARM] 4600/1: fix kernel build failure with build-id-supporting binutils
  [ARM] 4599/1: Preserve ATAG list for use with kexec (2.6.23)
  [ARM] Rename consistent_sync() as dma_cache_maint()
  [ARM] 4572/1: ep93xx: add cirrus logic edb9307 support
  [ARM] 4596/1: S3C2412: Correct IRQs for SDI+CF and add decoding support
  [ARM] 4595/1: ns9xxx: define registers as void __iomem * instead of volatile u32
  [ARM] 4594/1: ns9xxx: use the new gpio functions
  [ARM] 4593/1: ns9xxx: implement generic clockevents
  ...
parents 541010e4 0181b61a
...@@ -4,19 +4,29 @@ Booting ...@@ -4,19 +4,29 @@ Booting
- requirements for booting - requirements for booting
Interrupts Interrupts
- ARM Interrupt subsystem documentation - ARM Interrupt subsystem documentation
IXP2000
- Release Notes for Linux on Intel's IXP2000 Network Processor
Netwinder Netwinder
- Netwinder specific documentation - Netwinder specific documentation
Porting
- Symbol definitions for porting Linux to a new ARM machine.
Setup
- Kernel initialization parameters on ARM Linux
README README
- General ARM documentation - General ARM documentation
SA1100 SA1100/
- SA1100 documentation - SA1100 documentation
XScale Samsung-S3C24XX
- XScale documentation - S3C24XX ARM Linux Overview
empeg Sharp-LH
- Empeg documentation - Linux on Sharp LH79524 and LH7A40X System On a Chip (SOC)
VFP/
- Release notes for Linux Kernel Vector Floating Point support code
empeg/
- Ltd's Empeg MP3 Car Audio Player
mem_alignment mem_alignment
- alignment abort handler documentation - alignment abort handler documentation
memory.txt memory.txt
- description of the virtual memory layout - description of the virtual memory layout
nwfpe nwfpe/
- NWFPE floating point emulator documentation - NWFPE floating point emulator documentation
...@@ -318,6 +318,9 @@ config ARCH_KS8695 ...@@ -318,6 +318,9 @@ config ARCH_KS8695
config ARCH_NS9XXX config ARCH_NS9XXX
bool "NetSilicon NS9xxx" bool "NetSilicon NS9xxx"
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help help
Say Y here if you intend to run this kernel on a NetSilicon NS9xxx Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
System. System.
...@@ -336,14 +339,14 @@ config ARCH_PNX4008 ...@@ -336,14 +339,14 @@ config ARCH_PNX4008
This enables support for Philips PNX4008 mobile platform. This enables support for Philips PNX4008 mobile platform.
config ARCH_PXA config ARCH_PXA
bool "PXA2xx-based" bool "PXA2xx/PXA3xx-based"
depends on MMU depends on MMU
select ARCH_MTD_XIP select ARCH_MTD_XIP
select GENERIC_GPIO select GENERIC_GPIO
select GENERIC_TIME select GENERIC_TIME
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
help help
Support for Intel's PXA2XX processor line. Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
config ARCH_RPC config ARCH_RPC
bool "RiscPC" bool "RiscPC"
...@@ -486,7 +489,7 @@ source arch/arm/mm/Kconfig ...@@ -486,7 +489,7 @@ source arch/arm/mm/Kconfig
config IWMMXT config IWMMXT
bool "Enable iWMMXt support" bool "Enable iWMMXt support"
depends on CPU_XSCALE || CPU_XSC3 depends on CPU_XSCALE || CPU_XSC3
default y if PXA27x default y if PXA27x || PXA3xx
help help
Enable support for iWMMXt context switching at run time if Enable support for iWMMXt context switching at run time if
running on a CPU that supports it. running on a CPU that supports it.
...@@ -994,6 +997,10 @@ source "drivers/pnp/Kconfig" ...@@ -994,6 +997,10 @@ source "drivers/pnp/Kconfig"
source "drivers/block/Kconfig" source "drivers/block/Kconfig"
# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
source "drivers/misc/Kconfig"
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
...@@ -1029,16 +1036,16 @@ source "drivers/spi/Kconfig" ...@@ -1029,16 +1036,16 @@ source "drivers/spi/Kconfig"
source "drivers/w1/Kconfig" source "drivers/w1/Kconfig"
source "drivers/power/Kconfig"
source "drivers/hwmon/Kconfig" source "drivers/hwmon/Kconfig"
#source "drivers/l3/Kconfig" source "drivers/ssb/Kconfig"
source "drivers/misc/Kconfig" #source "drivers/l3/Kconfig"
source "drivers/mfd/Kconfig" source "drivers/mfd/Kconfig"
source "drivers/leds/Kconfig"
source "drivers/media/Kconfig" source "drivers/media/Kconfig"
source "drivers/video/Kconfig" source "drivers/video/Kconfig"
...@@ -1051,6 +1058,8 @@ source "drivers/usb/Kconfig" ...@@ -1051,6 +1058,8 @@ source "drivers/usb/Kconfig"
source "drivers/mmc/Kconfig" source "drivers/mmc/Kconfig"
source "drivers/leds/Kconfig"
source "drivers/rtc/Kconfig" source "drivers/rtc/Kconfig"
source "drivers/dma/Kconfig" source "drivers/dma/Kconfig"
......
...@@ -26,7 +26,7 @@ config FLASH_SIZE ...@@ -26,7 +26,7 @@ config FLASH_SIZE
default 0x00400000 default 0x00400000
config PROCESSOR_ID config PROCESSOR_ID
hex hex 'Hard wire the processor ID'
default 0x00007700 default 0x00007700
depends on !CPU_CP15 depends on !CPU_CP15
help help
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
LDFLAGS_vmlinux :=-p --no-undefined -X LDFLAGS_vmlinux :=-p --no-undefined -X
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
OBJCOPYFLAGS :=-O binary -R .note -R .comment -S OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
GZFLAGS :=-9 GZFLAGS :=-9
#CFLAGS +=-pipe #CFLAGS +=-pipe
# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
......
...@@ -33,10 +33,6 @@ __XScale_start: ...@@ -33,10 +33,6 @@ __XScale_start:
bic r0, r0, #0x1000 @ clear Icache bic r0, r0, #0x1000 @ clear Icache
mcr p15, 0, r0, c1, c0, 0 mcr p15, 0, r0, c1, c0, 0
#ifdef CONFIG_ARCH_LUBBOCK
mov r7, #MACH_TYPE_LUBBOCK
#endif
#ifdef CONFIG_ARCH_COTULLA_IDP #ifdef CONFIG_ARCH_COTULLA_IDP
mov r7, #MACH_TYPE_COTULLA_IDP mov r7, #MACH_TYPE_COTULLA_IDP
#endif #endif
......
...@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o ...@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_ARCH_IXP2000) += uengine.o obj-$(CONFIG_ARCH_IXP2000) += uengine.o
obj-$(CONFIG_ARCH_IXP23XX) += uengine.o obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
...@@ -263,7 +263,7 @@ map_single(struct device *dev, void *ptr, size_t size, ...@@ -263,7 +263,7 @@ map_single(struct device *dev, void *ptr, size_t size,
* We don't need to sync the DMA buffer since * We don't need to sync the DMA buffer since
* it was allocated via the coherent allocators. * it was allocated via the coherent allocators.
*/ */
consistent_sync(ptr, size, dir); dma_cache_maint(ptr, size, dir);
} }
return dma_addr; return dma_addr;
...@@ -383,7 +383,7 @@ sync_single(struct device *dev, dma_addr_t dma_addr, size_t size, ...@@ -383,7 +383,7 @@ sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
* via the coherent allocators. * via the coherent allocators.
*/ */
} else { } else {
consistent_sync(dma_to_virt(dev, dma_addr), size, dir); dma_cache_maint(dma_to_virt(dev, dma_addr), size, dir);
} }
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -279,6 +279,25 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev) ...@@ -279,6 +279,25 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev)
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693);
static void __init pci_fixup_it8152(struct pci_dev *dev)
{
int i;
/* fixup for ITE 8152 devices */
/* FIXME: add defines for class 0x68000 and 0x80103 */
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST ||
dev->class == 0x68000 ||
dev->class == 0x80103) {
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_ITE, PCI_DEVICE_ID_ITE_8152, pci_fixup_it8152);
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
{ {
if (debug_pci) if (debug_pci)
...@@ -292,9 +311,12 @@ void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) ...@@ -292,9 +311,12 @@ void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
*/ */
static inline int pdev_bad_for_parity(struct pci_dev *dev) static inline int pdev_bad_for_parity(struct pci_dev *dev)
{ {
return (dev->vendor == PCI_VENDOR_ID_INTERG && return ((dev->vendor == PCI_VENDOR_ID_INTERG &&
(dev->device == PCI_DEVICE_ID_INTERG_2000 || (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
dev->device == PCI_DEVICE_ID_INTERG_2010)); dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
(dev->vendor == PCI_VENDOR_ID_ITE &&
dev->device == PCI_DEVICE_ID_ITE_8152));
} }
/* /*
......
...@@ -361,6 +361,7 @@ ...@@ -361,6 +361,7 @@
CALL(sys_signalfd) CALL(sys_signalfd)
/* 350 */ CALL(sys_timerfd) /* 350 */ CALL(sys_timerfd)
CALL(sys_eventfd) CALL(sys_eventfd)
CALL(sys_fallocate)
#ifndef syscalls_counted #ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted #define syscalls_counted
......
...@@ -7,6 +7,23 @@ ...@@ -7,6 +7,23 @@
.globl relocate_new_kernel .globl relocate_new_kernel
relocate_new_kernel: relocate_new_kernel:
/* Move boot params back to where the kernel expects them */
ldr r0,kexec_boot_params_address
teq r0,#0
beq 8f
ldr r1,kexec_boot_params_copy
mov r6,#KEXEC_BOOT_PARAMS_SIZE/4
7:
ldr r5,[r1],#4
str r5,[r0],#4
subs r6,r6,#1
bne 7b
8:
/* Boot params moved, now go on with the kernel */
ldr r0,kexec_indirection_page ldr r0,kexec_indirection_page
ldr r1,kexec_start_address ldr r1,kexec_start_address
...@@ -50,7 +67,7 @@ relocate_new_kernel: ...@@ -50,7 +67,7 @@ relocate_new_kernel:
mov lr,r1 mov lr,r1
mov r0,#0 mov r0,#0
ldr r1,kexec_mach_type ldr r1,kexec_mach_type
mov r2,#0 ldr r2,kexec_boot_params_address
mov pc,lr mov pc,lr
.globl kexec_start_address .globl kexec_start_address
...@@ -65,6 +82,16 @@ kexec_indirection_page: ...@@ -65,6 +82,16 @@ kexec_indirection_page:
kexec_mach_type: kexec_mach_type:
.long 0x0 .long 0x0
/* phy addr where new kernel will expect to find boot params */
.globl kexec_boot_params_address
kexec_boot_params_address:
.long 0x0
/* phy addr where old kernel put a copy of orig boot params */
.globl kexec_boot_params_copy
kexec_boot_params_copy:
.long 0x0
relocate_new_kernel_end: relocate_new_kernel_end:
.globl relocate_new_kernel_size .globl relocate_new_kernel_size
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/kexec.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/elf.h> #include <asm/elf.h>
...@@ -304,10 +305,23 @@ int cpu_architecture(void) ...@@ -304,10 +305,23 @@ int cpu_architecture(void)
cpu_arch = (processor_id >> 16) & 7; cpu_arch = (processor_id >> 16) & 7;
if (cpu_arch) if (cpu_arch)
cpu_arch += CPU_ARCH_ARMv3; cpu_arch += CPU_ARCH_ARMv3;
} else { } else if ((processor_id & 0x000f0000) == 0x000f0000) {
/* the revised CPUID */ unsigned int mmfr0;
cpu_arch = ((processor_id >> 12) & 0xf) - 0xb + CPU_ARCH_ARMv6;
} /* Revised CPUID format. Read the Memory Model Feature
* Register 0 and check for VMSAv7 or PMSAv7 */
asm("mrc p15, 0, %0, c0, c1, 4"
: "=r" (mmfr0));
if ((mmfr0 & 0x0000000f) == 0x00000003 ||
(mmfr0 & 0x000000f0) == 0x00000030)
cpu_arch = CPU_ARCH_ARMv7;
else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
(mmfr0 & 0x000000f0) == 0x00000020)
cpu_arch = CPU_ARCH_ARMv6;
else
cpu_arch = CPU_ARCH_UNKNOWN;
} else
cpu_arch = CPU_ARCH_UNKNOWN;
return cpu_arch; return cpu_arch;
} }
...@@ -770,6 +784,23 @@ static int __init customize_machine(void) ...@@ -770,6 +784,23 @@ static int __init customize_machine(void)
} }
arch_initcall(customize_machine); arch_initcall(customize_machine);
#ifdef CONFIG_KEXEC
/* Physical addr of where the boot params should be for this machine */
extern unsigned long kexec_boot_params_address;
/* Physical addr of the buffer into which the boot params are copied */
extern unsigned long kexec_boot_params_copy;
/* Pointer to the boot params buffer, for manipulation and display */
unsigned long kexec_boot_params;
EXPORT_SYMBOL(kexec_boot_params);
/* The buffer itself - make sure it is sized correctly */
static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4];
#endif
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
{ {
struct tag *tags = (struct tag *)&init_tags; struct tag *tags = (struct tag *)&init_tags;
...@@ -788,6 +819,18 @@ void __init setup_arch(char **cmdline_p) ...@@ -788,6 +819,18 @@ void __init setup_arch(char **cmdline_p)
else if (mdesc->boot_params) else if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params); tags = phys_to_virt(mdesc->boot_params);
#ifdef CONFIG_KEXEC
kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf);
kexec_boot_params = (unsigned long)kexec_boot_params_buf;
if (__atags_pointer) {
kexec_boot_params_address = __atags_pointer;
memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
} else if (mdesc->boot_params) {
kexec_boot_params_address = mdesc->boot_params;
memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
}
#endif
/* /*
* If we have the old style parameters, convert them to * If we have the old style parameters, convert them to
* a tag list. * a tag list.
......
...@@ -7,6 +7,8 @@ choice ...@@ -7,6 +7,8 @@ choice
config ARCH_AT91RM9200 config ARCH_AT91RM9200
bool "AT91RM9200" bool "AT91RM9200"
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
config ARCH_AT91SAM9260 config ARCH_AT91SAM9260
bool "AT91SAM9260 or AT91SAM9XE" bool "AT91SAM9260 or AT91SAM9XE"
...@@ -20,8 +22,15 @@ config ARCH_AT91SAM9263 ...@@ -20,8 +22,15 @@ config ARCH_AT91SAM9263
config ARCH_AT91SAM9RL config ARCH_AT91SAM9RL
bool "AT91SAM9RL" bool "AT91SAM9RL"
config ARCH_AT91X40
bool "AT91x40"
endchoice endchoice
config AT91_PMC_UNIT
bool
default !ARCH_AT91X40
# ---------------------------------------------------------- # ----------------------------------------------------------
if ARCH_AT91RM9200 if ARCH_AT91RM9200
...@@ -169,6 +178,22 @@ endif ...@@ -169,6 +178,22 @@ endif
# ---------------------------------------------------------- # ----------------------------------------------------------
if ARCH_AT91X40
comment "AT91X40 Board Type"
config MACH_AT91EB01
bool "Atmel AT91EB01 Evaluation Kit"
help
Select this if you are using Atmel's AT91EB01 Evaluation Kit.
It is also a popular target for simulators such as GDB's
ARM simulator (commonly known as the ARMulator) and the
Skyeye simulator.
endif
# ----------------------------------------------------------
comment "AT91 Board Options" comment "AT91 Board Options"
config MTD_AT91_DATAFLASH_CARD config MTD_AT91_DATAFLASH_CARD
......
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
obj-y := clock.o irq.o gpio.o obj-y := irq.o gpio.o
obj-m := obj-m :=
obj-n := obj-n :=
obj- := obj- :=
obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += pm.o
# CPU-specific support # CPU-specific support
...@@ -15,6 +16,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d ...@@ -15,6 +16,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d
obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
# AT91RM9200 board-specific support # AT91RM9200 board-specific support
obj-$(CONFIG_MACH_ONEARM) += board-1arm.o obj-$(CONFIG_MACH_ONEARM) += board-1arm.o
...@@ -27,6 +29,7 @@ obj-$(CONFIG_MACH_KB9200) += board-kb9202.o ...@@ -27,6 +29,7 @@ obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
obj-$(CONFIG_MACH_KAFA) += board-kafa.o obj-$(CONFIG_MACH_KAFA) += board-kafa.o
obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
# AT91SAM9260 board-specific support # AT91SAM9260 board-specific support
obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
......
...@@ -19,70 +19,64 @@ ...@@ -19,70 +19,64 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <linux/init.h> #include <linux/kernel.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/kernel.h> #include <linux/clockchips.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/arch/at91_st.h> #include <asm/arch/at91_st.h>
static unsigned long last_crtr; static unsigned long last_crtr;
static u32 irqmask;
static struct clock_event_device clkevt;
/* /*
* The ST_CRTR is updated asynchronously to the master clock. It is therefore * The ST_CRTR is updated asynchronously to the master clock ... but
* necessary to read it twice (with the same value) to ensure accuracy. * the updates as seen by the CPU don't seem to be strictly monotonic.
* Waiting until we read the same value twice avoids glitching.
*/ */
static inline unsigned long read_CRTR(void) { static inline unsigned long read_CRTR(void)
{
unsigned long x1, x2; unsigned long x1, x2;
x1 = at91_sys_read(AT91_ST_CRTR);
do { do {
x1 = at91_sys_read(AT91_ST_CRTR);
x2 = at91_sys_read(AT91_ST_CRTR); x2 = at91_sys_read(AT91_ST_CRTR);
} while (x1 != x2); if (x1 == x2)
break;
x1 = x2;
} while (1);
return x1; return x1;
} }
/*
* Returns number of microseconds since last timer interrupt. Note that interrupts
* will have been disabled by do_gettimeofday()
* 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
* 'tick' is usecs per jiffy (linux/timex.h).
*/
static unsigned long at91rm9200_gettimeoffset(void)
{
unsigned long elapsed;
elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV;
return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
}
/* /*
* IRQ handler for the timer. * IRQ handler for the timer.
*/ */
static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
{ {
if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */ u32 sr = at91_sys_read(AT91_ST_SR) & irqmask;
write_seqlock(&xtime_lock);
while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) { /* simulate "oneshot" timer with alarm */
timer_tick(); if (sr & AT91_ST_ALMS) {
last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV; clkevt.event_handler(&clkevt);
} return IRQ_HANDLED;
}
write_sequnlock(&xtime_lock); /* periodic mode should handle delayed ticks */
if (sr & AT91_ST_PITS) {
u32 crtr = read_CRTR();
while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) {
last_crtr += LATCH;
clkevt.event_handler(&clkevt);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
else
return IRQ_NONE; /* not handled */ /* this irq is shared ... */
return IRQ_NONE;
} }
static struct irqaction at91rm9200_timer_irq = { static struct irqaction at91rm9200_timer_irq = {
...@@ -91,56 +85,127 @@ static struct irqaction at91rm9200_timer_irq = { ...@@ -91,56 +85,127 @@ static struct irqaction at91rm9200_timer_irq = {
.handler = at91rm9200_timer_interrupt .handler = at91rm9200_timer_interrupt
}; };
void at91rm9200_timer_reset(void) static cycle_t read_clk32k(void)
{ {
last_crtr = 0; return read_CRTR();
}
/* Real time counter incremented every 30.51758 microseconds */ static struct clocksource clk32k = {
at91_sys_write(AT91_ST_RTMR, 1); .name = "32k_counter",
.rating = 150,
.read = read_clk32k,
.mask = CLOCKSOURCE_MASK(20),
.shift = 10,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static void
clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
/* Disable and flush pending timer interrupts */
at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
(void) at91_sys_read(AT91_ST_SR);
/* Set Period Interval timer */ last_crtr = read_CRTR();
at91_sys_write(AT91_ST_PIMR, LATCH); switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
/* PIT for periodic irqs; fixed rate of 1/HZ */
irqmask = AT91_ST_PITS;
at91_sys_write(AT91_ST_PIMR, LATCH);
break;
case CLOCK_EVT_MODE_ONESHOT:
/* ALM for oneshot irqs, set by next_event()
* before 32 seconds have passed
*/
irqmask = AT91_ST_ALMS;
at91_sys_write(AT91_ST_RTAR, last_crtr);
break;
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_RESUME:
irqmask = 0;
break;
}
at91_sys_write(AT91_ST_IER, irqmask);
}
/* Clear any pending interrupts */ static int
clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
{
unsigned long flags;
u32 alm;
int status = 0;
BUG_ON(delta < 2);
/* Use "raw" primitives so we behave correctly on RT kernels. */
raw_local_irq_save(flags);
/* The alarm IRQ uses absolute time (now+delta), not the relative
* time (delta) in our calling convention. Like all clockevents
* using such "match" hardware, we have a race to defend against.
*
* Our defense here is to have set up the clockevent device so the
* delta is at least two. That way we never end up writing RTAR
* with the value then held in CRTR ... which would mean the match
* wouldn't trigger until 32 seconds later, after CRTR wraps.
*/
alm = read_CRTR();
/* Cancel any pending alarm; flush any pending IRQ */
at91_sys_write(AT91_ST_RTAR, alm);
(void) at91_sys_read(AT91_ST_SR); (void) at91_sys_read(AT91_ST_SR);
/* Enable Period Interval Timer interrupt */ /* Schedule alarm by writing RTAR. */
at91_sys_write(AT91_ST_IER, AT91_ST_PITS); alm += delta;
at91_sys_write(AT91_ST_RTAR, alm);
raw_local_irq_restore(flags);
return status;
} }
static struct clock_event_device clkevt = {
.name = "at91_tick",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.shift = 32,
.rating = 150,
.cpumask = CPU_MASK_CPU0,
.set_next_event = clkevt32k_next_event,
.set_mode = clkevt32k_mode,
};
/* /*
* Set up timer interrupt. * ST (system timer) module supports both clockevents and clocksource.
*/ */
void __init at91rm9200_timer_init(void) void __init at91rm9200_timer_init(void)
{ {
/* Disable all timer interrupts */ /* Disable all timer interrupts, and clear any pending ones */
at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); at91_sys_write(AT91_ST_IDR,
(void) at91_sys_read(AT91_ST_SR); /* Clear any pending interrupts */ AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
(void) at91_sys_read(AT91_ST_SR);
/* Make IRQs happen for the system timer */ /* Make IRQs happen for the system timer */
setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq);
/* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */ /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
tick_usec = (LATCH * 1000000) / CLOCK_TICK_RATE; * directly for the clocksource and all clockevents, after adjusting
* its prescaler from the 1 Hz default.
*/
at91_sys_write(AT91_ST_RTMR, 1);
/* Initialize and enable the timer interrupt */ /* Setup timer clockevent, with minimum of two ticks (important!!) */
at91rm9200_timer_reset(); clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
} clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt);
clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;
clkevt.cpumask = cpumask_of_cpu(0);
clockevents_register_device(&clkevt);
#ifdef CONFIG_PM /* register clocksource */
static void at91rm9200_timer_suspend(void) clk32k.mult = clocksource_hz2mult(AT91_SLOW_CLOCK, clk32k.shift);
{ clocksource_register(&clk32k);
/* disable Period Interval Timer interrupt */
at91_sys_write(AT91_ST_IDR, AT91_ST_PITS);
} }
#else
#define at91rm9200_timer_suspend NULL
#endif
struct sys_timer at91rm9200_timer = { struct sys_timer at91rm9200_timer = {
.init = at91rm9200_timer_init, .init = at91rm9200_timer_init,
.offset = at91rm9200_gettimeoffset,
.suspend = at91rm9200_timer_suspend,
.resume = at91rm9200_timer_reset,
}; };
/*
* arch/arm/mach-at91/at91x40.c
*
* (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
* Copyright (C) 2005 SAN People
*
* 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/init.h>
#include <linux/irq.h>
#include <asm/mach/arch.h>
#include <asm/arch/at91x40.h>
#include <asm/arch/at91_st.h>
#include "generic.h"
/*
* This is used in the gpio code, stub locally.
*/
int clk_enable(struct clk *clk)
{
return 0;
}
void __init at91x40_initialize(unsigned long main_clock)
{
at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
| (1 << AT91X40_ID_IRQ2);
}
/*
* The default interrupt priority levels (0 = lowest, 7 = highest).
*/
static unsigned int at91x40_default_irq_priority[NR_AIC_IRQS] __initdata = {
7, /* Advanced Interrupt Controller (FIQ) */
0, /* System Peripherals */
0, /* USART 0 */
0, /* USART 1 */
2, /* Timer Counter 0 */
2, /* Timer Counter 1 */
2, /* Timer Counter 2 */
0, /* Watchdog timer */
0, /* Parallel IO Controller A */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* External IRQ0 */
0, /* External IRQ1 */
0, /* External IRQ2 */
};
void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS])
{
if (!priority)
priority = at91x40_default_irq_priority;
at91_aic_init(priority);
}
/*
* arch/arm/mach-at91/at91x40_time.c
*
* (C) Copyright 2007, Greg Ungerer <gerg@snapgear.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/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/time.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/mach/time.h>
#include <asm/arch/at91_tc.h>
/*
* 3 counter/timer units present.
*/
#define AT91_TC_CLK0BASE 0
#define AT91_TC_CLK1BASE 0x40
#define AT91_TC_CLK2BASE 0x80
static unsigned long at91x40_gettimeoffset(void)
{
return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128));
}
static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id)
{
at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR);
timer_tick();
return IRQ_HANDLED;
}
static struct irqaction at91x40_timer_irq = {
.name = "at91_tick",
.flags = IRQF_DISABLED | IRQF_TIMER,
.handler = at91x40_timer_interrupt
};
void __init at91x40_timer_init(void)
{
unsigned int v;
at91_sys_write(AT91_TC + AT91_TC_BCR, 0);
v = at91_sys_read(AT91_TC + AT91_TC_BMR);
v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE;
at91_sys_write(AT91_TC + AT91_TC_BMR, v);
at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS);
at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG));
at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff);
at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1);
at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4));
setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq);
at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN));
}
struct sys_timer at91x40_timer = {
.init = at91x40_timer_init,
.offset = at91x40_gettimeoffset,
};
/*
* arch/arm/mach-at91/board-eb01.c
*
* (C) Copyright 2007, Greg Ungerer <gerg@snapgear.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/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/arch/board.h>
#include "generic.h"
static void __init at91eb01_map_io(void)
{
at91x40_initialize(40000000);
}
MACHINE_START(AT91EB01, "Atmel AT91 EB01")
/* Maintainer: Greg Ungerer <gerg@snapgear.com> */
.timer = &at91x40_timer,
.init_irq = at91x40_init_interrupts,
.map_io = at91eb01_map_io,
MACHINE_END
...@@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock); ...@@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock);
extern void __init at91sam9261_initialize(unsigned long main_clock); extern void __init at91sam9261_initialize(unsigned long main_clock);
extern void __init at91sam9263_initialize(unsigned long main_clock); extern void __init at91sam9263_initialize(unsigned long main_clock);
extern void __init at91sam9rl_initialize(unsigned long main_clock); extern void __init at91sam9rl_initialize(unsigned long main_clock);
extern void __init at91x40_initialize(unsigned long main_clock);
/* Interrupts */ /* Interrupts */
extern void __init at91rm9200_init_interrupts(unsigned int priority[]); extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
...@@ -21,12 +22,14 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]); ...@@ -21,12 +22,14 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
extern void __init at91sam9261_init_interrupts(unsigned int priority[]); extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
extern void __init at91sam9263_init_interrupts(unsigned int priority[]); extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
extern void __init at91x40_init_interrupts(unsigned int priority[]);
extern void __init at91_aic_init(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]);
/* Timer */ /* Timer */
struct sys_timer; struct sys_timer;
extern struct sys_timer at91rm9200_timer; extern struct sys_timer at91rm9200_timer;
extern struct sys_timer at91sam926x_timer; extern struct sys_timer at91sam926x_timer;
extern struct sys_timer at91x40_timer;
/* Clocks */ /* Clocks */
extern int __init at91_clock_init(unsigned long main_clock); extern int __init at91_clock_init(unsigned long main_clock);
......
...@@ -193,7 +193,11 @@ static struct irq_chip clps7500_no_chip = { ...@@ -193,7 +193,11 @@ static struct irq_chip clps7500_no_chip = {
.unmask = cl7500_no_action, .unmask = cl7500_no_action,
}; };
static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL }; static struct irqaction irq_isa = {
.handler = no_action,
.mask = CPU_MASK_NONE,
.name = "isa",
};
static void __init clps7500_init_irq(void) static void __init clps7500_init_irq(void)
{ {
......
...@@ -27,6 +27,12 @@ config MACH_EDB9302A ...@@ -27,6 +27,12 @@ config MACH_EDB9302A
Say 'Y' here if you want your kernel to support the Cirrus Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9302A Evaluation Board. Logic EDB9302A Evaluation Board.
config MACH_EDB9307
bool "Support Cirrus Logic EDB9307"
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9307 Evaluation Board.
config MACH_EDB9312 config MACH_EDB9312
bool "Support Cirrus Logic EDB9312" bool "Support Cirrus Logic EDB9312"
help help
......
...@@ -9,6 +9,7 @@ obj- := ...@@ -9,6 +9,7 @@ obj- :=
obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o
obj-$(CONFIG_MACH_EDB9302) += edb9302.o obj-$(CONFIG_MACH_EDB9302) += edb9302.o
obj-$(CONFIG_MACH_EDB9302A) += edb9302a.o obj-$(CONFIG_MACH_EDB9302A) += edb9302a.o
obj-$(CONFIG_MACH_EDB9307) += edb9307.o
obj-$(CONFIG_MACH_EDB9312) += edb9312.o obj-$(CONFIG_MACH_EDB9312) += edb9312.o
obj-$(CONFIG_MACH_EDB9315) += edb9315.o obj-$(CONFIG_MACH_EDB9315) += edb9315.o
obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o
......
/*
* arch/arm/mach-ep93xx/edb9307.c
* Cirrus Logic EDB9307 support.
*
* Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
static struct physmap_flash_data edb9307_flash_data = {
.width = 4,
};
static struct resource edb9307_flash_resource = {
.start = 0x60000000,
.end = 0x61ffffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device edb9307_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &edb9307_flash_data,
},
.num_resources = 1,
.resource = &edb9307_flash_resource,
};
static struct ep93xx_eth_data edb9307_eth_data = {
.phy_id = 1,
};
static struct resource edb9307_eth_resource[] = {
{
.start = EP93XX_ETHERNET_PHYS_BASE,
.end = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_EP93XX_ETHERNET,
.end = IRQ_EP93XX_ETHERNET,
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device edb9307_eth_device = {
.name = "ep93xx-eth",
.id = -1,
.dev = {
.platform_data = &edb9307_eth_data,
},
.num_resources = 2,
.resource = edb9307_eth_resource,
};
static void __init edb9307_init_machine(void)
{
ep93xx_init_devices();
platform_device_register(&edb9307_flash);
memcpy(edb9307_eth_data.dev_addr,
(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
platform_device_register(&edb9307_eth_device);
}
MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
.phys_io = EP93XX_APB_PHYS_BASE,
.io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.timer = &ep93xx_timer,
.init_machine = edb9307_init_machine,
MACHINE_END
...@@ -12,6 +12,39 @@ ...@@ -12,6 +12,39 @@
#include <asm/irq.h> #include <asm/irq.h>
static struct resource rtc_resources[] = {
[0] = {
.start = 0x70,
.end = 0x73,
.flags = IORESOURCE_IO,
},
[1] = {
.start = IRQ_ISA_RTC_ALARM,
.end = IRQ_ISA_RTC_ALARM,
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device rtc_device = {
.name = "rtc_cmos",
.id = -1,
.resource = rtc_resources,
.num_resources = ARRAY_SIZE(rtc_resources),
};
static struct resource serial_resources[] = {
[0] = {
.start = 0x3f8,
.end = 0x3ff,
.flags = IORESOURCE_IO,
},
[1] = {
.start = 0x2f8,
.end = 0x2ff,
.flags = IORESOURCE_IO,
},
};
static struct plat_serial8250_port serial_platform_data[] = { static struct plat_serial8250_port serial_platform_data[] = {
{ {
.iobase = 0x3f8, .iobase = 0x3f8,
...@@ -38,11 +71,21 @@ static struct platform_device serial_device = { ...@@ -38,11 +71,21 @@ static struct platform_device serial_device = {
.dev = { .dev = {
.platform_data = serial_platform_data, .platform_data = serial_platform_data,
}, },
.resource = serial_resources,
.num_resources = ARRAY_SIZE(serial_resources),
}; };
static int __init footbridge_isa_init(void) static int __init footbridge_isa_init(void)
{ {
return platform_device_register(&serial_device); int err;
err = platform_device_register(&rtc_device);
if (err)
printk(KERN_ERR "Unable to register RTC device: %d\n", err);
err = platform_device_register(&serial_device);
if (err)
printk(KERN_ERR "Unable to register serial device: %d\n", err);
return 0;
} }
arch_initcall(footbridge_isa_init); arch_initcall(footbridge_isa_init);
obj-y := irq.o time.o generic.o obj-y := irq.o time.o generic.o gpio.o
obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/gpio.h>
#include <asm/arch-ns9xxx/board.h> #include <asm/arch-ns9xxx/board.h>
#include <asm/arch-ns9xxx/regs-sys.h> #include <asm/arch-ns9xxx/regs-sys.h>
...@@ -44,7 +45,13 @@ static void a9m9750dev_fpga_ack_irq(unsigned int irq) ...@@ -44,7 +45,13 @@ static void a9m9750dev_fpga_ack_irq(unsigned int irq)
static void a9m9750dev_fpga_mask_irq(unsigned int irq) static void a9m9750dev_fpga_mask_irq(unsigned int irq)
{ {
FPGA_IER &= ~(1 << (irq - FPGA_IRQ(0))); u8 ier;
ier = __raw_readb(FPGA_IER);
ier &= ~(1 << (irq - FPGA_IRQ(0)));
__raw_writeb(ier, FPGA_IER);
} }
static void a9m9750dev_fpga_maskack_irq(unsigned int irq) static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
...@@ -55,7 +62,13 @@ static void a9m9750dev_fpga_maskack_irq(unsigned int irq) ...@@ -55,7 +62,13 @@ static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
static void a9m9750dev_fpga_unmask_irq(unsigned int irq) static void a9m9750dev_fpga_unmask_irq(unsigned int irq)
{ {
FPGA_IER |= 1 << (irq - FPGA_IRQ(0)); u8 ier;
ier = __raw_readb(FPGA_IER);
ier |= 1 << (irq - FPGA_IRQ(0));
__raw_writeb(ier, FPGA_IER);
} }
static struct irq_chip a9m9750dev_fpga_chip = { static struct irq_chip a9m9750dev_fpga_chip = {
...@@ -68,30 +81,34 @@ static struct irq_chip a9m9750dev_fpga_chip = { ...@@ -68,30 +81,34 @@ static struct irq_chip a9m9750dev_fpga_chip = {
static void a9m9750dev_fpga_demux_handler(unsigned int irq, static void a9m9750dev_fpga_demux_handler(unsigned int irq,
struct irq_desc *desc) struct irq_desc *desc)
{ {
int stat = FPGA_ISR; u8 stat = __raw_readb(FPGA_ISR);
desc->chip->mask_ack(irq);
while (stat != 0) { while (stat != 0) {
int irqno = fls(stat) - 1; int irqno = fls(stat) - 1;
struct irq_desc *fpgadesc;
stat &= ~(1 << irqno); stat &= ~(1 << irqno);
desc = irq_desc + FPGA_IRQ(irqno); fpgadesc = irq_desc + FPGA_IRQ(irqno);
desc_handle_irq(FPGA_IRQ(irqno), desc); desc_handle_irq(FPGA_IRQ(irqno), fpgadesc);
} }
desc->chip->unmask(irq);
} }
void __init board_a9m9750dev_init_irq(void) void __init board_a9m9750dev_init_irq(void)
{ {
u32 reg; u32 eic;
int i; int i;
/* if (gpio_request(11, "board a9m9750dev extirq2") == 0)
* configure gpio for IRQ_EXT2 ns9xxx_gpio_configure(11, 0, 1);
* use GPIO 11, because GPIO 32 is used for the LCD else
*/ printk(KERN_ERR "%s: cannot get gpio 11 for IRQ_EXT2\n",
/* XXX: proper GPIO handling */ __func__);
BBU_GCONFb1(1) &= ~0x2000;
for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) { for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
set_irq_chip(i, &a9m9750dev_fpga_chip); set_irq_chip(i, &a9m9750dev_fpga_chip);
...@@ -100,10 +117,10 @@ void __init board_a9m9750dev_init_irq(void) ...@@ -100,10 +117,10 @@ void __init board_a9m9750dev_init_irq(void)
} }
/* IRQ_EXT2: level sensitive + active low */ /* IRQ_EXT2: level sensitive + active low */
reg = SYS_EIC(2); eic = __raw_readl(SYS_EIC(2));
REGSET(reg, SYS_EIC, PLTY, AL); REGSET(eic, SYS_EIC, PLTY, AL);
REGSET(reg, SYS_EIC, LVEDG, LEVEL); REGSET(eic, SYS_EIC, LVEDG, LEVEL);
SYS_EIC(2) = reg; __raw_writel(eic, SYS_EIC(2));
set_irq_chained_handler(IRQ_EXT2, set_irq_chained_handler(IRQ_EXT2,
a9m9750dev_fpga_demux_handler); a9m9750dev_fpga_demux_handler);
...@@ -167,17 +184,18 @@ void __init board_a9m9750dev_init_machine(void) ...@@ -167,17 +184,18 @@ void __init board_a9m9750dev_init_machine(void)
u32 reg; u32 reg;
/* setup static CS0: memory base ... */ /* setup static CS0: memory base ... */
REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB, reg = __raw_readl(SYS_SMCSSMB(0));
NS9XXX_CSxSTAT_PHYS(0) >> 12); REGSETIM(reg, SYS_SMCSSMB, CSxB, NS9XXX_CSxSTAT_PHYS(0) >> 12);
__raw_writel(reg, SYS_SMCSSMB(0));
/* ... and mask */ /* ... and mask */
reg = SYS_SMCSSMM(0); reg = __raw_readl(SYS_SMCSSMM(0));
REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff); REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff);
REGSET(reg, SYS_SMCSSMM, CSEx, EN); REGSET(reg, SYS_SMCSSMM, CSEx, EN);
SYS_SMCSSMM(0) = reg; __raw_writel(reg, SYS_SMCSSMM(0));
/* setup static CS0: memory configuration */ /* setup static CS0: memory configuration */
reg = MEM_SMC(0); reg = __raw_readl(MEM_SMC(0));
REGSET(reg, MEM_SMC, PSMC, OFF); REGSET(reg, MEM_SMC, PSMC, OFF);
REGSET(reg, MEM_SMC, BSMC, OFF); REGSET(reg, MEM_SMC, BSMC, OFF);
REGSET(reg, MEM_SMC, EW, OFF); REGSET(reg, MEM_SMC, EW, OFF);
...@@ -185,13 +203,13 @@ void __init board_a9m9750dev_init_machine(void) ...@@ -185,13 +203,13 @@ void __init board_a9m9750dev_init_machine(void)
REGSET(reg, MEM_SMC, PC, AL); REGSET(reg, MEM_SMC, PC, AL);
REGSET(reg, MEM_SMC, PM, DIS); REGSET(reg, MEM_SMC, PM, DIS);
REGSET(reg, MEM_SMC, MW, 8); REGSET(reg, MEM_SMC, MW, 8);
MEM_SMC(0) = reg; __raw_writel(reg, MEM_SMC(0));
/* setup static CS0: timing */ /* setup static CS0: timing */
MEM_SMWED(0) = 0x2; __raw_writel(0x2, MEM_SMWED(0));
MEM_SMOED(0) = 0x2; __raw_writel(0x2, MEM_SMOED(0));
MEM_SMRD(0) = 0x6; __raw_writel(0x6, MEM_SMRD(0));
MEM_SMWD(0) = 0x6; __raw_writel(0x6, MEM_SMWD(0));
platform_add_devices(board_a9m9750dev_devices, platform_add_devices(board_a9m9750dev_devices,
ARRAY_SIZE(board_a9m9750dev_devices)); ARRAY_SIZE(board_a9m9750dev_devices));
......
This diff is collapsed.
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* the Free Software Foundation. * the Free Software Foundation.
*/ */
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/arch-ns9xxx/regs-sys.h> #include <asm/arch-ns9xxx/regs-sys.h>
...@@ -17,48 +18,17 @@ ...@@ -17,48 +18,17 @@
#include "generic.h" #include "generic.h"
static void ns9xxx_ack_irq_timer(unsigned int irq)
{
u32 tc = SYS_TC(irq - IRQ_TIMER0);
/*
* If the timer is programmed to halt on terminal count, the
* timer must be disabled before clearing the interrupt.
*/
if (REGGET(tc, SYS_TCx, REN) == 0) {
REGSET(tc, SYS_TCx, TEN, DIS);
SYS_TC(irq - IRQ_TIMER0) = tc;
}
REGSET(tc, SYS_TCx, INTC, SET);
SYS_TC(irq - IRQ_TIMER0) = tc;
REGSET(tc, SYS_TCx, INTC, UNSET);
SYS_TC(irq - IRQ_TIMER0) = tc;
}
static void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
[IRQ_TIMER0] = ns9xxx_ack_irq_timer,
[IRQ_TIMER1] = ns9xxx_ack_irq_timer,
[IRQ_TIMER2] = ns9xxx_ack_irq_timer,
[IRQ_TIMER3] = ns9xxx_ack_irq_timer,
};
static void ns9xxx_mask_irq(unsigned int irq) static void ns9xxx_mask_irq(unsigned int irq)
{ {
/* XXX: better use cpp symbols */ /* XXX: better use cpp symbols */
SYS_IC(irq / 4) &= ~(1 << (7 + 8 * (3 - (irq & 3)))); u32 ic = __raw_readl(SYS_IC(irq / 4));
ic &= ~(1 << (7 + 8 * (3 - (irq & 3))));
__raw_writel(ic, SYS_IC(irq / 4));
} }
static void ns9xxx_ack_irq(unsigned int irq) static void ns9xxx_ack_irq(unsigned int irq)
{ {
if (!ns9xxx_ack_irq_functions[irq]) { __raw_writel(0, SYS_ISRADDR);
printk(KERN_ERR "no ack function for irq %u\n", irq);
BUG();
}
ns9xxx_ack_irq_functions[irq](irq);
SYS_ISRADDR = 0;
} }
static void ns9xxx_maskack_irq(unsigned int irq) static void ns9xxx_maskack_irq(unsigned int irq)
...@@ -70,7 +40,9 @@ static void ns9xxx_maskack_irq(unsigned int irq) ...@@ -70,7 +40,9 @@ static void ns9xxx_maskack_irq(unsigned int irq)
static void ns9xxx_unmask_irq(unsigned int irq) static void ns9xxx_unmask_irq(unsigned int irq)
{ {
/* XXX: better use cpp symbols */ /* XXX: better use cpp symbols */
SYS_IC(irq / 4) |= 1 << (7 + 8 * (3 - (irq & 3))); u32 ic = __raw_readl(SYS_IC(irq / 4));
ic |= 1 << (7 + 8 * (3 - (irq & 3)));
__raw_writel(ic, SYS_IC(irq / 4));
} }
static struct irq_chip ns9xxx_chip = { static struct irq_chip ns9xxx_chip = {
...@@ -86,14 +58,14 @@ void __init ns9xxx_init_irq(void) ...@@ -86,14 +58,14 @@ void __init ns9xxx_init_irq(void)
/* disable all IRQs */ /* disable all IRQs */
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
SYS_IC(i) = (4 * i) << 24 | (4 * i + 1) << 16 | __raw_writel((4 * i) << 24 | (4 * i + 1) << 16 |
(4 * i + 2) << 8 | (4 * i + 3); (4 * i + 2) << 8 | (4 * i + 3), SYS_IC(i));
/* simple interrupt prio table: /* simple interrupt prio table:
* prio(x) < prio(y) <=> x < y * prio(x) < prio(y) <=> x < y
*/ */
for (i = 0; i < 32; ++i) for (i = 0; i < 32; ++i)
SYS_IVA(i) = i; __raw_writel(i, SYS_IVA(i));
for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) { for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) {
set_irq_chip(i, &ns9xxx_chip); set_irq_chip(i, &ns9xxx_chip);
......
This diff is collapsed.
...@@ -84,11 +84,39 @@ config MACH_OMAP_PALMTE ...@@ -84,11 +84,39 @@ config MACH_OMAP_PALMTE
bool "Palm Tungsten E" bool "Palm Tungsten E"
depends on ARCH_OMAP1 && ARCH_OMAP15XX depends on ARCH_OMAP1 && ARCH_OMAP15XX
help help
Support for the Palm Tungsten E PDA. Currently only the LCD panel Support for the Palm Tungsten E PDA. To boot the kernel, you'll
is supported. To boot the kernel, you'll need a PalmOS compatible need a PalmOS compatible bootloader; check out
bootloader; check out http://palmtelinux.sourceforge.net for more http://palmtelinux.sourceforge.net/ for more information.
information. Say Y here if you have this PDA model, say N otherwise.
Say Y here if you have such a PDA, say NO otherwise.
config MACH_OMAP_PALMZ71
bool "Palm Zire71"
depends on ARCH_OMAP1 && ARCH_OMAP15XX
help
Support for the Palm Zire71 PDA. To boot the kernel,
you'll need a PalmOS compatible bootloader; check out
http://hackndev.com/palm/z71 for more informations.
Say Y here if you have such a PDA, say N otherwise.
config MACH_OMAP_PALMTT
bool "Palm Tungsten|T"
depends on ARCH_OMAP1 && ARCH_OMAP15XX
help
Support for the Palm Tungsten|T PDA. To boot the kernel, you'll
need a PalmOS compatible bootloader (Garux); check out
http://www.hackndev.com/palm/tt/ for more information.
Say Y here if you have this PDA model, say N otherwise.
config MACH_SX1
bool "Siemens SX1"
depends on ARCH_OMAP1 && ARCH_OMAP15XX
help
Support for the Siemens SX1 phone. To boot the kernel,
you'll need a SX1 compatible bootloader; check out
http://forum.oslik.ru and
http://www.handhelds.org/moin/moin.cgi/SiemensSX1
for more information.
Say Y here if you have such a phone, say NO otherwise.
config MACH_NOKIA770 config MACH_NOKIA770
bool "Nokia 770" bool "Nokia 770"
......
...@@ -22,8 +22,11 @@ obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o ...@@ -22,8 +22,11 @@ obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
obj-$(CONFIG_MACH_OMAP_PALMZ71) += board-palmz71.o
obj-$(CONFIG_MACH_OMAP_PALMTT) += board-palmtt.o
obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o
obj-$(CONFIG_MACH_SX1) += board-sx1.o
ifeq ($(CONFIG_ARCH_OMAP15XX),y) ifeq ($(CONFIG_ARCH_OMAP15XX),y)
# Innovator-1510 FPGA # Innovator-1510 FPGA
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment