Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (100 commits) ARM: Eliminate decompressor -Dstatic= PIC hack ARM: 5958/1: ARM: U300: fix inverted clk round rate ARM: 5956/1: misplaced parentheses ARM: 5955/1: ep93xx: move timer defines into core.c and document ARM: 5954/1: ep93xx: move gpio interrupt support to gpio.c ARM: 5953/1: ep93xx: fix broken build of clock.c ARM: 5952/1: ARM: MM: Add ARM_L1_CACHE_SHIFT_6 for handle inside each ARCH Kconfig ARM: 5949/1: NUC900 add gpio virtual memory map ARM: 5948/1: Enable timer0 to time4 clock support for nuc910 ARM: 5940/2: ARM: MMCI: remove custom DBG macro and printk ARM: make_coherent(): fix problems with highpte, part 2 MM: Pass a PTE pointer to update_mmu_cache() rather than the PTE itself ARM: 5945/1: ep93xx: include correct irq.h in core.c ARM: 5933/1: amba-pl011: support hardware flow control ARM: 5930/1: Add PKMAP area description to memory.txt. ARM: 5929/1: Add checks to detect overlap of memory regions. ARM: 5928/1: Change type of VMALLOC_END to unsigned long. ARM: 5927/1: Make delimiters of DMA area globally visibly. ARM: 5926/1: Add "Virtual kernel memory..." printout. ARM: 5920/1: OMAP4: Enable L2 Cache ... Fix up trivial conflict in arch/arm/mach-mx25/clock.c
This commit is contained in:
commit
ac0f6f927d
|
@ -59,7 +59,11 @@ PAGE_OFFSET high_memory-1 Kernel direct-mapped RAM region.
|
||||||
This maps the platforms RAM, and typically
|
This maps the platforms RAM, and typically
|
||||||
maps all platform RAM in a 1:1 relationship.
|
maps all platform RAM in a 1:1 relationship.
|
||||||
|
|
||||||
TASK_SIZE PAGE_OFFSET-1 Kernel module space
|
PKMAP_BASE PAGE_OFFSET-1 Permanent kernel mappings
|
||||||
|
One way of mapping HIGHMEM pages into kernel
|
||||||
|
space.
|
||||||
|
|
||||||
|
MODULES_VADDR MODULES_END-1 Kernel module space
|
||||||
Kernel modules inserted via insmod are
|
Kernel modules inserted via insmod are
|
||||||
placed here using dynamic mappings.
|
placed here using dynamic mappings.
|
||||||
|
|
||||||
|
|
|
@ -88,12 +88,12 @@ changes occur:
|
||||||
This is used primarily during fault processing.
|
This is used primarily during fault processing.
|
||||||
|
|
||||||
5) void update_mmu_cache(struct vm_area_struct *vma,
|
5) void update_mmu_cache(struct vm_area_struct *vma,
|
||||||
unsigned long address, pte_t pte)
|
unsigned long address, pte_t *ptep)
|
||||||
|
|
||||||
At the end of every page fault, this routine is invoked to
|
At the end of every page fault, this routine is invoked to
|
||||||
tell the architecture specific code that a translation
|
tell the architecture specific code that a translation
|
||||||
described by "pte" now exists at virtual address "address"
|
now exists at virtual address "address" for address space
|
||||||
for address space "vma->vm_mm", in the software page tables.
|
"vma->vm_mm", in the software page tables.
|
||||||
|
|
||||||
A port may use this information in any way it so chooses.
|
A port may use this information in any way it so chooses.
|
||||||
For example, it could use this event to pre-load TLB
|
For example, it could use this event to pre-load TLB
|
||||||
|
|
|
@ -329,7 +329,7 @@ extern pgd_t swapper_pg_dir[1024];
|
||||||
* tables contain all the necessary information.
|
* tables contain all the necessary information.
|
||||||
*/
|
*/
|
||||||
extern inline void update_mmu_cache(struct vm_area_struct * vma,
|
extern inline void update_mmu_cache(struct vm_area_struct * vma,
|
||||||
unsigned long address, pte_t pte)
|
unsigned long address, pte_t *ptep)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ config ARM
|
||||||
select HAVE_IDE
|
select HAVE_IDE
|
||||||
select RTC_LIB
|
select RTC_LIB
|
||||||
select SYS_SUPPORTS_APM_EMULATION
|
select SYS_SUPPORTS_APM_EMULATION
|
||||||
|
select GENERIC_ATOMIC64 if (!CPU_32v6K)
|
||||||
select HAVE_OPROFILE
|
select HAVE_OPROFILE
|
||||||
select HAVE_ARCH_KGDB
|
select HAVE_ARCH_KGDB
|
||||||
select HAVE_KPROBES if (!XIP_KERNEL)
|
select HAVE_KPROBES if (!XIP_KERNEL)
|
||||||
|
@ -20,6 +21,8 @@ config ARM
|
||||||
select HAVE_GENERIC_DMA_COHERENT
|
select HAVE_GENERIC_DMA_COHERENT
|
||||||
select HAVE_KERNEL_GZIP
|
select HAVE_KERNEL_GZIP
|
||||||
select HAVE_KERNEL_LZO
|
select HAVE_KERNEL_LZO
|
||||||
|
select HAVE_PERF_EVENTS
|
||||||
|
select PERF_USE_VMALLOC
|
||||||
help
|
help
|
||||||
The ARM series is a line of low-power-consumption RISC chip designs
|
The ARM series is a line of low-power-consumption RISC chip designs
|
||||||
licensed by ARM Ltd and targeted at embedded applications and
|
licensed by ARM Ltd and targeted at embedded applications and
|
||||||
|
@ -52,6 +55,9 @@ config HAVE_TCM
|
||||||
bool
|
bool
|
||||||
select GENERIC_ALLOCATOR
|
select GENERIC_ALLOCATOR
|
||||||
|
|
||||||
|
config HAVE_PROC_CPU
|
||||||
|
bool
|
||||||
|
|
||||||
config NO_IOPORT
|
config NO_IOPORT
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
@ -161,6 +167,11 @@ config ARCH_MTD_XIP
|
||||||
config GENERIC_HARDIRQS_NO__DO_IRQ
|
config GENERIC_HARDIRQS_NO__DO_IRQ
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
config ARM_L1_CACHE_SHIFT_6
|
||||||
|
bool
|
||||||
|
help
|
||||||
|
Setting ARM L1 cache line size to 64 Bytes.
|
||||||
|
|
||||||
if OPROFILE
|
if OPROFILE
|
||||||
|
|
||||||
config OPROFILE_ARMV6
|
config OPROFILE_ARMV6
|
||||||
|
@ -550,10 +561,20 @@ config ARCH_W90X900
|
||||||
<http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
|
<http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
|
||||||
ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
|
ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
|
||||||
|
|
||||||
|
config ARCH_NUC93X
|
||||||
|
bool "Nuvoton NUC93X CPU"
|
||||||
|
select CPU_ARM926T
|
||||||
|
select HAVE_CLK
|
||||||
|
select COMMON_CLKDEV
|
||||||
|
help
|
||||||
|
Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
|
||||||
|
low-power and high performance MPEG-4/JPEG multimedia controller chip.
|
||||||
|
|
||||||
config ARCH_PNX4008
|
config ARCH_PNX4008
|
||||||
bool "Philips Nexperia PNX4008 Mobile"
|
bool "Philips Nexperia PNX4008 Mobile"
|
||||||
select CPU_ARM926T
|
select CPU_ARM926T
|
||||||
select HAVE_CLK
|
select HAVE_CLK
|
||||||
|
select COMMON_CLKDEV
|
||||||
help
|
help
|
||||||
This enables support for Philips PNX4008 mobile platform.
|
This enables support for Philips PNX4008 mobile platform.
|
||||||
|
|
||||||
|
@ -638,6 +659,7 @@ config ARCH_S5PC1XX
|
||||||
select GENERIC_GPIO
|
select GENERIC_GPIO
|
||||||
select HAVE_CLK
|
select HAVE_CLK
|
||||||
select CPU_V7
|
select CPU_V7
|
||||||
|
select ARM_L1_CACHE_SHIFT_6
|
||||||
help
|
help
|
||||||
Samsung S5PC1XX series based systems
|
Samsung S5PC1XX series based systems
|
||||||
|
|
||||||
|
@ -785,6 +807,8 @@ source "arch/arm/plat-nomadik/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-ns9xxx/Kconfig"
|
source "arch/arm/mach-ns9xxx/Kconfig"
|
||||||
|
|
||||||
|
source "arch/arm/mach-nuc93x/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/plat-omap/Kconfig"
|
source "arch/arm/plat-omap/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-omap1/Kconfig"
|
source "arch/arm/mach-omap1/Kconfig"
|
||||||
|
@ -867,6 +891,11 @@ config XSCALE_PMU
|
||||||
depends on CPU_XSCALE && !XSCALE_PMU_TIMER
|
depends on CPU_XSCALE && !XSCALE_PMU_TIMER
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config CPU_HAS_PMU
|
||||||
|
depends on CPU_V6 || CPU_V7 || XSCALE_PMU
|
||||||
|
default y
|
||||||
|
bool
|
||||||
|
|
||||||
if !MMU
|
if !MMU
|
||||||
source "arch/arm/Kconfig-nommu"
|
source "arch/arm/Kconfig-nommu"
|
||||||
endif
|
endif
|
||||||
|
@ -921,6 +950,19 @@ config ARM_ERRATA_460075
|
||||||
ACTLR register. Note that setting specific bits in the ACTLR register
|
ACTLR register. Note that setting specific bits in the ACTLR register
|
||||||
may not be available in non-secure mode.
|
may not be available in non-secure mode.
|
||||||
|
|
||||||
|
config PL310_ERRATA_588369
|
||||||
|
bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
|
||||||
|
depends on CACHE_L2X0 && ARCH_OMAP4
|
||||||
|
help
|
||||||
|
The PL310 L2 cache controller implements three types of Clean &
|
||||||
|
Invalidate maintenance operations: by Physical Address
|
||||||
|
(offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
|
||||||
|
They are architecturally defined to behave as the execution of a
|
||||||
|
clean operation followed immediately by an invalidate operation,
|
||||||
|
both performing to the same memory location. This functionality
|
||||||
|
is not correctly implemented in PL310 as clean lines are not
|
||||||
|
invalidated as a result of these operations. Note that this errata
|
||||||
|
uses Texas Instrument's secure monitor api.
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
source "arch/arm/common/Kconfig"
|
source "arch/arm/common/Kconfig"
|
||||||
|
@ -1171,6 +1213,14 @@ config HIGHPTE
|
||||||
depends on HIGHMEM
|
depends on HIGHMEM
|
||||||
depends on !OUTER_CACHE
|
depends on !OUTER_CACHE
|
||||||
|
|
||||||
|
config HW_PERF_EVENTS
|
||||||
|
bool "Enable hardware performance counter support for perf events"
|
||||||
|
depends on PERF_EVENTS && CPU_HAS_PMU && (CPU_V6 || CPU_V7)
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable hardware performance counter support for perf events. If
|
||||||
|
disabled, perf events will use software events only.
|
||||||
|
|
||||||
source "mm/Kconfig"
|
source "mm/Kconfig"
|
||||||
|
|
||||||
config LEDS
|
config LEDS
|
||||||
|
@ -1230,6 +1280,7 @@ config ALIGNMENT_TRAP
|
||||||
bool
|
bool
|
||||||
depends on CPU_CP15_MMU
|
depends on CPU_CP15_MMU
|
||||||
default y if !ARCH_EBSA110
|
default y if !ARCH_EBSA110
|
||||||
|
select HAVE_PROC_CPU if PROC_FS
|
||||||
help
|
help
|
||||||
ARM processors cannot fetch/store information which is not
|
ARM processors cannot fetch/store information which is not
|
||||||
naturally aligned on the bus, i.e., a 4 byte fetch must start at an
|
naturally aligned on the bus, i.e., a 4 byte fetch must start at an
|
||||||
|
|
|
@ -171,6 +171,7 @@ machine-$(CONFIG_ARCH_U300) := u300
|
||||||
machine-$(CONFIG_ARCH_U8500) := ux500
|
machine-$(CONFIG_ARCH_U8500) := ux500
|
||||||
machine-$(CONFIG_ARCH_VERSATILE) := versatile
|
machine-$(CONFIG_ARCH_VERSATILE) := versatile
|
||||||
machine-$(CONFIG_ARCH_W90X900) := w90x900
|
machine-$(CONFIG_ARCH_W90X900) := w90x900
|
||||||
|
machine-$(CONFIG_ARCH_NUC93X) := nuc93x
|
||||||
machine-$(CONFIG_FOOTBRIDGE) := footbridge
|
machine-$(CONFIG_FOOTBRIDGE) := footbridge
|
||||||
|
|
||||||
# Platform directory name. This list is sorted alphanumerically
|
# Platform directory name. This list is sorted alphanumerically
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
HEAD = head.o
|
HEAD = head.o
|
||||||
OBJS = misc.o
|
OBJS = misc.o decompress.o
|
||||||
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
|
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -106,10 +106,6 @@ lib1funcs = $(obj)/lib1funcs.o
|
||||||
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
|
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
|
||||||
$(call cmd,shipped)
|
$(call cmd,shipped)
|
||||||
|
|
||||||
# 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.$(suffix_y).o \
|
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
|
||||||
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
|
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
|
||||||
$(call if_changed,ld)
|
$(call if_changed,ld)
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
#define _LINUX_STRING_H_
|
||||||
|
|
||||||
|
#include <linux/compiler.h> /* for inline */
|
||||||
|
#include <linux/types.h> /* for size_t */
|
||||||
|
#include <linux/stddef.h> /* for NULL */
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/string.h>
|
||||||
|
|
||||||
|
extern unsigned long free_mem_ptr;
|
||||||
|
extern unsigned long free_mem_end_ptr;
|
||||||
|
extern void error(char *);
|
||||||
|
|
||||||
|
#define STATIC static
|
||||||
|
|
||||||
|
#define ARCH_HAS_DECOMP_WDOG
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_GZIP
|
||||||
|
#include "../../../../lib/decompress_inflate.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_LZO
|
||||||
|
#include "../../../../lib/decompress_unlzo.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
|
||||||
|
{
|
||||||
|
decompress(input, len, NULL, NULL, output, NULL, error);
|
||||||
|
}
|
|
@ -22,13 +22,13 @@
|
||||||
#if defined(CONFIG_DEBUG_ICEDCC)
|
#if defined(CONFIG_DEBUG_ICEDCC)
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_V6
|
#ifdef CONFIG_CPU_V6
|
||||||
.macro loadsp, rb
|
.macro loadsp, rb, tmp
|
||||||
.endm
|
.endm
|
||||||
.macro writeb, ch, rb
|
.macro writeb, ch, rb
|
||||||
mcr p14, 0, \ch, c0, c5, 0
|
mcr p14, 0, \ch, c0, c5, 0
|
||||||
.endm
|
.endm
|
||||||
#elif defined(CONFIG_CPU_V7)
|
#elif defined(CONFIG_CPU_V7)
|
||||||
.macro loadsp, rb
|
.macro loadsp, rb, tmp
|
||||||
.endm
|
.endm
|
||||||
.macro writeb, ch, rb
|
.macro writeb, ch, rb
|
||||||
wait: mrc p14, 0, pc, c0, c1, 0
|
wait: mrc p14, 0, pc, c0, c1, 0
|
||||||
|
@ -36,13 +36,13 @@ wait: mrc p14, 0, pc, c0, c1, 0
|
||||||
mcr p14, 0, \ch, c0, c5, 0
|
mcr p14, 0, \ch, c0, c5, 0
|
||||||
.endm
|
.endm
|
||||||
#elif defined(CONFIG_CPU_XSCALE)
|
#elif defined(CONFIG_CPU_XSCALE)
|
||||||
.macro loadsp, rb
|
.macro loadsp, rb, tmp
|
||||||
.endm
|
.endm
|
||||||
.macro writeb, ch, rb
|
.macro writeb, ch, rb
|
||||||
mcr p14, 0, \ch, c8, c0, 0
|
mcr p14, 0, \ch, c8, c0, 0
|
||||||
.endm
|
.endm
|
||||||
#else
|
#else
|
||||||
.macro loadsp, rb
|
.macro loadsp, rb, tmp
|
||||||
.endm
|
.endm
|
||||||
.macro writeb, ch, rb
|
.macro writeb, ch, rb
|
||||||
mcr p14, 0, \ch, c1, c0, 0
|
mcr p14, 0, \ch, c1, c0, 0
|
||||||
|
@ -58,7 +58,7 @@ wait: mrc p14, 0, pc, c0, c1, 0
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_SA1100)
|
#if defined(CONFIG_ARCH_SA1100)
|
||||||
.macro loadsp, rb
|
.macro loadsp, rb, tmp
|
||||||
mov \rb, #0x80000000 @ physical base address
|
mov \rb, #0x80000000 @ physical base address
|
||||||
#ifdef CONFIG_DEBUG_LL_SER3
|
#ifdef CONFIG_DEBUG_LL_SER3
|
||||||
add \rb, \rb, #0x00050000 @ Ser3
|
add \rb, \rb, #0x00050000 @ Ser3
|
||||||
|
@ -67,13 +67,13 @@ wait: mrc p14, 0, pc, c0, c1, 0
|
||||||
#endif
|
#endif
|
||||||
.endm
|
.endm
|
||||||
#elif defined(CONFIG_ARCH_S3C2410)
|
#elif defined(CONFIG_ARCH_S3C2410)
|
||||||
.macro loadsp, rb
|
.macro loadsp, rb, tmp
|
||||||
mov \rb, #0x50000000
|
mov \rb, #0x50000000
|
||||||
add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
|
add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
|
||||||
.endm
|
.endm
|
||||||
#else
|
#else
|
||||||
.macro loadsp, rb
|
.macro loadsp, rb, tmp
|
||||||
addruart \rb
|
addruart \rb, \tmp
|
||||||
.endm
|
.endm
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -1025,7 +1025,7 @@ phex: adr r3, phexbuf
|
||||||
strb r2, [r3, r1]
|
strb r2, [r3, r1]
|
||||||
b 1b
|
b 1b
|
||||||
|
|
||||||
puts: loadsp r3
|
puts: loadsp r3, r1
|
||||||
1: ldrb r2, [r0], #1
|
1: ldrb r2, [r0], #1
|
||||||
teq r2, #0
|
teq r2, #0
|
||||||
moveq pc, lr
|
moveq pc, lr
|
||||||
|
@ -1042,7 +1042,7 @@ puts: loadsp r3
|
||||||
putc:
|
putc:
|
||||||
mov r2, r0
|
mov r2, r0
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
loadsp r3
|
loadsp r3, r1
|
||||||
b 2b
|
b 2b
|
||||||
|
|
||||||
memdump: mov r12, r0
|
memdump: mov r12, r0
|
||||||
|
|
|
@ -23,8 +23,8 @@ unsigned int __machine_arch_type;
|
||||||
#include <linux/compiler.h> /* for inline */
|
#include <linux/compiler.h> /* for inline */
|
||||||
#include <linux/types.h> /* for size_t */
|
#include <linux/types.h> /* for size_t */
|
||||||
#include <linux/stddef.h> /* for NULL */
|
#include <linux/stddef.h> /* for NULL */
|
||||||
#include <asm/string.h>
|
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/string.h>
|
||||||
|
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
|
@ -117,57 +117,7 @@ static void putstr(const char *ptr)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __ptr_t void *
|
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||||
|
|
||||||
#define memzero(s,n) __memzero(s,n)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
int i = 0;
|
||||||
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
|
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
|
||||||
|
@ -204,59 +154,20 @@ static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
|
||||||
/*
|
/*
|
||||||
* gzip delarations
|
* gzip delarations
|
||||||
*/
|
*/
|
||||||
#define STATIC static
|
|
||||||
|
|
||||||
/* 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 void error(char *m);
|
|
||||||
|
|
||||||
extern char input_data[];
|
extern char input_data[];
|
||||||
extern char input_data_end[];
|
extern char input_data_end[];
|
||||||
|
|
||||||
static unsigned char *output_data;
|
unsigned char *output_data;
|
||||||
static unsigned long output_ptr;
|
unsigned long output_ptr;
|
||||||
|
|
||||||
static void error(char *m);
|
unsigned long free_mem_ptr;
|
||||||
|
unsigned long free_mem_end_ptr;
|
||||||
static void putstr(const char *);
|
|
||||||
|
|
||||||
static unsigned long free_mem_ptr;
|
|
||||||
static unsigned long free_mem_end_ptr;
|
|
||||||
|
|
||||||
#ifdef STANDALONE_DEBUG
|
|
||||||
#define NO_INFLATE_MALLOC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ARCH_HAS_DECOMP_WDOG
|
|
||||||
|
|
||||||
#ifdef CONFIG_KERNEL_GZIP
|
|
||||||
#include "../../../../lib/decompress_inflate.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_KERNEL_LZO
|
|
||||||
#include "../../../../lib/decompress_unlzo.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef arch_error
|
#ifndef arch_error
|
||||||
#define arch_error(x)
|
#define arch_error(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void error(char *x)
|
void error(char *x)
|
||||||
{
|
{
|
||||||
arch_error(x);
|
arch_error(x);
|
||||||
|
|
||||||
|
@ -272,6 +183,8 @@ asmlinkage void __div0(void)
|
||||||
error("Attempting division by 0!");
|
error("Attempting division by 0!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
|
||||||
|
|
||||||
#ifndef STANDALONE_DEBUG
|
#ifndef STANDALONE_DEBUG
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
|
@ -292,8 +205,8 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
|
||||||
output_ptr = get_unaligned_le32(tmp);
|
output_ptr = get_unaligned_le32(tmp);
|
||||||
|
|
||||||
putstr("Uncompressing Linux...");
|
putstr("Uncompressing Linux...");
|
||||||
decompress(input_data, input_data_end - input_data,
|
do_decompress(input_data, input_data_end - input_data,
|
||||||
NULL, NULL, output_data, NULL, error);
|
output_data, error);
|
||||||
putstr(" done, booting the kernel.\n");
|
putstr(" done, booting the kernel.\n");
|
||||||
return output_ptr;
|
return output_ptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,13 @@ SECTIONS
|
||||||
/DISCARD/ : {
|
/DISCARD/ : {
|
||||||
*(.ARM.exidx*)
|
*(.ARM.exidx*)
|
||||||
*(.ARM.extab*)
|
*(.ARM.extab*)
|
||||||
|
/*
|
||||||
|
* Discard any r/w data - this produces a link error if we have any,
|
||||||
|
* which is required for PIC decompression. Local data generates
|
||||||
|
* GOTOFF relocations, which prevents it being relocated independently
|
||||||
|
* of the text/got segments.
|
||||||
|
*/
|
||||||
|
*(.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
. = TEXT_START;
|
. = TEXT_START;
|
||||||
|
@ -40,7 +47,6 @@ SECTIONS
|
||||||
.got : { *(.got) }
|
.got : { *(.got) }
|
||||||
_got_end = .;
|
_got_end = .;
|
||||||
.got.plt : { *(.got.plt) }
|
.got.plt : { *(.got.plt) }
|
||||||
.data : { *(.data) }
|
|
||||||
_edata = .;
|
_edata = .;
|
||||||
|
|
||||||
. = BSS_START;
|
. = BSS_START;
|
||||||
|
|
|
@ -99,6 +99,16 @@ void clkdev_add(struct clk_lookup *cl)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(clkdev_add);
|
EXPORT_SYMBOL(clkdev_add);
|
||||||
|
|
||||||
|
void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
|
||||||
|
{
|
||||||
|
mutex_lock(&clocks_mutex);
|
||||||
|
while (num--) {
|
||||||
|
list_add_tail(&cl->node, &clocks);
|
||||||
|
cl++;
|
||||||
|
}
|
||||||
|
mutex_unlock(&clocks_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
#define MAX_DEV_ID 20
|
#define MAX_DEV_ID 20
|
||||||
#define MAX_CON_ID 16
|
#define MAX_CON_ID 16
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,7 @@ static inline dma_addr_t 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.
|
||||||
*/
|
*/
|
||||||
dma_cache_maint(ptr, size, dir);
|
__dma_single_cpu_to_dev(ptr, size, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dma_addr;
|
return dma_addr;
|
||||||
|
@ -315,6 +315,8 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
|
||||||
__cpuc_flush_dcache_area(ptr, size);
|
__cpuc_flush_dcache_area(ptr, size);
|
||||||
}
|
}
|
||||||
free_safe_buffer(dev->archdata.dmabounce, buf);
|
free_safe_buffer(dev->archdata.dmabounce, buf);
|
||||||
|
} else {
|
||||||
|
__dma_single_dev_to_cpu(dma_to_virt(dev, dma_addr), size, dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* 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/init.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
@ -28,48 +29,6 @@
|
||||||
#include <asm/mach/irq.h>
|
#include <asm/mach/irq.h>
|
||||||
#include <asm/hardware/vic.h>
|
#include <asm/hardware/vic.h>
|
||||||
|
|
||||||
static void vic_ack_irq(unsigned int irq)
|
|
||||||
{
|
|
||||||
void __iomem *base = get_irq_chip_data(irq);
|
|
||||||
irq &= 31;
|
|
||||||
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
|
|
||||||
/* moreover, clear the soft-triggered, in case it was the reason */
|
|
||||||
writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vic_mask_irq(unsigned int irq)
|
|
||||||
{
|
|
||||||
void __iomem *base = get_irq_chip_data(irq);
|
|
||||||
irq &= 31;
|
|
||||||
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vic_unmask_irq(unsigned int irq)
|
|
||||||
{
|
|
||||||
void __iomem *base = get_irq_chip_data(irq);
|
|
||||||
irq &= 31;
|
|
||||||
writel(1 << irq, base + VIC_INT_ENABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vic_init2 - common initialisation code
|
|
||||||
* @base: Base of the VIC.
|
|
||||||
*
|
|
||||||
* Common initialisation code for registeration
|
|
||||||
* and resume.
|
|
||||||
*/
|
|
||||||
static void vic_init2(void __iomem *base)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
|
|
||||||
writel(VIC_VECT_CNTL_ENABLE | i, reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
writel(32, base + VIC_PL190_DEF_VECT_ADDR);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_PM)
|
#if defined(CONFIG_PM)
|
||||||
/**
|
/**
|
||||||
* struct vic_device - VIC PM device
|
* struct vic_device - VIC PM device
|
||||||
|
@ -99,13 +58,34 @@ struct vic_device {
|
||||||
/* we cannot allocate memory when VICs are initially registered */
|
/* we cannot allocate memory when VICs are initially registered */
|
||||||
static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
|
static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
|
||||||
|
|
||||||
|
static int vic_id;
|
||||||
|
|
||||||
static inline struct vic_device *to_vic(struct sys_device *sys)
|
static inline struct vic_device *to_vic(struct sys_device *sys)
|
||||||
{
|
{
|
||||||
return container_of(sys, struct vic_device, sysdev);
|
return container_of(sys, struct vic_device, sysdev);
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
static int vic_id;
|
/**
|
||||||
|
* vic_init2 - common initialisation code
|
||||||
|
* @base: Base of the VIC.
|
||||||
|
*
|
||||||
|
* Common initialisation code for registeration
|
||||||
|
* and resume.
|
||||||
|
*/
|
||||||
|
static void vic_init2(void __iomem *base)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
|
||||||
|
writel(VIC_VECT_CNTL_ENABLE | i, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(32, base + VIC_PL190_DEF_VECT_ADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_PM)
|
||||||
static int vic_class_resume(struct sys_device *dev)
|
static int vic_class_resume(struct sys_device *dev)
|
||||||
{
|
{
|
||||||
struct vic_device *vic = to_vic(dev);
|
struct vic_device *vic = to_vic(dev);
|
||||||
|
@ -158,31 +138,6 @@ struct sysdev_class vic_class = {
|
||||||
.resume = vic_class_resume,
|
.resume = vic_class_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* vic_pm_register - Register a VIC for later power management control
|
|
||||||
* @base: The base address of the VIC.
|
|
||||||
* @irq: The base IRQ for the VIC.
|
|
||||||
* @resume_sources: bitmask of interrupts allowed for resume sources.
|
|
||||||
*
|
|
||||||
* Register the VIC with the system device tree so that it can be notified
|
|
||||||
* of suspend and resume requests and ensure that the correct actions are
|
|
||||||
* taken to re-instate the settings on resume.
|
|
||||||
*/
|
|
||||||
static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
|
|
||||||
{
|
|
||||||
struct vic_device *v;
|
|
||||||
|
|
||||||
if (vic_id >= ARRAY_SIZE(vic_devices))
|
|
||||||
printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
|
|
||||||
else {
|
|
||||||
v = &vic_devices[vic_id];
|
|
||||||
v->base = base;
|
|
||||||
v->resume_sources = resume_sources;
|
|
||||||
v->irq = irq;
|
|
||||||
vic_id++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vic_pm_init - initicall to register VIC pm
|
* vic_pm_init - initicall to register VIC pm
|
||||||
*
|
*
|
||||||
|
@ -219,9 +174,60 @@ static int __init vic_pm_init(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
late_initcall(vic_pm_init);
|
late_initcall(vic_pm_init);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vic_pm_register - Register a VIC for later power management control
|
||||||
|
* @base: The base address of the VIC.
|
||||||
|
* @irq: The base IRQ for the VIC.
|
||||||
|
* @resume_sources: bitmask of interrupts allowed for resume sources.
|
||||||
|
*
|
||||||
|
* Register the VIC with the system device tree so that it can be notified
|
||||||
|
* of suspend and resume requests and ensure that the correct actions are
|
||||||
|
* taken to re-instate the settings on resume.
|
||||||
|
*/
|
||||||
|
static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
|
||||||
|
{
|
||||||
|
struct vic_device *v;
|
||||||
|
|
||||||
|
if (vic_id >= ARRAY_SIZE(vic_devices))
|
||||||
|
printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
|
||||||
|
else {
|
||||||
|
v = &vic_devices[vic_id];
|
||||||
|
v->base = base;
|
||||||
|
v->resume_sources = resume_sources;
|
||||||
|
v->irq = irq;
|
||||||
|
vic_id++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
|
||||||
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
|
static void vic_ack_irq(unsigned int irq)
|
||||||
|
{
|
||||||
|
void __iomem *base = get_irq_chip_data(irq);
|
||||||
|
irq &= 31;
|
||||||
|
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
|
||||||
|
/* moreover, clear the soft-triggered, in case it was the reason */
|
||||||
|
writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vic_mask_irq(unsigned int irq)
|
||||||
|
{
|
||||||
|
void __iomem *base = get_irq_chip_data(irq);
|
||||||
|
irq &= 31;
|
||||||
|
writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vic_unmask_irq(unsigned int irq)
|
||||||
|
{
|
||||||
|
void __iomem *base = get_irq_chip_data(irq);
|
||||||
|
irq &= 31;
|
||||||
|
writel(1 << irq, base + VIC_INT_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_PM)
|
||||||
static struct vic_device *vic_from_irq(unsigned int irq)
|
static struct vic_device *vic_from_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
struct vic_device *v = vic_devices;
|
struct vic_device *v = vic_devices;
|
||||||
|
@ -255,10 +261,7 @@ static int vic_set_wake(unsigned int irq, unsigned int on)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
|
|
||||||
|
|
||||||
#define vic_set_wake NULL
|
#define vic_set_wake NULL
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
|
@ -270,80 +273,6 @@ static struct irq_chip vic_chip = {
|
||||||
.set_wake = vic_set_wake,
|
.set_wake = vic_set_wake,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The PL190 cell from ARM has been modified by ST, so handle both here */
|
|
||||||
static void vik_init_st(void __iomem *base, unsigned int irq_start,
|
|
||||||
u32 vic_sources);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vic_init - initialise a vectored interrupt controller
|
|
||||||
* @base: iomem base address
|
|
||||||
* @irq_start: starting interrupt number, must be muliple of 32
|
|
||||||
* @vic_sources: bitmask of interrupt sources to allow
|
|
||||||
* @resume_sources: bitmask of interrupt sources to allow for resume
|
|
||||||
*/
|
|
||||||
void __init vic_init(void __iomem *base, unsigned int irq_start,
|
|
||||||
u32 vic_sources, u32 resume_sources)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
u32 cellid = 0;
|
|
||||||
enum amba_vendor vendor;
|
|
||||||
|
|
||||||
/* Identify which VIC cell this one is, by reading the ID */
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4);
|
|
||||||
cellid |= (readl(addr) & 0xff) << (8 * i);
|
|
||||||
}
|
|
||||||
vendor = (cellid >> 12) & 0xff;
|
|
||||||
printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n",
|
|
||||||
base, cellid, vendor);
|
|
||||||
|
|
||||||
switch(vendor) {
|
|
||||||
case AMBA_VENDOR_ST:
|
|
||||||
vik_init_st(base, irq_start, vic_sources);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
|
|
||||||
/* fall through */
|
|
||||||
case AMBA_VENDOR_ARM:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable all interrupts initially. */
|
|
||||||
|
|
||||||
writel(0, base + VIC_INT_SELECT);
|
|
||||||
writel(0, base + VIC_INT_ENABLE);
|
|
||||||
writel(~0, base + VIC_INT_ENABLE_CLEAR);
|
|
||||||
writel(0, base + VIC_IRQ_STATUS);
|
|
||||||
writel(0, base + VIC_ITCR);
|
|
||||||
writel(~0, base + VIC_INT_SOFT_CLEAR);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure we clear all existing interrupts
|
|
||||||
*/
|
|
||||||
writel(0, base + VIC_PL190_VECT_ADDR);
|
|
||||||
for (i = 0; i < 19; i++) {
|
|
||||||
unsigned int value;
|
|
||||||
|
|
||||||
value = readl(base + VIC_PL190_VECT_ADDR);
|
|
||||||
writel(value, base + VIC_PL190_VECT_ADDR);
|
|
||||||
}
|
|
||||||
|
|
||||||
vic_init2(base);
|
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
|
||||||
if (vic_sources & (1 << i)) {
|
|
||||||
unsigned int irq = irq_start + i;
|
|
||||||
|
|
||||||
set_irq_chip(irq, &vic_chip);
|
|
||||||
set_irq_chip_data(irq, base);
|
|
||||||
set_irq_handler(irq, handle_level_irq);
|
|
||||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vic_pm_register(base, irq_start, resume_sources);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
|
* The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
|
||||||
* The original cell has 32 interrupts, while the modified one has 64,
|
* The original cell has 32 interrupts, while the modified one has 64,
|
||||||
|
@ -351,7 +280,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
|
||||||
* the probe function is called twice, with base set to offset 000
|
* the probe function is called twice, with base set to offset 000
|
||||||
* and 020 within the page. We call this "second block".
|
* and 020 within the page. We call this "second block".
|
||||||
*/
|
*/
|
||||||
static void __init vik_init_st(void __iomem *base, unsigned int irq_start,
|
static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
|
||||||
u32 vic_sources)
|
u32 vic_sources)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -400,3 +329,73 @@ static void __init vik_init_st(void __iomem *base, unsigned int irq_start,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vic_init - initialise a vectored interrupt controller
|
||||||
|
* @base: iomem base address
|
||||||
|
* @irq_start: starting interrupt number, must be muliple of 32
|
||||||
|
* @vic_sources: bitmask of interrupt sources to allow
|
||||||
|
* @resume_sources: bitmask of interrupt sources to allow for resume
|
||||||
|
*/
|
||||||
|
void __init vic_init(void __iomem *base, unsigned int irq_start,
|
||||||
|
u32 vic_sources, u32 resume_sources)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
u32 cellid = 0;
|
||||||
|
enum amba_vendor vendor;
|
||||||
|
|
||||||
|
/* Identify which VIC cell this one is, by reading the ID */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4);
|
||||||
|
cellid |= (readl(addr) & 0xff) << (8 * i);
|
||||||
|
}
|
||||||
|
vendor = (cellid >> 12) & 0xff;
|
||||||
|
printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n",
|
||||||
|
base, cellid, vendor);
|
||||||
|
|
||||||
|
switch(vendor) {
|
||||||
|
case AMBA_VENDOR_ST:
|
||||||
|
vic_init_st(base, irq_start, vic_sources);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
|
||||||
|
/* fall through */
|
||||||
|
case AMBA_VENDOR_ARM:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable all interrupts initially. */
|
||||||
|
|
||||||
|
writel(0, base + VIC_INT_SELECT);
|
||||||
|
writel(0, base + VIC_INT_ENABLE);
|
||||||
|
writel(~0, base + VIC_INT_ENABLE_CLEAR);
|
||||||
|
writel(0, base + VIC_IRQ_STATUS);
|
||||||
|
writel(0, base + VIC_ITCR);
|
||||||
|
writel(~0, base + VIC_INT_SOFT_CLEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure we clear all existing interrupts
|
||||||
|
*/
|
||||||
|
writel(0, base + VIC_PL190_VECT_ADDR);
|
||||||
|
for (i = 0; i < 19; i++) {
|
||||||
|
unsigned int value;
|
||||||
|
|
||||||
|
value = readl(base + VIC_PL190_VECT_ADDR);
|
||||||
|
writel(value, base + VIC_PL190_VECT_ADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
vic_init2(base);
|
||||||
|
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
if (vic_sources & (1 << i)) {
|
||||||
|
unsigned int irq = irq_start + i;
|
||||||
|
|
||||||
|
set_irq_chip(irq, &vic_chip);
|
||||||
|
set_irq_chip_data(irq, base);
|
||||||
|
set_irq_handler(irq, handle_level_irq);
|
||||||
|
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vic_pm_register(base, irq_start, resume_sources);
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -242,10 +242,13 @@ CONFIG_CPU_CP15_MMU=y
|
||||||
# CONFIG_CPU_DCACHE_DISABLE is not set
|
# CONFIG_CPU_DCACHE_DISABLE is not set
|
||||||
# CONFIG_CPU_BPREDICT_DISABLE is not set
|
# CONFIG_CPU_BPREDICT_DISABLE is not set
|
||||||
CONFIG_HAS_TLS_REG=y
|
CONFIG_HAS_TLS_REG=y
|
||||||
|
CONFIG_OUTER_CACHE=y
|
||||||
|
CONFIG_CACHE_L2X0=y
|
||||||
CONFIG_ARM_L1_CACHE_SHIFT=5
|
CONFIG_ARM_L1_CACHE_SHIFT=5
|
||||||
# CONFIG_ARM_ERRATA_430973 is not set
|
# CONFIG_ARM_ERRATA_430973 is not set
|
||||||
# CONFIG_ARM_ERRATA_458693 is not set
|
# CONFIG_ARM_ERRATA_458693 is not set
|
||||||
# CONFIG_ARM_ERRATA_460075 is not set
|
# CONFIG_ARM_ERRATA_460075 is not set
|
||||||
|
CONFIG_PL310_ERRATA_588369=y
|
||||||
CONFIG_ARM_GIC=y
|
CONFIG_ARM_GIC=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -235,6 +235,234 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
|
||||||
#define smp_mb__before_atomic_inc() smp_mb()
|
#define smp_mb__before_atomic_inc() smp_mb()
|
||||||
#define smp_mb__after_atomic_inc() smp_mb()
|
#define smp_mb__after_atomic_inc() smp_mb()
|
||||||
|
|
||||||
|
#ifndef CONFIG_GENERIC_ATOMIC64
|
||||||
|
typedef struct {
|
||||||
|
u64 __aligned(8) counter;
|
||||||
|
} atomic64_t;
|
||||||
|
|
||||||
|
#define ATOMIC64_INIT(i) { (i) }
|
||||||
|
|
||||||
|
static inline u64 atomic64_read(atomic64_t *v)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_read\n"
|
||||||
|
" ldrexd %0, %H0, [%1]"
|
||||||
|
: "=&r" (result)
|
||||||
|
: "r" (&v->counter)
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void atomic64_set(atomic64_t *v, u64 i)
|
||||||
|
{
|
||||||
|
u64 tmp;
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_set\n"
|
||||||
|
"1: ldrexd %0, %H0, [%1]\n"
|
||||||
|
" strexd %0, %2, %H2, [%1]\n"
|
||||||
|
" teq %0, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "r" (i)
|
||||||
|
: "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void atomic64_add(u64 i, atomic64_t *v)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_add\n"
|
||||||
|
"1: ldrexd %0, %H0, [%2]\n"
|
||||||
|
" adds %0, %0, %3\n"
|
||||||
|
" adc %H0, %H0, %H3\n"
|
||||||
|
" strexd %1, %0, %H0, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (result), "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "r" (i)
|
||||||
|
: "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_add_return\n"
|
||||||
|
"1: ldrexd %0, %H0, [%2]\n"
|
||||||
|
" adds %0, %0, %3\n"
|
||||||
|
" adc %H0, %H0, %H3\n"
|
||||||
|
" strexd %1, %0, %H0, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (result), "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "r" (i)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void atomic64_sub(u64 i, atomic64_t *v)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_sub\n"
|
||||||
|
"1: ldrexd %0, %H0, [%2]\n"
|
||||||
|
" subs %0, %0, %3\n"
|
||||||
|
" sbc %H0, %H0, %H3\n"
|
||||||
|
" strexd %1, %0, %H0, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (result), "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "r" (i)
|
||||||
|
: "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_sub_return\n"
|
||||||
|
"1: ldrexd %0, %H0, [%2]\n"
|
||||||
|
" subs %0, %0, %3\n"
|
||||||
|
" sbc %H0, %H0, %H3\n"
|
||||||
|
" strexd %1, %0, %H0, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (result), "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "r" (i)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
|
||||||
|
{
|
||||||
|
u64 oldval;
|
||||||
|
unsigned long res;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
do {
|
||||||
|
__asm__ __volatile__("@ atomic64_cmpxchg\n"
|
||||||
|
"ldrexd %1, %H1, [%2]\n"
|
||||||
|
"mov %0, #0\n"
|
||||||
|
"teq %1, %3\n"
|
||||||
|
"teqeq %H1, %H3\n"
|
||||||
|
"strexdeq %0, %4, %H4, [%2]"
|
||||||
|
: "=&r" (res), "=&r" (oldval)
|
||||||
|
: "r" (&ptr->counter), "r" (old), "r" (new)
|
||||||
|
: "cc");
|
||||||
|
} while (res);
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
return oldval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_xchg\n"
|
||||||
|
"1: ldrexd %0, %H0, [%2]\n"
|
||||||
|
" strexd %1, %3, %H3, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b"
|
||||||
|
: "=&r" (result), "=&r" (tmp)
|
||||||
|
: "r" (&ptr->counter), "r" (new)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 atomic64_dec_if_positive(atomic64_t *v)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_dec_if_positive\n"
|
||||||
|
"1: ldrexd %0, %H0, [%2]\n"
|
||||||
|
" subs %0, %0, #1\n"
|
||||||
|
" sbc %H0, %H0, #0\n"
|
||||||
|
" teq %H0, #0\n"
|
||||||
|
" bmi 2f\n"
|
||||||
|
" strexd %1, %0, %H0, [%2]\n"
|
||||||
|
" teq %1, #0\n"
|
||||||
|
" bne 1b\n"
|
||||||
|
"2:"
|
||||||
|
: "=&r" (result), "=&r" (tmp)
|
||||||
|
: "r" (&v->counter)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
|
||||||
|
{
|
||||||
|
u64 val;
|
||||||
|
unsigned long tmp;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
__asm__ __volatile__("@ atomic64_add_unless\n"
|
||||||
|
"1: ldrexd %0, %H0, [%3]\n"
|
||||||
|
" teq %0, %4\n"
|
||||||
|
" teqeq %H0, %H4\n"
|
||||||
|
" moveq %1, #0\n"
|
||||||
|
" beq 2f\n"
|
||||||
|
" adds %0, %0, %5\n"
|
||||||
|
" adc %H0, %H0, %H5\n"
|
||||||
|
" strexd %2, %0, %H0, [%3]\n"
|
||||||
|
" teq %2, #0\n"
|
||||||
|
" bne 1b\n"
|
||||||
|
"2:"
|
||||||
|
: "=&r" (val), "=&r" (ret), "=&r" (tmp)
|
||||||
|
: "r" (&v->counter), "r" (u), "r" (a)
|
||||||
|
: "cc");
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
|
||||||
|
#define atomic64_inc(v) atomic64_add(1LL, (v))
|
||||||
|
#define atomic64_inc_return(v) atomic64_add_return(1LL, (v))
|
||||||
|
#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
|
||||||
|
#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
|
||||||
|
#define atomic64_dec(v) atomic64_sub(1LL, (v))
|
||||||
|
#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v))
|
||||||
|
#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
|
||||||
|
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
|
||||||
|
|
||||||
|
#else /* !CONFIG_GENERIC_ATOMIC64 */
|
||||||
|
#include <asm-generic/atomic64.h>
|
||||||
|
#endif
|
||||||
#include <asm-generic/atomic-long.h>
|
#include <asm-generic/atomic-long.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -197,21 +197,6 @@
|
||||||
* DMA Cache Coherency
|
* DMA Cache Coherency
|
||||||
* ===================
|
* ===================
|
||||||
*
|
*
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* dma_clean_range(start, end)
|
|
||||||
*
|
|
||||||
* Clean (write back) the specified virtual address range.
|
|
||||||
* - start - virtual start address
|
|
||||||
* - end - virtual end address
|
|
||||||
*
|
|
||||||
* dma_flush_range(start, end)
|
* dma_flush_range(start, end)
|
||||||
*
|
*
|
||||||
* Clean and invalidate the specified virtual address range.
|
* Clean and invalidate the specified virtual address range.
|
||||||
|
@ -228,8 +213,9 @@ struct cpu_cache_fns {
|
||||||
void (*coherent_user_range)(unsigned long, unsigned long);
|
void (*coherent_user_range)(unsigned long, unsigned long);
|
||||||
void (*flush_kern_dcache_area)(void *, size_t);
|
void (*flush_kern_dcache_area)(void *, size_t);
|
||||||
|
|
||||||
void (*dma_inv_range)(const void *, const void *);
|
void (*dma_map_area)(const void *, size_t, int);
|
||||||
void (*dma_clean_range)(const void *, const void *);
|
void (*dma_unmap_area)(const void *, size_t, int);
|
||||||
|
|
||||||
void (*dma_flush_range)(const void *, const void *);
|
void (*dma_flush_range)(const void *, const void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -259,8 +245,8 @@ extern struct cpu_cache_fns cpu_cache;
|
||||||
* is visible to DMA, or data written by DMA to system memory is
|
* is visible to DMA, or data written by DMA to system memory is
|
||||||
* visible to the CPU.
|
* visible to the CPU.
|
||||||
*/
|
*/
|
||||||
#define dmac_inv_range cpu_cache.dma_inv_range
|
#define dmac_map_area cpu_cache.dma_map_area
|
||||||
#define dmac_clean_range cpu_cache.dma_clean_range
|
#define dmac_unmap_area cpu_cache.dma_unmap_area
|
||||||
#define dmac_flush_range cpu_cache.dma_flush_range
|
#define dmac_flush_range cpu_cache.dma_flush_range
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -285,12 +271,12 @@ extern void __cpuc_flush_dcache_area(void *, size_t);
|
||||||
* is visible to DMA, or data written by DMA to system memory is
|
* is visible to DMA, or data written by DMA to system memory is
|
||||||
* visible to the CPU.
|
* visible to the CPU.
|
||||||
*/
|
*/
|
||||||
#define dmac_inv_range __glue(_CACHE,_dma_inv_range)
|
#define dmac_map_area __glue(_CACHE,_dma_map_area)
|
||||||
#define dmac_clean_range __glue(_CACHE,_dma_clean_range)
|
#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
|
||||||
#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
|
#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
|
||||||
|
|
||||||
extern void dmac_inv_range(const void *, const void *);
|
extern void dmac_map_area(const void *, size_t, int);
|
||||||
extern void dmac_clean_range(const void *, const void *);
|
extern void dmac_unmap_area(const void *, size_t, int);
|
||||||
extern void dmac_flush_range(const void *, const void *);
|
extern void dmac_flush_range(const void *, const void *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -331,12 +317,8 @@ static inline void outer_flush_range(unsigned long start, unsigned long end)
|
||||||
* processes address space. Really, we want to allow our "user
|
* processes address space. Really, we want to allow our "user
|
||||||
* space" model to handle this.
|
* space" model to handle this.
|
||||||
*/
|
*/
|
||||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
extern void copy_to_user_page(struct vm_area_struct *, struct page *,
|
||||||
do { \
|
unsigned long, void *, const void *, unsigned long);
|
||||||
memcpy(dst, src, len); \
|
|
||||||
flush_ptrace_access(vma, page, vaddr, dst, len, 1);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||||
do { \
|
do { \
|
||||||
memcpy(dst, src, len); \
|
memcpy(dst, src, len); \
|
||||||
|
@ -370,17 +352,6 @@ vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
vivt_flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
|
|
||||||
unsigned long uaddr, void *kaddr,
|
|
||||||
unsigned long len, int write)
|
|
||||||
{
|
|
||||||
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
|
|
||||||
unsigned long addr = (unsigned long)kaddr;
|
|
||||||
__cpuc_coherent_kern_range(addr, addr + len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CONFIG_CPU_CACHE_VIPT
|
#ifndef CONFIG_CPU_CACHE_VIPT
|
||||||
#define flush_cache_mm(mm) \
|
#define flush_cache_mm(mm) \
|
||||||
vivt_flush_cache_mm(mm)
|
vivt_flush_cache_mm(mm)
|
||||||
|
@ -388,15 +359,10 @@ vivt_flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
|
||||||
vivt_flush_cache_range(vma,start,end)
|
vivt_flush_cache_range(vma,start,end)
|
||||||
#define flush_cache_page(vma,addr,pfn) \
|
#define flush_cache_page(vma,addr,pfn) \
|
||||||
vivt_flush_cache_page(vma,addr,pfn)
|
vivt_flush_cache_page(vma,addr,pfn)
|
||||||
#define flush_ptrace_access(vma,page,ua,ka,len,write) \
|
|
||||||
vivt_flush_ptrace_access(vma,page,ua,ka,len,write)
|
|
||||||
#else
|
#else
|
||||||
extern void flush_cache_mm(struct mm_struct *mm);
|
extern void flush_cache_mm(struct mm_struct *mm);
|
||||||
extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
|
extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
|
||||||
extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
|
extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
|
||||||
extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
|
|
||||||
unsigned long uaddr, void *kaddr,
|
|
||||||
unsigned long len, int write);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
|
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
|
||||||
|
|
|
@ -27,4 +27,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
|
||||||
void clkdev_add(struct clk_lookup *cl);
|
void clkdev_add(struct clk_lookup *cl);
|
||||||
void clkdev_drop(struct clk_lookup *cl);
|
void clkdev_drop(struct clk_lookup *cl);
|
||||||
|
|
||||||
|
void clkdev_add_table(struct clk_lookup *, size_t);
|
||||||
|
int clk_add_alias(const char *, const char *, char *, struct device *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,18 +57,58 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DMA-consistent mapping functions. These allocate/free a region of
|
* The DMA API is built upon the notion of "buffer ownership". A buffer
|
||||||
* uncached, unwrite-buffered mapped memory space for use with DMA
|
* is either exclusively owned by the CPU (and therefore may be accessed
|
||||||
* devices. This is the "generic" version. The PCI specific version
|
* by it) or exclusively owned by the DMA device. These helper functions
|
||||||
* is in pci.h
|
* represent the transitions between these two ownership states.
|
||||||
*
|
*
|
||||||
* Note: Drivers should NOT use this function directly, as it will break
|
* Note, however, that on later ARMs, this notion does not work due to
|
||||||
* platforms with CONFIG_DMABOUNCE.
|
* speculative prefetches. We model our approach on the assumption that
|
||||||
* Use the driver DMA support - see dma-mapping.h (dma_sync_*)
|
* the CPU does do speculative prefetches, which means we clean caches
|
||||||
|
* before transfers and delay cache invalidation until transfer completion.
|
||||||
|
*
|
||||||
|
* Private support functions: these are not part of the API and are
|
||||||
|
* liable to change. Drivers must not use these.
|
||||||
*/
|
*/
|
||||||
extern void dma_cache_maint(const void *kaddr, size_t size, int rw);
|
static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
|
||||||
extern void dma_cache_maint_page(struct page *page, unsigned long offset,
|
enum dma_data_direction dir)
|
||||||
size_t size, int rw);
|
{
|
||||||
|
extern void ___dma_single_cpu_to_dev(const void *, size_t,
|
||||||
|
enum dma_data_direction);
|
||||||
|
|
||||||
|
if (!arch_is_coherent())
|
||||||
|
___dma_single_cpu_to_dev(kaddr, size, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
|
||||||
|
enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
extern void ___dma_single_dev_to_cpu(const void *, size_t,
|
||||||
|
enum dma_data_direction);
|
||||||
|
|
||||||
|
if (!arch_is_coherent())
|
||||||
|
___dma_single_dev_to_cpu(kaddr, size, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
|
||||||
|
size_t size, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
extern void ___dma_page_cpu_to_dev(struct page *, unsigned long,
|
||||||
|
size_t, enum dma_data_direction);
|
||||||
|
|
||||||
|
if (!arch_is_coherent())
|
||||||
|
___dma_page_cpu_to_dev(page, off, size, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
|
||||||
|
size_t size, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
extern void ___dma_page_dev_to_cpu(struct page *, unsigned long,
|
||||||
|
size_t, enum dma_data_direction);
|
||||||
|
|
||||||
|
if (!arch_is_coherent())
|
||||||
|
___dma_page_dev_to_cpu(page, off, size, dir);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return whether the given device DMA address mask can be supported
|
* Return whether the given device DMA address mask can be supported
|
||||||
|
@ -304,8 +344,7 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
|
||||||
{
|
{
|
||||||
BUG_ON(!valid_dma_direction(dir));
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
|
||||||
if (!arch_is_coherent())
|
__dma_single_cpu_to_dev(cpu_addr, size, dir);
|
||||||
dma_cache_maint(cpu_addr, size, dir);
|
|
||||||
|
|
||||||
return virt_to_dma(dev, cpu_addr);
|
return virt_to_dma(dev, cpu_addr);
|
||||||
}
|
}
|
||||||
|
@ -329,8 +368,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
|
||||||
{
|
{
|
||||||
BUG_ON(!valid_dma_direction(dir));
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
|
||||||
if (!arch_is_coherent())
|
__dma_page_cpu_to_dev(page, offset, size, dir);
|
||||||
dma_cache_maint_page(page, offset, size, dir);
|
|
||||||
|
|
||||||
return page_to_dma(dev, page) + offset;
|
return page_to_dma(dev, page) + offset;
|
||||||
}
|
}
|
||||||
|
@ -352,7 +390,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
|
||||||
static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
|
static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
|
||||||
size_t size, enum dma_data_direction dir)
|
size_t size, enum dma_data_direction dir)
|
||||||
{
|
{
|
||||||
/* nothing to do */
|
__dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -372,7 +410,8 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
|
||||||
static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
|
static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
|
||||||
size_t size, enum dma_data_direction dir)
|
size_t size, enum dma_data_direction dir)
|
||||||
{
|
{
|
||||||
/* nothing to do */
|
__dma_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK,
|
||||||
|
size, dir);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DMABOUNCE */
|
#endif /* CONFIG_DMABOUNCE */
|
||||||
|
|
||||||
|
@ -400,7 +439,10 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
|
||||||
{
|
{
|
||||||
BUG_ON(!valid_dma_direction(dir));
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
|
||||||
dmabounce_sync_for_cpu(dev, handle, offset, size, dir);
|
if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
|
||||||
|
return;
|
||||||
|
|
||||||
|
__dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dma_sync_single_range_for_device(struct device *dev,
|
static inline void dma_sync_single_range_for_device(struct device *dev,
|
||||||
|
@ -412,8 +454,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
|
||||||
if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
|
if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!arch_is_coherent())
|
__dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir);
|
||||||
dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dma_sync_single_for_cpu(struct device *dev,
|
static inline void dma_sync_single_for_cpu(struct device *dev,
|
||||||
|
|
|
@ -69,9 +69,16 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
|
||||||
/*
|
/*
|
||||||
* __arm_ioremap takes CPU physical address.
|
* __arm_ioremap takes CPU physical address.
|
||||||
* __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
|
* __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
|
||||||
|
* The _caller variety takes a __builtin_return_address(0) value for
|
||||||
|
* /proc/vmalloc to use - and should only be used in non-inline functions.
|
||||||
*/
|
*/
|
||||||
extern void __iomem * __arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
|
extern void __iomem *__arm_ioremap_pfn_caller(unsigned long, unsigned long,
|
||||||
extern void __iomem * __arm_ioremap(unsigned long, size_t, unsigned int);
|
size_t, unsigned int, void *);
|
||||||
|
extern void __iomem *__arm_ioremap_caller(unsigned long, size_t, unsigned int,
|
||||||
|
void *);
|
||||||
|
|
||||||
|
extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
|
||||||
|
extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int);
|
||||||
extern void __iounmap(volatile void __iomem *addr);
|
extern void __iounmap(volatile void __iomem *addr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -46,12 +46,4 @@ struct sys_timer {
|
||||||
extern struct sys_timer *system_timer;
|
extern struct sys_timer *system_timer;
|
||||||
extern void timer_tick(void);
|
extern void timer_tick(void);
|
||||||
|
|
||||||
/*
|
|
||||||
* Kernel time keeping support.
|
|
||||||
*/
|
|
||||||
struct timespec;
|
|
||||||
extern int (*set_rtc)(void);
|
|
||||||
extern void save_time_delta(struct timespec *delta, struct timespec *rtc);
|
|
||||||
extern void restore_time_delta(struct timespec *delta, struct timespec *rtc);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,6 +76,17 @@
|
||||||
*/
|
*/
|
||||||
#define IOREMAP_MAX_ORDER 24
|
#define IOREMAP_MAX_ORDER 24
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Size of DMA-consistent memory region. Must be multiple of 2M,
|
||||||
|
* between 2MB and 14MB inclusive.
|
||||||
|
*/
|
||||||
|
#ifndef CONSISTENT_DMA_SIZE
|
||||||
|
#define CONSISTENT_DMA_SIZE SZ_2M
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONSISTENT_END (0xffe00000UL)
|
||||||
|
#define CONSISTENT_BASE (CONSISTENT_END - CONSISTENT_DMA_SIZE)
|
||||||
|
|
||||||
#else /* CONFIG_MMU */
|
#else /* CONFIG_MMU */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -93,11 +104,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PHYS_OFFSET
|
#ifndef PHYS_OFFSET
|
||||||
#define PHYS_OFFSET (CONFIG_DRAM_BASE)
|
#define PHYS_OFFSET UL(CONFIG_DRAM_BASE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef END_MEM
|
#ifndef END_MEM
|
||||||
#define END_MEM (CONFIG_DRAM_BASE + CONFIG_DRAM_SIZE)
|
#define END_MEM (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PAGE_OFFSET
|
#ifndef PAGE_OFFSET
|
||||||
|
@ -112,14 +123,6 @@
|
||||||
|
|
||||||
#endif /* !CONFIG_MMU */
|
#endif /* !CONFIG_MMU */
|
||||||
|
|
||||||
/*
|
|
||||||
* Size of DMA-consistent memory region. Must be multiple of 2M,
|
|
||||||
* between 2MB and 14MB inclusive.
|
|
||||||
*/
|
|
||||||
#ifndef CONSISTENT_DMA_SIZE
|
|
||||||
#define CONSISTENT_DMA_SIZE SZ_2M
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Physical vs virtual RAM address space conversion. These are
|
* Physical vs virtual RAM address space conversion. These are
|
||||||
* private definitions which should NOT be used outside memory.h
|
* private definitions which should NOT be used outside memory.h
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
#ifdef CONFIG_CPU_HAS_ASID
|
#ifdef CONFIG_CPU_HAS_ASID
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
spinlock_t id_lock;
|
||||||
#endif
|
#endif
|
||||||
unsigned int kvm_seq;
|
unsigned int kvm_seq;
|
||||||
} mm_context_t;
|
} mm_context_t;
|
||||||
|
|
|
@ -43,12 +43,23 @@ void __check_kvm_seq(struct mm_struct *mm);
|
||||||
#define ASID_FIRST_VERSION (1 << ASID_BITS)
|
#define ASID_FIRST_VERSION (1 << ASID_BITS)
|
||||||
|
|
||||||
extern unsigned int cpu_last_asid;
|
extern unsigned int cpu_last_asid;
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
DECLARE_PER_CPU(struct mm_struct *, current_mm);
|
||||||
|
#endif
|
||||||
|
|
||||||
void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
|
void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
|
||||||
void __new_context(struct mm_struct *mm);
|
void __new_context(struct mm_struct *mm);
|
||||||
|
|
||||||
static inline void check_context(struct mm_struct *mm)
|
static inline void check_context(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This code is executed with interrupts enabled. Therefore,
|
||||||
|
* mm->context.id cannot be updated to the latest ASID version
|
||||||
|
* on a different CPU (and condition below not triggered)
|
||||||
|
* without first getting an IPI to reset the context. The
|
||||||
|
* alternative is to take a read_lock on mm->context.id_lock
|
||||||
|
* (after changing its type to rwlock_t).
|
||||||
|
*/
|
||||||
if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS))
|
if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS))
|
||||||
__new_context(mm);
|
__new_context(mm);
|
||||||
|
|
||||||
|
@ -108,6 +119,10 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||||
__flush_icache_all();
|
__flush_icache_all();
|
||||||
#endif
|
#endif
|
||||||
if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
|
if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
struct mm_struct **crt_mm = &per_cpu(current_mm, cpu);
|
||||||
|
*crt_mm = next;
|
||||||
|
#endif
|
||||||
check_context(next);
|
check_context(next);
|
||||||
cpu_switch_mm(next->pgd, next);
|
cpu_switch_mm(next->pgd, next);
|
||||||
if (cache_is_vivt())
|
if (cache_is_vivt())
|
||||||
|
|
|
@ -117,11 +117,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct page;
|
struct page;
|
||||||
|
struct vm_area_struct;
|
||||||
|
|
||||||
struct cpu_user_fns {
|
struct cpu_user_fns {
|
||||||
void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
|
void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
|
||||||
void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
|
void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
|
||||||
unsigned long vaddr);
|
unsigned long vaddr, struct vm_area_struct *vma);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef MULTI_USER
|
#ifdef MULTI_USER
|
||||||
|
@ -137,7 +138,7 @@ extern struct cpu_user_fns cpu_user;
|
||||||
|
|
||||||
extern void __cpu_clear_user_highpage(struct page *page, unsigned long vaddr);
|
extern void __cpu_clear_user_highpage(struct page *page, unsigned long vaddr);
|
||||||
extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
|
extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
|
||||||
unsigned long vaddr);
|
unsigned long vaddr, struct vm_area_struct *vma);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define clear_user_highpage(page,vaddr) \
|
#define clear_user_highpage(page,vaddr) \
|
||||||
|
@ -145,7 +146,7 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
|
||||||
|
|
||||||
#define __HAVE_ARCH_COPY_USER_HIGHPAGE
|
#define __HAVE_ARCH_COPY_USER_HIGHPAGE
|
||||||
#define copy_user_highpage(to,from,vaddr,vma) \
|
#define copy_user_highpage(to,from,vaddr,vma) \
|
||||||
__cpu_copy_user_highpage(to, from, vaddr)
|
__cpu_copy_user_highpage(to, from, vaddr, vma)
|
||||||
|
|
||||||
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
|
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
|
||||||
extern void copy_page(void *to, const void *from);
|
extern void copy_page(void *to, const void *from);
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/include/asm/perf_event.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
|
||||||
|
*
|
||||||
|
* 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 __ARM_PERF_EVENT_H__
|
||||||
|
#define __ARM_PERF_EVENT_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOP: on *most* (read: all supported) ARM platforms, the performance
|
||||||
|
* counter interrupts are regular interrupts and not an NMI. This
|
||||||
|
* means that when we receive the interrupt we can call
|
||||||
|
* perf_event_do_pending() that handles all of the work with
|
||||||
|
* interrupts enabled.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
set_perf_event_pending(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARM performance counters start from 1 (in the cp15 accesses) so use the
|
||||||
|
* same indexes here for consistency. */
|
||||||
|
#define PERF_EVENT_INDEX_OFFSET 1
|
||||||
|
|
||||||
|
#endif /* __ARM_PERF_EVENT_H__ */
|
|
@ -86,8 +86,8 @@ extern unsigned int kobjsize(const void *objp);
|
||||||
* All 32bit addresses are effectively valid for vmalloc...
|
* All 32bit addresses are effectively valid for vmalloc...
|
||||||
* Sort of meaningless for non-VM targets.
|
* Sort of meaningless for non-VM targets.
|
||||||
*/
|
*/
|
||||||
#define VMALLOC_START 0
|
#define VMALLOC_START 0UL
|
||||||
#define VMALLOC_END 0xffffffff
|
#define VMALLOC_END 0xffffffffUL
|
||||||
|
|
||||||
#define FIRST_USER_ADDRESS (0)
|
#define FIRST_USER_ADDRESS (0)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/include/asm/pmu.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
|
||||||
|
*
|
||||||
|
* 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 __ARM_PMU_H__
|
||||||
|
#define __ARM_PMU_H__
|
||||||
|
|
||||||
|
#ifdef CONFIG_CPU_HAS_PMU
|
||||||
|
|
||||||
|
struct pmu_irqs {
|
||||||
|
const int *irqs;
|
||||||
|
int num_irqs;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reserve_pmu() - reserve the hardware performance counters
|
||||||
|
*
|
||||||
|
* Reserve the hardware performance counters in the system for exclusive use.
|
||||||
|
* The 'struct pmu_irqs' for the system is returned on success, ERR_PTR()
|
||||||
|
* encoded error on failure.
|
||||||
|
*/
|
||||||
|
extern const struct pmu_irqs *
|
||||||
|
reserve_pmu(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* release_pmu() - Relinquish control of the performance counters
|
||||||
|
*
|
||||||
|
* Release the performance counters and allow someone else to use them.
|
||||||
|
* Callers must have disabled the counters and released IRQs before calling
|
||||||
|
* this. The 'struct pmu_irqs' returned from reserve_pmu() must be passed as
|
||||||
|
* a cookie.
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
release_pmu(const struct pmu_irqs *irqs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init_pmu() - Initialise the PMU.
|
||||||
|
*
|
||||||
|
* Initialise the system ready for PMU enabling. This should typically set the
|
||||||
|
* IRQ affinity and nothing else. The users (oprofile/perf events etc) will do
|
||||||
|
* the actual hardware initialisation.
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
init_pmu(void);
|
||||||
|
|
||||||
|
#else /* CONFIG_CPU_HAS_PMU */
|
||||||
|
|
||||||
|
static inline const struct pmu_irqs *
|
||||||
|
reserve_pmu(void)
|
||||||
|
{
|
||||||
|
return ERR_PTR(-ENODEV);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
release_pmu(const struct pmu_irqs *irqs)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
init_pmu(void)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_CPU_HAS_PMU */
|
||||||
|
|
||||||
|
#endif /* __ARM_PMU_H__ */
|
|
@ -223,18 +223,6 @@ extern struct meminfo meminfo;
|
||||||
#define bank_phys_end(bank) ((bank)->start + (bank)->size)
|
#define bank_phys_end(bank) ((bank)->start + (bank)->size)
|
||||||
#define bank_phys_size(bank) (bank)->size
|
#define bank_phys_size(bank) (bank)->size
|
||||||
|
|
||||||
/*
|
|
||||||
* Early command line parameters.
|
|
||||||
*/
|
|
||||||
struct early_params {
|
|
||||||
const char *arg;
|
|
||||||
void (*fn)(char **p);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define __early_param(name,fn) \
|
|
||||||
static struct early_params __early_##fn __used \
|
|
||||||
__attribute__((__section__(".early_param.init"))) = { name, fn }
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,4 +13,9 @@ static inline int tlb_ops_need_broadcast(void)
|
||||||
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
|
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int cache_ops_need_broadcast(void)
|
||||||
|
{
|
||||||
|
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,6 +5,22 @@
|
||||||
#error SMP not supported on pre-ARMv6 CPUs
|
#error SMP not supported on pre-ARMv6 CPUs
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void dsb_sev(void)
|
||||||
|
{
|
||||||
|
#if __LINUX_ARM_ARCH__ >= 7
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"dsb\n"
|
||||||
|
"sev"
|
||||||
|
);
|
||||||
|
#elif defined(CONFIG_CPU_32v6K)
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"mcr p15, 0, %0, c7, c10, 4\n"
|
||||||
|
"sev"
|
||||||
|
: : "r" (0)
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ARMv6 Spin-locking.
|
* ARMv6 Spin-locking.
|
||||||
*
|
*
|
||||||
|
@ -69,13 +85,11 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" str %1, [%0]\n"
|
" str %1, [%0]\n"
|
||||||
#ifdef CONFIG_CPU_32v6K
|
|
||||||
" mcr p15, 0, %1, c7, c10, 4\n" /* DSB */
|
|
||||||
" sev"
|
|
||||||
#endif
|
|
||||||
:
|
:
|
||||||
: "r" (&lock->lock), "r" (0)
|
: "r" (&lock->lock), "r" (0)
|
||||||
: "cc");
|
: "cc");
|
||||||
|
|
||||||
|
dsb_sev();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -132,13 +146,11 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"str %1, [%0]\n"
|
"str %1, [%0]\n"
|
||||||
#ifdef CONFIG_CPU_32v6K
|
|
||||||
" mcr p15, 0, %1, c7, c10, 4\n" /* DSB */
|
|
||||||
" sev\n"
|
|
||||||
#endif
|
|
||||||
:
|
:
|
||||||
: "r" (&rw->lock), "r" (0)
|
: "r" (&rw->lock), "r" (0)
|
||||||
: "cc");
|
: "cc");
|
||||||
|
|
||||||
|
dsb_sev();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write_can_lock - would write_trylock() succeed? */
|
/* write_can_lock - would write_trylock() succeed? */
|
||||||
|
@ -188,14 +200,12 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
|
||||||
" strex %1, %0, [%2]\n"
|
" strex %1, %0, [%2]\n"
|
||||||
" teq %1, #0\n"
|
" teq %1, #0\n"
|
||||||
" bne 1b"
|
" bne 1b"
|
||||||
#ifdef CONFIG_CPU_32v6K
|
|
||||||
"\n cmp %0, #0\n"
|
|
||||||
" mcreq p15, 0, %0, c7, c10, 4\n"
|
|
||||||
" seveq"
|
|
||||||
#endif
|
|
||||||
: "=&r" (tmp), "=&r" (tmp2)
|
: "=&r" (tmp), "=&r" (tmp2)
|
||||||
: "r" (&rw->lock)
|
: "r" (&rw->lock)
|
||||||
: "cc");
|
: "cc");
|
||||||
|
|
||||||
|
if (tmp == 0)
|
||||||
|
dsb_sev();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int arch_read_trylock(arch_rwlock_t *rw)
|
static inline int arch_read_trylock(arch_rwlock_t *rw)
|
||||||
|
|
|
@ -73,8 +73,7 @@ extern unsigned int mem_fclk_21285;
|
||||||
|
|
||||||
struct pt_regs;
|
struct pt_regs;
|
||||||
|
|
||||||
void die(const char *msg, struct pt_regs *regs, int err)
|
void die(const char *msg, struct pt_regs *regs, int err);
|
||||||
__attribute__((noreturn));
|
|
||||||
|
|
||||||
struct siginfo;
|
struct siginfo;
|
||||||
void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
|
void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
|
||||||
|
|
|
@ -115,7 +115,8 @@ extern void iwmmxt_task_restore(struct thread_info *, void *);
|
||||||
extern void iwmmxt_task_release(struct thread_info *);
|
extern void iwmmxt_task_release(struct thread_info *);
|
||||||
extern void iwmmxt_task_switch(struct thread_info *);
|
extern void iwmmxt_task_switch(struct thread_info *);
|
||||||
|
|
||||||
extern void vfp_sync_state(struct thread_info *thread);
|
extern void vfp_sync_hwstate(struct thread_info *);
|
||||||
|
extern void vfp_flush_hwstate(struct thread_info *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -529,7 +529,8 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||||
* cache entries for the kernels virtual memory range are written
|
* cache entries for the kernels virtual memory range are written
|
||||||
* back to the page.
|
* back to the page.
|
||||||
*/
|
*/
|
||||||
extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
|
extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
|
||||||
|
pte_t *ptep);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \
|
||||||
process.o ptrace.o return_address.o setup.o signal.o \
|
process.o ptrace.o return_address.o setup.o signal.o \
|
||||||
sys_arm.o stacktrace.o time.o traps.o
|
sys_arm.o stacktrace.o time.o traps.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_LEDS) += leds.o
|
||||||
obj-$(CONFIG_OC_ETM) += etm.o
|
obj-$(CONFIG_OC_ETM) += etm.o
|
||||||
|
|
||||||
obj-$(CONFIG_ISA_DMA_API) += dma.o
|
obj-$(CONFIG_ISA_DMA_API) += dma.o
|
||||||
|
@ -46,6 +47,8 @@ obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
|
||||||
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
|
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
|
||||||
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
|
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
|
||||||
obj-$(CONFIG_IWMMXT) += iwmmxt.o
|
obj-$(CONFIG_IWMMXT) += iwmmxt.o
|
||||||
|
obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
|
||||||
|
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
|
||||||
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
|
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
|
||||||
|
|
||||||
ifneq ($(CONFIG_ARCH_EBSA110),y)
|
ifneq ($(CONFIG_ARCH_EBSA110),y)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/thread_info.h>
|
#include <asm/thread_info.h>
|
||||||
#include <asm/memory.h>
|
#include <asm/memory.h>
|
||||||
|
@ -112,5 +113,9 @@ int main(void)
|
||||||
#ifdef MULTI_PABORT
|
#ifdef MULTI_PABORT
|
||||||
DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
|
DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
|
||||||
#endif
|
#endif
|
||||||
|
BLANK();
|
||||||
|
DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
|
||||||
|
DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
|
||||||
|
DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#if defined(CONFIG_CPU_V6)
|
#if defined(CONFIG_CPU_V6)
|
||||||
|
|
||||||
.macro addruart, rx
|
.macro addruart, rx, tmp
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro senduart, rd, rx
|
.macro senduart, rd, rx
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
|
|
||||||
#elif defined(CONFIG_CPU_V7)
|
#elif defined(CONFIG_CPU_V7)
|
||||||
|
|
||||||
.macro addruart, rx
|
.macro addruart, rx, tmp
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro senduart, rd, rx
|
.macro senduart, rd, rx
|
||||||
|
@ -71,7 +71,7 @@ wait: mrc p14, 0, pc, c0, c1, 0
|
||||||
|
|
||||||
#elif defined(CONFIG_CPU_XSCALE)
|
#elif defined(CONFIG_CPU_XSCALE)
|
||||||
|
|
||||||
.macro addruart, rx
|
.macro addruart, rx, tmp
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro senduart, rd, rx
|
.macro senduart, rd, rx
|
||||||
|
@ -98,7 +98,7 @@ wait: mrc p14, 0, pc, c0, c1, 0
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
.macro addruart, rx
|
.macro addruart, rx, tmp
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro senduart, rd, rx
|
.macro senduart, rd, rx
|
||||||
|
@ -164,7 +164,7 @@ ENDPROC(printhex2)
|
||||||
.ltorg
|
.ltorg
|
||||||
|
|
||||||
ENTRY(printascii)
|
ENTRY(printascii)
|
||||||
addruart r3
|
addruart r3, r1
|
||||||
b 2f
|
b 2f
|
||||||
1: waituart r2, r3
|
1: waituart r2, r3
|
||||||
senduart r1, r3
|
senduart r1, r3
|
||||||
|
@ -180,7 +180,7 @@ ENTRY(printascii)
|
||||||
ENDPROC(printascii)
|
ENDPROC(printascii)
|
||||||
|
|
||||||
ENTRY(printch)
|
ENTRY(printch)
|
||||||
addruart r3
|
addruart r3, r1
|
||||||
mov r1, r0
|
mov r1, r0
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
b 1b
|
b 1b
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* LED support code, ripped out of arch/arm/kernel/time.c
|
||||||
|
*
|
||||||
|
* Copyright (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.
|
||||||
|
*/
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/sysdev.h>
|
||||||
|
|
||||||
|
#include <asm/leds.h>
|
||||||
|
|
||||||
|
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,
|
||||||
|
struct sysdev_attribute *attr,
|
||||||
|
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 = {
|
||||||
|
.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);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/kernel/pmu.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
|
||||||
|
*
|
||||||
|
* 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/cpumask.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include <asm/pmu.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the IRQs for the system. We could use something like a platform
|
||||||
|
* device but that seems fairly heavyweight for this. Also, the performance
|
||||||
|
* counters can't be removed or hotplugged.
|
||||||
|
*
|
||||||
|
* Ordering is important: init_pmu() will use the ordering to set the affinity
|
||||||
|
* to the corresponding core. e.g. the first interrupt will go to cpu 0, the
|
||||||
|
* second goes to cpu 1 etc.
|
||||||
|
*/
|
||||||
|
static const int irqs[] = {
|
||||||
|
#if defined(CONFIG_ARCH_OMAP2)
|
||||||
|
3,
|
||||||
|
#elif defined(CONFIG_ARCH_BCMRING)
|
||||||
|
IRQ_PMUIRQ,
|
||||||
|
#elif defined(CONFIG_MACH_REALVIEW_EB)
|
||||||
|
IRQ_EB11MP_PMU_CPU0,
|
||||||
|
IRQ_EB11MP_PMU_CPU1,
|
||||||
|
IRQ_EB11MP_PMU_CPU2,
|
||||||
|
IRQ_EB11MP_PMU_CPU3,
|
||||||
|
#elif defined(CONFIG_ARCH_OMAP3)
|
||||||
|
INT_34XX_BENCH_MPU_EMUL,
|
||||||
|
#elif defined(CONFIG_ARCH_IOP32X)
|
||||||
|
IRQ_IOP32X_CORE_PMU,
|
||||||
|
#elif defined(CONFIG_ARCH_IOP33X)
|
||||||
|
IRQ_IOP33X_CORE_PMU,
|
||||||
|
#elif defined(CONFIG_ARCH_PXA)
|
||||||
|
IRQ_PMU,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct pmu_irqs pmu_irqs = {
|
||||||
|
.irqs = irqs,
|
||||||
|
.num_irqs = ARRAY_SIZE(irqs),
|
||||||
|
};
|
||||||
|
|
||||||
|
static volatile long pmu_lock;
|
||||||
|
|
||||||
|
const struct pmu_irqs *
|
||||||
|
reserve_pmu(void)
|
||||||
|
{
|
||||||
|
return test_and_set_bit_lock(0, &pmu_lock) ? ERR_PTR(-EBUSY) :
|
||||||
|
&pmu_irqs;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(reserve_pmu);
|
||||||
|
|
||||||
|
int
|
||||||
|
release_pmu(const struct pmu_irqs *irqs)
|
||||||
|
{
|
||||||
|
if (WARN_ON(irqs != &pmu_irqs))
|
||||||
|
return -EINVAL;
|
||||||
|
clear_bit_unlock(0, &pmu_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(release_pmu);
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_irq_affinity(int irq,
|
||||||
|
unsigned int cpu)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
int err = irq_set_affinity(irq, cpumask_of(cpu));
|
||||||
|
if (err)
|
||||||
|
pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
|
||||||
|
irq, cpu);
|
||||||
|
return err;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
init_pmu(void)
|
||||||
|
{
|
||||||
|
int i, err = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < pmu_irqs.num_irqs; ++i) {
|
||||||
|
err = set_irq_affinity(pmu_irqs.irqs[i], i);
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(init_pmu);
|
|
@ -499,10 +499,41 @@ static struct undef_hook thumb_break_hook = {
|
||||||
.fn = break_trap,
|
.fn = break_trap,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int thumb2_break_trap(struct pt_regs *regs, unsigned int instr)
|
||||||
|
{
|
||||||
|
unsigned int instr2;
|
||||||
|
void __user *pc;
|
||||||
|
|
||||||
|
/* Check the second half of the instruction. */
|
||||||
|
pc = (void __user *)(instruction_pointer(regs) + 2);
|
||||||
|
|
||||||
|
if (processor_mode(regs) == SVC_MODE) {
|
||||||
|
instr2 = *(u16 *) pc;
|
||||||
|
} else {
|
||||||
|
get_user(instr2, (u16 __user *)pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instr2 == 0xa000) {
|
||||||
|
ptrace_break(current, regs);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct undef_hook thumb2_break_hook = {
|
||||||
|
.instr_mask = 0xffff,
|
||||||
|
.instr_val = 0xf7f0,
|
||||||
|
.cpsr_mask = PSR_T_BIT,
|
||||||
|
.cpsr_val = PSR_T_BIT,
|
||||||
|
.fn = thumb2_break_trap,
|
||||||
|
};
|
||||||
|
|
||||||
static int __init ptrace_break_init(void)
|
static int __init ptrace_break_init(void)
|
||||||
{
|
{
|
||||||
register_undef_hook(&arm_break_hook);
|
register_undef_hook(&arm_break_hook);
|
||||||
register_undef_hook(&thumb_break_hook);
|
register_undef_hook(&thumb_break_hook);
|
||||||
|
register_undef_hook(&thumb2_break_hook);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,7 +700,7 @@ static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data)
|
||||||
union vfp_state *vfp = &thread->vfpstate;
|
union vfp_state *vfp = &thread->vfpstate;
|
||||||
struct user_vfp __user *ufp = data;
|
struct user_vfp __user *ufp = data;
|
||||||
|
|
||||||
vfp_sync_state(thread);
|
vfp_sync_hwstate(thread);
|
||||||
|
|
||||||
/* copy the floating point registers */
|
/* copy the floating point registers */
|
||||||
if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
|
if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
|
||||||
|
@ -692,7 +723,7 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
|
||||||
union vfp_state *vfp = &thread->vfpstate;
|
union vfp_state *vfp = &thread->vfpstate;
|
||||||
struct user_vfp __user *ufp = data;
|
struct user_vfp __user *ufp = data;
|
||||||
|
|
||||||
vfp_sync_state(thread);
|
vfp_sync_hwstate(thread);
|
||||||
|
|
||||||
/* copy the floating point registers */
|
/* copy the floating point registers */
|
||||||
if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
|
if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
|
||||||
|
@ -703,6 +734,8 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
|
||||||
if (get_user(vfp->hard.fpscr, &ufp->fpscr))
|
if (get_user(vfp->hard.fpscr, &ufp->fpscr))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
vfp_flush_hwstate(thread);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -712,26 +745,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (request) {
|
switch (request) {
|
||||||
/*
|
|
||||||
* read word at location "addr" in the child process.
|
|
||||||
*/
|
|
||||||
case PTRACE_PEEKTEXT:
|
|
||||||
case PTRACE_PEEKDATA:
|
|
||||||
ret = generic_ptrace_peekdata(child, addr, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_PEEKUSR:
|
case PTRACE_PEEKUSR:
|
||||||
ret = ptrace_read_user(child, addr, (unsigned long __user *)data);
|
ret = ptrace_read_user(child, addr, (unsigned long __user *)data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
|
||||||
* write the word at location addr.
|
|
||||||
*/
|
|
||||||
case PTRACE_POKETEXT:
|
|
||||||
case PTRACE_POKEDATA:
|
|
||||||
ret = generic_ptrace_pokedata(child, addr, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PTRACE_POKEUSR:
|
case PTRACE_POKEUSR:
|
||||||
ret = ptrace_write_user(child, addr, data);
|
ret = ptrace_write_user(child, addr, data);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -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/proc_fs.h>
|
||||||
|
|
||||||
#include <asm/unified.h>
|
#include <asm/unified.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
@ -118,7 +119,7 @@ EXPORT_SYMBOL(elf_platform);
|
||||||
|
|
||||||
static const char *cpu_name;
|
static const char *cpu_name;
|
||||||
static const char *machine_name;
|
static const char *machine_name;
|
||||||
static char __initdata command_line[COMMAND_LINE_SIZE];
|
static char __initdata cmd_line[COMMAND_LINE_SIZE];
|
||||||
|
|
||||||
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
|
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
|
||||||
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
|
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
|
||||||
|
@ -418,10 +419,11 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
|
||||||
* Pick out the memory size. We look for mem=size@start,
|
* Pick out the memory size. We look for mem=size@start,
|
||||||
* where start and size are "size[KkMm]"
|
* where start and size are "size[KkMm]"
|
||||||
*/
|
*/
|
||||||
static void __init early_mem(char **p)
|
static int __init early_mem(char *p)
|
||||||
{
|
{
|
||||||
static int usermem __initdata = 0;
|
static int usermem __initdata = 0;
|
||||||
unsigned long size, start;
|
unsigned long size, start;
|
||||||
|
char *endp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the user specifies memory size, we
|
* If the user specifies memory size, we
|
||||||
|
@ -434,52 +436,15 @@ static void __init early_mem(char **p)
|
||||||
}
|
}
|
||||||
|
|
||||||
start = PHYS_OFFSET;
|
start = PHYS_OFFSET;
|
||||||
size = memparse(*p, p);
|
size = memparse(p, &endp);
|
||||||
if (**p == '@')
|
if (*endp == '@')
|
||||||
start = memparse(*p + 1, p);
|
start = memparse(endp + 1, NULL);
|
||||||
|
|
||||||
arm_add_memory(start, size);
|
arm_add_memory(start, size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
__early_param("mem=", early_mem);
|
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 arglen = strlen(p->arg);
|
|
||||||
|
|
||||||
if (memcmp(from, p->arg, arglen) == 0) {
|
|
||||||
if (to != command_line)
|
|
||||||
to -= 1;
|
|
||||||
from += arglen;
|
|
||||||
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
|
static void __init
|
||||||
setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
|
setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
|
||||||
|
@ -740,9 +705,15 @@ void __init setup_arch(char **cmdline_p)
|
||||||
init_mm.end_data = (unsigned long) _edata;
|
init_mm.end_data = (unsigned long) _edata;
|
||||||
init_mm.brk = (unsigned long) _end;
|
init_mm.brk = (unsigned long) _end;
|
||||||
|
|
||||||
memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
|
/* parse_early_param needs a boot_command_line */
|
||||||
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
|
strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
|
||||||
parse_cmdline(cmdline_p, from);
|
|
||||||
|
/* populate cmd_line too for later use, preserving boot_command_line */
|
||||||
|
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
|
||||||
|
*cmdline_p = cmd_line;
|
||||||
|
|
||||||
|
parse_early_param();
|
||||||
|
|
||||||
paging_init(mdesc);
|
paging_init(mdesc);
|
||||||
request_standard_resources(&meminfo, mdesc);
|
request_standard_resources(&meminfo, mdesc);
|
||||||
|
|
||||||
|
@ -783,9 +754,21 @@ static int __init topology_init(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
subsys_initcall(topology_init);
|
subsys_initcall(topology_init);
|
||||||
|
|
||||||
|
#ifdef CONFIG_HAVE_PROC_CPU
|
||||||
|
static int __init proc_cpu_init(void)
|
||||||
|
{
|
||||||
|
struct proc_dir_entry *res;
|
||||||
|
|
||||||
|
res = proc_mkdir("cpu", NULL);
|
||||||
|
if (!res)
|
||||||
|
return -ENOMEM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fs_initcall(proc_cpu_init);
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *hwcap_str[] = {
|
static const char *hwcap_str[] = {
|
||||||
"swp",
|
"swp",
|
||||||
"half",
|
"half",
|
||||||
|
|
|
@ -10,11 +10,6 @@
|
||||||
*
|
*
|
||||||
* This file contains the ARM-specific time handling details:
|
* This file contains the ARM-specific time handling details:
|
||||||
* reading the RTC at bootup, etc...
|
* 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/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -77,11 +72,6 @@ unsigned long profile_pc(struct pt_regs *regs)
|
||||||
EXPORT_SYMBOL(profile_pc);
|
EXPORT_SYMBOL(profile_pc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* hook for setting the RTC's idea of the current time.
|
|
||||||
*/
|
|
||||||
int (*set_rtc)(void);
|
|
||||||
|
|
||||||
#ifndef CONFIG_GENERIC_TIME
|
#ifndef CONFIG_GENERIC_TIME
|
||||||
static unsigned long dummy_gettimeoffset(void)
|
static unsigned long dummy_gettimeoffset(void)
|
||||||
{
|
{
|
||||||
|
@ -89,140 +79,6 @@ static unsigned long dummy_gettimeoffset(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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 (!ntp_synced() || 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,
|
|
||||||
struct sysdev_attribute *attr,
|
|
||||||
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 = {
|
|
||||||
.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
|
#ifdef CONFIG_LEDS_TIMER
|
||||||
static inline void do_leds(void)
|
static inline void do_leds(void)
|
||||||
{
|
{
|
||||||
|
@ -295,39 +151,6 @@ int do_settimeofday(struct timespec *tv)
|
||||||
EXPORT_SYMBOL(do_settimeofday);
|
EXPORT_SYMBOL(do_settimeofday);
|
||||||
#endif /* !CONFIG_GENERIC_TIME */
|
#endif /* !CONFIG_GENERIC_TIME */
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
#ifndef CONFIG_GENERIC_CLOCKEVENTS
|
#ifndef CONFIG_GENERIC_CLOCKEVENTS
|
||||||
/*
|
/*
|
||||||
* Kernel system timer support.
|
* Kernel system timer support.
|
||||||
|
@ -336,7 +159,6 @@ void timer_tick(void)
|
||||||
{
|
{
|
||||||
profile_tick(CPU_PROFILING);
|
profile_tick(CPU_PROFILING);
|
||||||
do_leds();
|
do_leds();
|
||||||
do_set_rtc();
|
|
||||||
write_seqlock(&xtime_lock);
|
write_seqlock(&xtime_lock);
|
||||||
do_timer(1);
|
do_timer(1);
|
||||||
write_sequnlock(&xtime_lock);
|
write_sequnlock(&xtime_lock);
|
||||||
|
|
|
@ -12,15 +12,17 @@
|
||||||
* 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
|
* 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
|
||||||
* kill the offending process.
|
* kill the offending process.
|
||||||
*/
|
*/
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/signal.h>
|
#include <linux/signal.h>
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/personality.h>
|
#include <linux/personality.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/hardirq.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/hardirq.h>
|
||||||
|
#include <linux/kdebug.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kexec.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
@ -224,14 +226,21 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
|
||||||
#define S_SMP ""
|
#define S_SMP ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
|
static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk = thread->task;
|
struct task_struct *tsk = thread->task;
|
||||||
static int die_counter;
|
static int die_counter;
|
||||||
|
int ret;
|
||||||
|
|
||||||
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
|
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
|
||||||
str, err, ++die_counter);
|
str, err, ++die_counter);
|
||||||
sysfs_printk_last_file();
|
sysfs_printk_last_file();
|
||||||
|
|
||||||
|
/* trap and error numbers are mostly meaningless on ARM */
|
||||||
|
ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
|
||||||
|
if (ret == NOTIFY_STOP)
|
||||||
|
return ret;
|
||||||
|
|
||||||
print_modules();
|
print_modules();
|
||||||
__show_regs(regs);
|
__show_regs(regs);
|
||||||
printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
|
printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
|
||||||
|
@ -243,6 +252,8 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
|
||||||
dump_backtrace(regs, tsk);
|
dump_backtrace(regs, tsk);
|
||||||
dump_instr(KERN_EMERG, regs);
|
dump_instr(KERN_EMERG, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_SPINLOCK(die_lock);
|
DEFINE_SPINLOCK(die_lock);
|
||||||
|
@ -250,16 +261,21 @@ DEFINE_SPINLOCK(die_lock);
|
||||||
/*
|
/*
|
||||||
* This function is protected against re-entrancy.
|
* This function is protected against re-entrancy.
|
||||||
*/
|
*/
|
||||||
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
void die(const char *str, struct pt_regs *regs, int err)
|
||||||
{
|
{
|
||||||
struct thread_info *thread = current_thread_info();
|
struct thread_info *thread = current_thread_info();
|
||||||
|
int ret;
|
||||||
|
|
||||||
oops_enter();
|
oops_enter();
|
||||||
|
|
||||||
spin_lock_irq(&die_lock);
|
spin_lock_irq(&die_lock);
|
||||||
console_verbose();
|
console_verbose();
|
||||||
bust_spinlocks(1);
|
bust_spinlocks(1);
|
||||||
__die(str, err, thread, regs);
|
ret = __die(str, err, thread, regs);
|
||||||
|
|
||||||
|
if (regs && kexec_should_crash(thread->task))
|
||||||
|
crash_kexec(regs);
|
||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
|
@ -267,11 +283,10 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
||||||
|
|
||||||
if (in_interrupt())
|
if (in_interrupt())
|
||||||
panic("Fatal exception in interrupt");
|
panic("Fatal exception in interrupt");
|
||||||
|
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
if (ret != NOTIFY_STOP)
|
||||||
do_exit(SIGSEGV);
|
do_exit(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arm_notify_die(const char *str, struct pt_regs *regs,
|
void arm_notify_die(const char *str, struct pt_regs *regs,
|
||||||
|
|
|
@ -43,10 +43,6 @@ SECTIONS
|
||||||
|
|
||||||
INIT_SETUP(16)
|
INIT_SETUP(16)
|
||||||
|
|
||||||
__early_begin = .;
|
|
||||||
*(.early_param.init)
|
|
||||||
__early_end = .;
|
|
||||||
|
|
||||||
INIT_CALLS
|
INIT_CALLS
|
||||||
CON_INITCALL
|
CON_INITCALL
|
||||||
SECURITY_INITCALL
|
SECURITY_INITCALL
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
moveq \rx, #0x80000000 @ physical
|
moveq \rx, #0x80000000 @ physical
|
||||||
|
|
|
@ -89,6 +89,12 @@ config ARCH_AT91CAP9
|
||||||
select GENERIC_CLOCKEVENTS
|
select GENERIC_CLOCKEVENTS
|
||||||
select HAVE_FB_ATMEL
|
select HAVE_FB_ATMEL
|
||||||
|
|
||||||
|
config ARCH_AT572D940HF
|
||||||
|
bool "AT572D940HF"
|
||||||
|
select CPU_ARM926T
|
||||||
|
select GENERIC_TIME
|
||||||
|
select GENERIC_CLOCKEVENTS
|
||||||
|
|
||||||
config ARCH_AT91X40
|
config ARCH_AT91X40
|
||||||
bool "AT91x40"
|
bool "AT91x40"
|
||||||
|
|
||||||
|
@ -390,6 +396,23 @@ endif
|
||||||
|
|
||||||
# ----------------------------------------------------------
|
# ----------------------------------------------------------
|
||||||
|
|
||||||
|
if ARCH_AT572D940HF
|
||||||
|
|
||||||
|
comment "AT572D940HF Board Type"
|
||||||
|
|
||||||
|
config MACH_AT572D940HFEB
|
||||||
|
bool "AT572D940HF-EK"
|
||||||
|
depends on ARCH_AT572D940HF
|
||||||
|
select HAVE_AT91_DATAFLASH_CARD
|
||||||
|
select HAVE_NAND_ATMEL_BUSWIDTH_16
|
||||||
|
help
|
||||||
|
Select this if you are using Atmel's AT572D940HF-EK evaluation kit.
|
||||||
|
<http://www.atmel.com/products/diopsis/default.asp>
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
|
||||||
if ARCH_AT91X40
|
if ARCH_AT91X40
|
||||||
|
|
||||||
comment "AT91X40 Board Type"
|
comment "AT91X40 Board Type"
|
||||||
|
|
|
@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devi
|
||||||
obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
|
obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
|
||||||
obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
|
obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
|
||||||
obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
|
obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
|
||||||
|
obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
|
||||||
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
|
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
|
||||||
|
|
||||||
# AT91RM9200 board-specific support
|
# AT91RM9200 board-specific support
|
||||||
|
@ -69,6 +70,9 @@ obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
|
||||||
# AT91CAP9 board-specific support
|
# AT91CAP9 board-specific support
|
||||||
obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
|
obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
|
||||||
|
|
||||||
|
# AT572D940HF board-specific support
|
||||||
|
obj-$(CONFIG_MACH_AT572D940HFEB) += board-at572d940hf_ek.o
|
||||||
|
|
||||||
# AT91X40 board-specific support
|
# AT91X40 board-specific support
|
||||||
obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
|
obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,377 @@
|
||||||
|
/*
|
||||||
|
* arch/arm/mach-at91/at572d940hf.c
|
||||||
|
*
|
||||||
|
* Antonio R. Costa <costa.antonior@gmail.com>
|
||||||
|
* Copyright (C) 2008 Atmel
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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/module.h>
|
||||||
|
|
||||||
|
#include <asm/mach/irq.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
#include <mach/at572d940hf.h>
|
||||||
|
#include <mach/at91_pmc.h>
|
||||||
|
#include <mach/at91_rstc.h>
|
||||||
|
|
||||||
|
#include "generic.h"
|
||||||
|
#include "clock.h"
|
||||||
|
|
||||||
|
static struct map_desc at572d940hf_io_desc[] __initdata = {
|
||||||
|
{
|
||||||
|
.virtual = AT91_VA_BASE_SYS,
|
||||||
|
.pfn = __phys_to_pfn(AT91_BASE_SYS),
|
||||||
|
.length = SZ_16K,
|
||||||
|
.type = MT_DEVICE,
|
||||||
|
}, {
|
||||||
|
.virtual = AT91_IO_VIRT_BASE - AT572D940HF_SRAM_SIZE,
|
||||||
|
.pfn = __phys_to_pfn(AT572D940HF_SRAM_BASE),
|
||||||
|
.length = AT572D940HF_SRAM_SIZE,
|
||||||
|
.type = MT_DEVICE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* Clocks
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The peripheral clocks.
|
||||||
|
*/
|
||||||
|
static struct clk pioA_clk = {
|
||||||
|
.name = "pioA_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_PIOA,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk pioB_clk = {
|
||||||
|
.name = "pioB_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_PIOB,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk pioC_clk = {
|
||||||
|
.name = "pioC_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_PIOC,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk macb_clk = {
|
||||||
|
.name = "macb_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_EMAC,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk usart0_clk = {
|
||||||
|
.name = "usart0_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_US0,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk usart1_clk = {
|
||||||
|
.name = "usart1_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_US1,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk usart2_clk = {
|
||||||
|
.name = "usart2_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_US2,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk mmc_clk = {
|
||||||
|
.name = "mci_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_MCI,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk udc_clk = {
|
||||||
|
.name = "udc_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_UDP,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk twi0_clk = {
|
||||||
|
.name = "twi0_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_TWI0,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk spi0_clk = {
|
||||||
|
.name = "spi0_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_SPI0,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk spi1_clk = {
|
||||||
|
.name = "spi1_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_SPI1,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk ssc0_clk = {
|
||||||
|
.name = "ssc0_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_SSC0,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk ssc1_clk = {
|
||||||
|
.name = "ssc1_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_SSC1,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk ssc2_clk = {
|
||||||
|
.name = "ssc2_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_SSC2,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk tc0_clk = {
|
||||||
|
.name = "tc0_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_TC0,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk tc1_clk = {
|
||||||
|
.name = "tc1_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_TC1,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk tc2_clk = {
|
||||||
|
.name = "tc2_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_TC2,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk ohci_clk = {
|
||||||
|
.name = "ohci_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_UHP,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk ssc3_clk = {
|
||||||
|
.name = "ssc3_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_SSC3,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk twi1_clk = {
|
||||||
|
.name = "twi1_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_TWI1,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk can0_clk = {
|
||||||
|
.name = "can0_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_CAN0,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk can1_clk = {
|
||||||
|
.name = "can1_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_CAN1,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
static struct clk mAgicV_clk = {
|
||||||
|
.name = "mAgicV_clk",
|
||||||
|
.pmc_mask = 1 << AT572D940HF_ID_MSIRQ0,
|
||||||
|
.type = CLK_TYPE_PERIPHERAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct clk *periph_clocks[] __initdata = {
|
||||||
|
&pioA_clk,
|
||||||
|
&pioB_clk,
|
||||||
|
&pioC_clk,
|
||||||
|
&macb_clk,
|
||||||
|
&usart0_clk,
|
||||||
|
&usart1_clk,
|
||||||
|
&usart2_clk,
|
||||||
|
&mmc_clk,
|
||||||
|
&udc_clk,
|
||||||
|
&twi0_clk,
|
||||||
|
&spi0_clk,
|
||||||
|
&spi1_clk,
|
||||||
|
&ssc0_clk,
|
||||||
|
&ssc1_clk,
|
||||||
|
&ssc2_clk,
|
||||||
|
&tc0_clk,
|
||||||
|
&tc1_clk,
|
||||||
|
&tc2_clk,
|
||||||
|
&ohci_clk,
|
||||||
|
&ssc3_clk,
|
||||||
|
&twi1_clk,
|
||||||
|
&can0_clk,
|
||||||
|
&can1_clk,
|
||||||
|
&mAgicV_clk,
|
||||||
|
/* irq0 .. irq2 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The five programmable clocks.
|
||||||
|
* You must configure pin multiplexing to bring these signals out.
|
||||||
|
*/
|
||||||
|
static struct clk pck0 = {
|
||||||
|
.name = "pck0",
|
||||||
|
.pmc_mask = AT91_PMC_PCK0,
|
||||||
|
.type = CLK_TYPE_PROGRAMMABLE,
|
||||||
|
.id = 0,
|
||||||
|
};
|
||||||
|
static struct clk pck1 = {
|
||||||
|
.name = "pck1",
|
||||||
|
.pmc_mask = AT91_PMC_PCK1,
|
||||||
|
.type = CLK_TYPE_PROGRAMMABLE,
|
||||||
|
.id = 1,
|
||||||
|
};
|
||||||
|
static struct clk pck2 = {
|
||||||
|
.name = "pck2",
|
||||||
|
.pmc_mask = AT91_PMC_PCK2,
|
||||||
|
.type = CLK_TYPE_PROGRAMMABLE,
|
||||||
|
.id = 2,
|
||||||
|
};
|
||||||
|
static struct clk pck3 = {
|
||||||
|
.name = "pck3",
|
||||||
|
.pmc_mask = AT91_PMC_PCK3,
|
||||||
|
.type = CLK_TYPE_PROGRAMMABLE,
|
||||||
|
.id = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk mAgicV_mem_clk = {
|
||||||
|
.name = "mAgicV_mem_clk",
|
||||||
|
.pmc_mask = AT91_PMC_PCK4,
|
||||||
|
.type = CLK_TYPE_PROGRAMMABLE,
|
||||||
|
.id = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* HClocks */
|
||||||
|
static struct clk hck0 = {
|
||||||
|
.name = "hck0",
|
||||||
|
.pmc_mask = AT91_PMC_HCK0,
|
||||||
|
.type = CLK_TYPE_SYSTEM,
|
||||||
|
.id = 0,
|
||||||
|
};
|
||||||
|
static struct clk hck1 = {
|
||||||
|
.name = "hck1",
|
||||||
|
.pmc_mask = AT91_PMC_HCK1,
|
||||||
|
.type = CLK_TYPE_SYSTEM,
|
||||||
|
.id = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init at572d940hf_register_clocks(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
|
||||||
|
clk_register(periph_clocks[i]);
|
||||||
|
|
||||||
|
clk_register(&pck0);
|
||||||
|
clk_register(&pck1);
|
||||||
|
clk_register(&pck2);
|
||||||
|
clk_register(&pck3);
|
||||||
|
clk_register(&mAgicV_mem_clk);
|
||||||
|
|
||||||
|
clk_register(&hck0);
|
||||||
|
clk_register(&hck1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* GPIO
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static struct at91_gpio_bank at572d940hf_gpio[] = {
|
||||||
|
{
|
||||||
|
.id = AT572D940HF_ID_PIOA,
|
||||||
|
.offset = AT91_PIOA,
|
||||||
|
.clock = &pioA_clk,
|
||||||
|
}, {
|
||||||
|
.id = AT572D940HF_ID_PIOB,
|
||||||
|
.offset = AT91_PIOB,
|
||||||
|
.clock = &pioB_clk,
|
||||||
|
}, {
|
||||||
|
.id = AT572D940HF_ID_PIOC,
|
||||||
|
.offset = AT91_PIOC,
|
||||||
|
.clock = &pioC_clk,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void at572d940hf_reset(void)
|
||||||
|
{
|
||||||
|
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* AT572D940HF processor initialization
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void __init at572d940hf_initialize(unsigned long main_clock)
|
||||||
|
{
|
||||||
|
/* Map peripherals */
|
||||||
|
iotable_init(at572d940hf_io_desc, ARRAY_SIZE(at572d940hf_io_desc));
|
||||||
|
|
||||||
|
at91_arch_reset = at572d940hf_reset;
|
||||||
|
at91_extern_irq = (1 << AT572D940HF_ID_IRQ0) | (1 << AT572D940HF_ID_IRQ1)
|
||||||
|
| (1 << AT572D940HF_ID_IRQ2);
|
||||||
|
|
||||||
|
/* Init clock subsystem */
|
||||||
|
at91_clock_init(main_clock);
|
||||||
|
|
||||||
|
/* Register the processor-specific clocks */
|
||||||
|
at572d940hf_register_clocks();
|
||||||
|
|
||||||
|
/* Register GPIO subsystem */
|
||||||
|
at91_gpio_init(at572d940hf_gpio, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* Interrupt initialization
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The default interrupt priority levels (0 = lowest, 7 = highest).
|
||||||
|
*/
|
||||||
|
static unsigned int at572d940hf_default_irq_priority[NR_AIC_IRQS] __initdata = {
|
||||||
|
7, /* Advanced Interrupt Controller */
|
||||||
|
7, /* System Peripherals */
|
||||||
|
0, /* Parallel IO Controller A */
|
||||||
|
0, /* Parallel IO Controller B */
|
||||||
|
0, /* Parallel IO Controller C */
|
||||||
|
3, /* Ethernet */
|
||||||
|
6, /* USART 0 */
|
||||||
|
6, /* USART 1 */
|
||||||
|
6, /* USART 2 */
|
||||||
|
0, /* Multimedia Card Interface */
|
||||||
|
4, /* USB Device Port */
|
||||||
|
0, /* Two-Wire Interface 0 */
|
||||||
|
6, /* Serial Peripheral Interface 0 */
|
||||||
|
6, /* Serial Peripheral Interface 1 */
|
||||||
|
5, /* Serial Synchronous Controller 0 */
|
||||||
|
5, /* Serial Synchronous Controller 1 */
|
||||||
|
5, /* Serial Synchronous Controller 2 */
|
||||||
|
0, /* Timer Counter 0 */
|
||||||
|
0, /* Timer Counter 1 */
|
||||||
|
0, /* Timer Counter 2 */
|
||||||
|
3, /* USB Host port */
|
||||||
|
3, /* Serial Synchronous Controller 3 */
|
||||||
|
0, /* Two-Wire Interface 1 */
|
||||||
|
0, /* CAN Controller 0 */
|
||||||
|
0, /* CAN Controller 1 */
|
||||||
|
0, /* mAgicV HALT line */
|
||||||
|
0, /* mAgicV SIRQ0 line */
|
||||||
|
0, /* mAgicV exception line */
|
||||||
|
0, /* mAgicV end of DMA line */
|
||||||
|
0, /* Advanced Interrupt Controller */
|
||||||
|
0, /* Advanced Interrupt Controller */
|
||||||
|
0, /* Advanced Interrupt Controller */
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at572d940hf_init_interrupts(unsigned int priority[NR_AIC_IRQS])
|
||||||
|
{
|
||||||
|
if (!priority)
|
||||||
|
priority = at572d940hf_default_irq_priority;
|
||||||
|
|
||||||
|
/* Initialize the AIC interrupt controller */
|
||||||
|
at91_aic_init(priority);
|
||||||
|
|
||||||
|
/* Enable GPIO interrupts */
|
||||||
|
at91_gpio_irq_setup();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,970 @@
|
||||||
|
/*
|
||||||
|
* arch/arm/mach-at91/at572d940hf_devices.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Atmel Antonio R. Costa <costa.antonior@gmail.com>
|
||||||
|
* Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
|
||||||
|
* Copyright (C) 2005 David Brownell
|
||||||
|
*
|
||||||
|
* 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 <asm/mach/arch.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
#include <mach/board.h>
|
||||||
|
#include <mach/gpio.h>
|
||||||
|
#include <mach/at572d940hf.h>
|
||||||
|
#include <mach/at572d940hf_matrix.h>
|
||||||
|
#include <mach/at91sam9_smc.h>
|
||||||
|
|
||||||
|
#include "generic.h"
|
||||||
|
#include "sam9_smc.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* USB Host
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
|
||||||
|
static u64 ohci_dmamask = DMA_BIT_MASK(32);
|
||||||
|
static struct at91_usbh_data usbh_data;
|
||||||
|
|
||||||
|
static struct resource usbh_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_UHP_BASE,
|
||||||
|
.end = AT572D940HF_UHP_BASE + SZ_1M - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_UHP,
|
||||||
|
.end = AT572D940HF_ID_UHP,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_usbh_device = {
|
||||||
|
.name = "at91_ohci",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = &ohci_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &usbh_data,
|
||||||
|
},
|
||||||
|
.resource = usbh_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(usbh_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at91_add_device_usbh(struct at91_usbh_data *data)
|
||||||
|
{
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
usbh_data = *data;
|
||||||
|
platform_device_register(&at572d940hf_usbh_device);
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* USB Device (Gadget)
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifdef CONFIG_USB_GADGET_AT91
|
||||||
|
static struct at91_udc_data udc_data;
|
||||||
|
|
||||||
|
static struct resource udc_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_UDP,
|
||||||
|
.end = AT572D940HF_BASE_UDP + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_UDP,
|
||||||
|
.end = AT572D940HF_ID_UDP,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_udc_device = {
|
||||||
|
.name = "at91_udc",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &udc_data,
|
||||||
|
},
|
||||||
|
.resource = udc_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(udc_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at91_add_device_udc(struct at91_udc_data *data)
|
||||||
|
{
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (data->vbus_pin) {
|
||||||
|
at91_set_gpio_input(data->vbus_pin, 0);
|
||||||
|
at91_set_deglitch(data->vbus_pin, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pullup pin is handled internally */
|
||||||
|
|
||||||
|
udc_data = *data;
|
||||||
|
platform_device_register(&at572d940hf_udc_device);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void __init at91_add_device_udc(struct at91_udc_data *data) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* Ethernet
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
|
||||||
|
static u64 eth_dmamask = DMA_BIT_MASK(32);
|
||||||
|
static struct at91_eth_data eth_data;
|
||||||
|
|
||||||
|
static struct resource eth_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_EMAC,
|
||||||
|
.end = AT572D940HF_BASE_EMAC + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_EMAC,
|
||||||
|
.end = AT572D940HF_ID_EMAC,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_eth_device = {
|
||||||
|
.name = "macb",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = ð_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = ð_data,
|
||||||
|
},
|
||||||
|
.resource = eth_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(eth_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at91_add_device_eth(struct at91_eth_data *data)
|
||||||
|
{
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (data->phy_irq_pin) {
|
||||||
|
at91_set_gpio_input(data->phy_irq_pin, 0);
|
||||||
|
at91_set_deglitch(data->phy_irq_pin, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only RMII is supported */
|
||||||
|
data->is_rmii = 1;
|
||||||
|
|
||||||
|
/* Pins used for RMII */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXCK_EREFCK */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA18, 0); /* ERX0 */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA19, 0); /* ERX1 */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA20, 0); /* ERXER */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA23, 0); /* ETXEN */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA21, 0); /* ETX0 */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA22, 0); /* ETX1 */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA13, 0); /* EMDIO */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA14, 0); /* EMDC */
|
||||||
|
|
||||||
|
eth_data = *data;
|
||||||
|
platform_device_register(&at572d940hf_eth_device);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void __init at91_add_device_eth(struct at91_eth_data *data) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* MMC / SD
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
|
||||||
|
static u64 mmc_dmamask = DMA_BIT_MASK(32);
|
||||||
|
static struct at91_mmc_data mmc_data;
|
||||||
|
|
||||||
|
static struct resource mmc_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_MCI,
|
||||||
|
.end = AT572D940HF_BASE_MCI + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_MCI,
|
||||||
|
.end = AT572D940HF_ID_MCI,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_mmc_device = {
|
||||||
|
.name = "at91_mci",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = &mmc_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &mmc_data,
|
||||||
|
},
|
||||||
|
.resource = mmc_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(mmc_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
|
||||||
|
{
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* input/irq */
|
||||||
|
if (data->det_pin) {
|
||||||
|
at91_set_gpio_input(data->det_pin, 1);
|
||||||
|
at91_set_deglitch(data->det_pin, 1);
|
||||||
|
}
|
||||||
|
if (data->wp_pin)
|
||||||
|
at91_set_gpio_input(data->wp_pin, 1);
|
||||||
|
if (data->vcc_pin)
|
||||||
|
at91_set_gpio_output(data->vcc_pin, 0);
|
||||||
|
|
||||||
|
/* CLK */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC22, 0);
|
||||||
|
|
||||||
|
/* CMD */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC23, 1);
|
||||||
|
|
||||||
|
/* DAT0, maybe DAT1..DAT3 */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC24, 1);
|
||||||
|
if (data->wire4) {
|
||||||
|
at91_set_A_periph(AT91_PIN_PC25, 1);
|
||||||
|
at91_set_A_periph(AT91_PIN_PC26, 1);
|
||||||
|
at91_set_A_periph(AT91_PIN_PC27, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mmc_data = *data;
|
||||||
|
platform_device_register(&at572d940hf_mmc_device);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* NAND / SmartMedia
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
|
||||||
|
static struct atmel_nand_data nand_data;
|
||||||
|
|
||||||
|
#define NAND_BASE AT91_CHIPSELECT_3
|
||||||
|
|
||||||
|
static struct resource nand_resources[] = {
|
||||||
|
{
|
||||||
|
.start = NAND_BASE,
|
||||||
|
.end = NAND_BASE + SZ_256M - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_nand_device = {
|
||||||
|
.name = "atmel_nand",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &nand_data,
|
||||||
|
},
|
||||||
|
.resource = nand_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(nand_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at91_add_device_nand(struct atmel_nand_data *data)
|
||||||
|
{
|
||||||
|
unsigned long csa;
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
csa = at91_sys_read(AT91_MATRIX_EBICSA);
|
||||||
|
at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
|
||||||
|
|
||||||
|
/* enable pin */
|
||||||
|
if (data->enable_pin)
|
||||||
|
at91_set_gpio_output(data->enable_pin, 1);
|
||||||
|
|
||||||
|
/* ready/busy pin */
|
||||||
|
if (data->rdy_pin)
|
||||||
|
at91_set_gpio_input(data->rdy_pin, 1);
|
||||||
|
|
||||||
|
/* card detect pin */
|
||||||
|
if (data->det_pin)
|
||||||
|
at91_set_gpio_input(data->det_pin, 1);
|
||||||
|
|
||||||
|
at91_set_A_periph(AT91_PIN_PB28, 0); /* A[22] */
|
||||||
|
at91_set_B_periph(AT91_PIN_PA28, 0); /* NANDOE */
|
||||||
|
at91_set_B_periph(AT91_PIN_PA29, 0); /* NANDWE */
|
||||||
|
|
||||||
|
nand_data = *data;
|
||||||
|
platform_device_register(&at572d940hf_nand_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void __init at91_add_device_nand(struct atmel_nand_data *data) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* TWI (i2c)
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prefer the GPIO code since the TWI controller isn't robust
|
||||||
|
* (gets overruns and underruns under load) and can only issue
|
||||||
|
* repeated STARTs in one scenario (the driver doesn't yet handle them).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
|
||||||
|
|
||||||
|
static struct i2c_gpio_platform_data pdata = {
|
||||||
|
.sda_pin = AT91_PIN_PC7,
|
||||||
|
.sda_is_open_drain = 1,
|
||||||
|
.scl_pin = AT91_PIN_PC8,
|
||||||
|
.scl_is_open_drain = 1,
|
||||||
|
.udelay = 2, /* ~100 kHz */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_twi_device {
|
||||||
|
.name = "i2c-gpio",
|
||||||
|
.id = -1,
|
||||||
|
.dev.platform_data = &pdata,
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
|
||||||
|
{
|
||||||
|
at91_set_GPIO_periph(AT91_PIN_PC7, 1); /* TWD (SDA) */
|
||||||
|
at91_set_multi_drive(AT91_PIN_PC7, 1);
|
||||||
|
|
||||||
|
at91_set_GPIO_periph(AT91_PIN_PA8, 1); /* TWCK (SCL) */
|
||||||
|
at91_set_multi_drive(AT91_PIN_PC8, 1);
|
||||||
|
|
||||||
|
i2c_register_board_info(0, devices, nr_devices);
|
||||||
|
platform_device_register(&at572d940hf_twi_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
|
||||||
|
|
||||||
|
static struct resource twi0_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_TWI0,
|
||||||
|
.end = AT572D940HF_BASE_TWI0 + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_TWI0,
|
||||||
|
.end = AT572D940HF_ID_TWI0,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_twi0_device = {
|
||||||
|
.name = "at91_i2c",
|
||||||
|
.id = 0,
|
||||||
|
.resource = twi0_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(twi0_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource twi1_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_TWI1,
|
||||||
|
.end = AT572D940HF_BASE_TWI1 + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_TWI1,
|
||||||
|
.end = AT572D940HF_ID_TWI1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_twi1_device = {
|
||||||
|
.name = "at91_i2c",
|
||||||
|
.id = 1,
|
||||||
|
.resource = twi1_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(twi1_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
|
||||||
|
{
|
||||||
|
/* pins used for TWI0 interface */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC7, 0); /* TWD */
|
||||||
|
at91_set_multi_drive(AT91_PIN_PC7, 1);
|
||||||
|
|
||||||
|
at91_set_A_periph(AT91_PIN_PC8, 0); /* TWCK */
|
||||||
|
at91_set_multi_drive(AT91_PIN_PC8, 1);
|
||||||
|
|
||||||
|
/* pins used for TWI1 interface */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC20, 0); /* TWD */
|
||||||
|
at91_set_multi_drive(AT91_PIN_PC20, 1);
|
||||||
|
|
||||||
|
at91_set_A_periph(AT91_PIN_PC21, 0); /* TWCK */
|
||||||
|
at91_set_multi_drive(AT91_PIN_PC21, 1);
|
||||||
|
|
||||||
|
i2c_register_board_info(0, devices, nr_devices);
|
||||||
|
platform_device_register(&at572d940hf_twi0_device);
|
||||||
|
platform_device_register(&at572d940hf_twi1_device);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* SPI
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
|
||||||
|
static u64 spi_dmamask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static struct resource spi0_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_SPI0,
|
||||||
|
.end = AT572D940HF_BASE_SPI0 + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_SPI0,
|
||||||
|
.end = AT572D940HF_ID_SPI0,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_spi0_device = {
|
||||||
|
.name = "atmel_spi",
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = &spi_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
},
|
||||||
|
.resource = spi0_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(spi0_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 };
|
||||||
|
|
||||||
|
static struct resource spi1_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_SPI1,
|
||||||
|
.end = AT572D940HF_BASE_SPI1 + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_SPI1,
|
||||||
|
.end = AT572D940HF_ID_SPI1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_spi1_device = {
|
||||||
|
.name = "atmel_spi",
|
||||||
|
.id = 1,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = &spi_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
},
|
||||||
|
.resource = spi1_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(spi1_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned spi1_standard_cs[4] = { AT91_PIN_PC3, AT91_PIN_PC4, AT91_PIN_PC5, AT91_PIN_PC6 };
|
||||||
|
|
||||||
|
void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned long cs_pin;
|
||||||
|
short enable_spi0 = 0;
|
||||||
|
short enable_spi1 = 0;
|
||||||
|
|
||||||
|
/* Choose SPI chip-selects */
|
||||||
|
for (i = 0; i < nr_devices; i++) {
|
||||||
|
if (devices[i].controller_data)
|
||||||
|
cs_pin = (unsigned long) devices[i].controller_data;
|
||||||
|
else if (devices[i].bus_num == 0)
|
||||||
|
cs_pin = spi0_standard_cs[devices[i].chip_select];
|
||||||
|
else
|
||||||
|
cs_pin = spi1_standard_cs[devices[i].chip_select];
|
||||||
|
|
||||||
|
if (devices[i].bus_num == 0)
|
||||||
|
enable_spi0 = 1;
|
||||||
|
else
|
||||||
|
enable_spi1 = 1;
|
||||||
|
|
||||||
|
/* enable chip-select pin */
|
||||||
|
at91_set_gpio_output(cs_pin, 1);
|
||||||
|
|
||||||
|
/* pass chip-select pin to driver */
|
||||||
|
devices[i].controller_data = (void *) cs_pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_register_board_info(devices, nr_devices);
|
||||||
|
|
||||||
|
/* Configure SPI bus(es) */
|
||||||
|
if (enable_spi0) {
|
||||||
|
at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
|
||||||
|
|
||||||
|
at91_clock_associate("spi0_clk", &at572d940hf_spi0_device.dev, "spi_clk");
|
||||||
|
platform_device_register(&at572d940hf_spi0_device);
|
||||||
|
}
|
||||||
|
if (enable_spi1) {
|
||||||
|
at91_set_A_periph(AT91_PIN_PC0, 0); /* SPI1_MISO */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC1, 0); /* SPI1_MOSI */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC2, 0); /* SPI1_SPCK */
|
||||||
|
|
||||||
|
at91_clock_associate("spi1_clk", &at572d940hf_spi1_device.dev, "spi_clk");
|
||||||
|
platform_device_register(&at572d940hf_spi1_device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* Timer/Counter blocks
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ATMEL_TCLIB
|
||||||
|
|
||||||
|
static struct resource tcb_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_TCB,
|
||||||
|
.end = AT572D940HF_BASE_TCB + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_TC0,
|
||||||
|
.end = AT572D940HF_ID_TC0,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
.start = AT572D940HF_ID_TC1,
|
||||||
|
.end = AT572D940HF_ID_TC1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
[3] = {
|
||||||
|
.start = AT572D940HF_ID_TC2,
|
||||||
|
.end = AT572D940HF_ID_TC2,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_tcb_device = {
|
||||||
|
.name = "atmel_tcb",
|
||||||
|
.id = 0,
|
||||||
|
.resource = tcb_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(tcb_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init at91_add_device_tc(void)
|
||||||
|
{
|
||||||
|
/* this chip has a separate clock and irq for each TC channel */
|
||||||
|
at91_clock_associate("tc0_clk", &at572d940hf_tcb_device.dev, "t0_clk");
|
||||||
|
at91_clock_associate("tc1_clk", &at572d940hf_tcb_device.dev, "t1_clk");
|
||||||
|
at91_clock_associate("tc2_clk", &at572d940hf_tcb_device.dev, "t2_clk");
|
||||||
|
platform_device_register(&at572d940hf_tcb_device);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void __init at91_add_device_tc(void) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* RTT
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static struct resource rtt_resources[] = {
|
||||||
|
{
|
||||||
|
.start = AT91_BASE_SYS + AT91_RTT,
|
||||||
|
.end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_rtt_device = {
|
||||||
|
.name = "at91_rtt",
|
||||||
|
.id = 0,
|
||||||
|
.resource = rtt_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(rtt_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init at91_add_device_rtt(void)
|
||||||
|
{
|
||||||
|
platform_device_register(&at572d940hf_rtt_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* Watchdog
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
|
||||||
|
static struct platform_device at572d940hf_wdt_device = {
|
||||||
|
.name = "at91_wdt",
|
||||||
|
.id = -1,
|
||||||
|
.num_resources = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init at91_add_device_watchdog(void)
|
||||||
|
{
|
||||||
|
platform_device_register(&at572d940hf_wdt_device);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void __init at91_add_device_watchdog(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* UART
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(CONFIG_SERIAL_ATMEL)
|
||||||
|
static struct resource dbgu_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT91_VA_BASE_SYS + AT91_DBGU,
|
||||||
|
.end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT91_ID_SYS,
|
||||||
|
.end = AT91_ID_SYS,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct atmel_uart_data dbgu_data = {
|
||||||
|
.use_dma_tx = 0,
|
||||||
|
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
|
||||||
|
.regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
|
||||||
|
};
|
||||||
|
|
||||||
|
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_dbgu_device = {
|
||||||
|
.name = "atmel_usart",
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = &dbgu_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &dbgu_data,
|
||||||
|
},
|
||||||
|
.resource = dbgu_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(dbgu_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void configure_dbgu_pins(void)
|
||||||
|
{
|
||||||
|
at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource uart0_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_US0,
|
||||||
|
.end = AT572D940HF_BASE_US0 + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_US0,
|
||||||
|
.end = AT572D940HF_ID_US0,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct atmel_uart_data uart0_data = {
|
||||||
|
.use_dma_tx = 1,
|
||||||
|
.use_dma_rx = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u64 uart0_dmamask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_uart0_device = {
|
||||||
|
.name = "atmel_usart",
|
||||||
|
.id = 1,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = &uart0_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &uart0_data,
|
||||||
|
},
|
||||||
|
.resource = uart0_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(uart0_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void configure_usart0_pins(unsigned pins)
|
||||||
|
{
|
||||||
|
at91_set_A_periph(AT91_PIN_PA8, 1); /* TXD0 */
|
||||||
|
at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */
|
||||||
|
|
||||||
|
if (pins & ATMEL_UART_RTS)
|
||||||
|
at91_set_A_periph(AT91_PIN_PA10, 0); /* RTS0 */
|
||||||
|
if (pins & ATMEL_UART_CTS)
|
||||||
|
at91_set_A_periph(AT91_PIN_PA9, 0); /* CTS0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource uart1_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_US1,
|
||||||
|
.end = AT572D940HF_BASE_US1 + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_US1,
|
||||||
|
.end = AT572D940HF_ID_US1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct atmel_uart_data uart1_data = {
|
||||||
|
.use_dma_tx = 1,
|
||||||
|
.use_dma_rx = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u64 uart1_dmamask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_uart1_device = {
|
||||||
|
.name = "atmel_usart",
|
||||||
|
.id = 2,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = &uart1_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &uart1_data,
|
||||||
|
},
|
||||||
|
.resource = uart1_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(uart1_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void configure_usart1_pins(unsigned pins)
|
||||||
|
{
|
||||||
|
at91_set_A_periph(AT91_PIN_PC10, 1); /* TXD1 */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC9 , 0); /* RXD1 */
|
||||||
|
|
||||||
|
if (pins & ATMEL_UART_RTS)
|
||||||
|
at91_set_A_periph(AT91_PIN_PC12, 0); /* RTS1 */
|
||||||
|
if (pins & ATMEL_UART_CTS)
|
||||||
|
at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource uart2_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_BASE_US2,
|
||||||
|
.end = AT572D940HF_BASE_US2 + SZ_16K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = AT572D940HF_ID_US2,
|
||||||
|
.end = AT572D940HF_ID_US2,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct atmel_uart_data uart2_data = {
|
||||||
|
.use_dma_tx = 1,
|
||||||
|
.use_dma_rx = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u64 uart2_dmamask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
static struct platform_device at572d940hf_uart2_device = {
|
||||||
|
.name = "atmel_usart",
|
||||||
|
.id = 3,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = &uart2_dmamask,
|
||||||
|
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||||
|
.platform_data = &uart2_data,
|
||||||
|
},
|
||||||
|
.resource = uart2_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(uart2_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void configure_usart2_pins(unsigned pins)
|
||||||
|
{
|
||||||
|
at91_set_A_periph(AT91_PIN_PC15, 1); /* TXD2 */
|
||||||
|
at91_set_A_periph(AT91_PIN_PC14, 0); /* RXD2 */
|
||||||
|
|
||||||
|
if (pins & ATMEL_UART_RTS)
|
||||||
|
at91_set_A_periph(AT91_PIN_PC17, 0); /* RTS2 */
|
||||||
|
if (pins & ATMEL_UART_CTS)
|
||||||
|
at91_set_A_periph(AT91_PIN_PC16, 0); /* CTS2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
|
||||||
|
struct platform_device *atmel_default_console_device; /* the serial console device */
|
||||||
|
|
||||||
|
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
|
||||||
|
{
|
||||||
|
struct platform_device *pdev;
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case 0: /* DBGU */
|
||||||
|
pdev = &at572d940hf_dbgu_device;
|
||||||
|
configure_dbgu_pins();
|
||||||
|
at91_clock_associate("mck", &pdev->dev, "usart");
|
||||||
|
break;
|
||||||
|
case AT572D940HF_ID_US0:
|
||||||
|
pdev = &at572d940hf_uart0_device;
|
||||||
|
configure_usart0_pins(pins);
|
||||||
|
at91_clock_associate("usart0_clk", &pdev->dev, "usart");
|
||||||
|
break;
|
||||||
|
case AT572D940HF_ID_US1:
|
||||||
|
pdev = &at572d940hf_uart1_device;
|
||||||
|
configure_usart1_pins(pins);
|
||||||
|
at91_clock_associate("usart1_clk", &pdev->dev, "usart");
|
||||||
|
break;
|
||||||
|
case AT572D940HF_ID_US2:
|
||||||
|
pdev = &at572d940hf_uart2_device;
|
||||||
|
configure_usart2_pins(pins);
|
||||||
|
at91_clock_associate("usart2_clk", &pdev->dev, "usart");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pdev->id = portnr; /* update to mapped ID */
|
||||||
|
|
||||||
|
if (portnr < ATMEL_MAX_UART)
|
||||||
|
at91_uarts[portnr] = pdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init at91_set_serial_console(unsigned portnr)
|
||||||
|
{
|
||||||
|
if (portnr < ATMEL_MAX_UART)
|
||||||
|
atmel_default_console_device = at91_uarts[portnr];
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init at91_add_device_serial(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ATMEL_MAX_UART; i++) {
|
||||||
|
if (at91_uarts[i])
|
||||||
|
platform_device_register(at91_uarts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!atmel_default_console_device)
|
||||||
|
printk(KERN_INFO "AT91: No default serial console defined.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
|
||||||
|
void __init at91_set_serial_console(unsigned portnr) {}
|
||||||
|
void __init at91_add_device_serial(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* mAgic
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifdef CONFIG_MAGICV
|
||||||
|
static struct resource mAgic_resources[] = {
|
||||||
|
{
|
||||||
|
.start = AT91_MAGIC_PM_BASE,
|
||||||
|
.end = AT91_MAGIC_PM_BASE + AT91_MAGIC_PM_SIZE - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT91_MAGIC_DM_I_BASE,
|
||||||
|
.end = AT91_MAGIC_DM_I_BASE + AT91_MAGIC_DM_I_SIZE - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT91_MAGIC_DM_F_BASE,
|
||||||
|
.end = AT91_MAGIC_DM_F_BASE + AT91_MAGIC_DM_F_SIZE - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT91_MAGIC_DM_DB_BASE,
|
||||||
|
.end = AT91_MAGIC_DM_DB_BASE + AT91_MAGIC_DM_DB_SIZE - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT91_MAGIC_REGS_BASE,
|
||||||
|
.end = AT91_MAGIC_REGS_BASE + AT91_MAGIC_REGS_SIZE - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT91_MAGIC_EXTPAGE_BASE,
|
||||||
|
.end = AT91_MAGIC_EXTPAGE_BASE + AT91_MAGIC_EXTPAGE_SIZE - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT572D940HF_ID_MSIRQ0,
|
||||||
|
.end = AT572D940HF_ID_MSIRQ0,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT572D940HF_ID_MHALT,
|
||||||
|
.end = AT572D940HF_ID_MHALT,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT572D940HF_ID_MEXC,
|
||||||
|
.end = AT572D940HF_ID_MEXC,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = AT572D940HF_ID_MEDMA,
|
||||||
|
.end = AT572D940HF_ID_MEDMA,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device mAgic_device = {
|
||||||
|
.name = "mAgic",
|
||||||
|
.id = -1,
|
||||||
|
.num_resources = ARRAY_SIZE(mAgic_resources),
|
||||||
|
.resource = mAgic_resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init at91_add_device_mAgic(void)
|
||||||
|
{
|
||||||
|
platform_device_register(&mAgic_device);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void __init at91_add_device_mAgic(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These devices are always present and don't need any board-specific
|
||||||
|
* setup.
|
||||||
|
*/
|
||||||
|
static int __init at91_add_standard_devices(void)
|
||||||
|
{
|
||||||
|
at91_add_device_rtt();
|
||||||
|
at91_add_device_watchdog();
|
||||||
|
at91_add_device_tc();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_initcall(at91_add_standard_devices);
|
|
@ -0,0 +1,328 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/mach-at91/board-at572d940hf_ek.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Atmel Antonio R. Costa <costa.antonior@gmail.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.
|
||||||
|
*
|
||||||
|
* 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/mm.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/spi/spi.h>
|
||||||
|
#include <linux/spi/ds1305.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/mtd/physmap.h>
|
||||||
|
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
#include <asm/setup.h>
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
#include <asm/mach/irq.h>
|
||||||
|
|
||||||
|
#include <mach/board.h>
|
||||||
|
#include <mach/gpio.h>
|
||||||
|
#include <mach/at91sam9_smc.h>
|
||||||
|
|
||||||
|
#include "sam9_smc.h"
|
||||||
|
#include "generic.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void __init eb_map_io(void)
|
||||||
|
{
|
||||||
|
/* Initialize processor: 12.500 MHz crystal */
|
||||||
|
at572d940hf_initialize(12000000);
|
||||||
|
|
||||||
|
/* DBGU on ttyS0. (Rx & Tx only) */
|
||||||
|
at91_register_uart(0, 0, 0);
|
||||||
|
|
||||||
|
/* USART0 on ttyS1. (Rx & Tx only) */
|
||||||
|
at91_register_uart(AT572D940HF_ID_US0, 1, 0);
|
||||||
|
|
||||||
|
/* USART1 on ttyS2. (Rx & Tx only) */
|
||||||
|
at91_register_uart(AT572D940HF_ID_US1, 2, 0);
|
||||||
|
|
||||||
|
/* USART2 on ttyS3. (Tx & Rx only */
|
||||||
|
at91_register_uart(AT572D940HF_ID_US2, 3, 0);
|
||||||
|
|
||||||
|
/* set serial console to ttyS0 (ie, DBGU) */
|
||||||
|
at91_set_serial_console(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init eb_init_irq(void)
|
||||||
|
{
|
||||||
|
at572d940hf_init_interrupts(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB Host Port
|
||||||
|
*/
|
||||||
|
static struct at91_usbh_data __initdata eb_usbh_data = {
|
||||||
|
.ports = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB Device Port
|
||||||
|
*/
|
||||||
|
static struct at91_udc_data __initdata eb_udc_data = {
|
||||||
|
.vbus_pin = 0, /* no VBUS detection,UDC always on */
|
||||||
|
.pullup_pin = 0, /* pull-up driven by UDC */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MCI (SD/MMC)
|
||||||
|
*/
|
||||||
|
static struct at91_mmc_data __initdata eb_mmc_data = {
|
||||||
|
.wire4 = 1,
|
||||||
|
/* .det_pin = ... not connected */
|
||||||
|
/* .wp_pin = ... not connected */
|
||||||
|
/* .vcc_pin = ... not connected */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MACB Ethernet device
|
||||||
|
*/
|
||||||
|
static struct at91_eth_data __initdata eb_eth_data = {
|
||||||
|
.phy_irq_pin = AT91_PIN_PB25,
|
||||||
|
.is_rmii = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOR flash
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct mtd_partition eb_nor_partitions[] = {
|
||||||
|
{
|
||||||
|
.name = "Raw Environment",
|
||||||
|
.offset = 0,
|
||||||
|
.size = SZ_4M,
|
||||||
|
.mask_flags = 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "OS FS",
|
||||||
|
.offset = MTDPART_OFS_APPEND,
|
||||||
|
.size = 3 * SZ_1M,
|
||||||
|
.mask_flags = 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "APP FS",
|
||||||
|
.offset = MTDPART_OFS_APPEND,
|
||||||
|
.size = MTDPART_SIZ_FULL,
|
||||||
|
.mask_flags = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void nor_flash_set_vpp(struct map_info* mi, int i) {
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct physmap_flash_data nor_flash_data = {
|
||||||
|
.width = 4,
|
||||||
|
.parts = eb_nor_partitions,
|
||||||
|
.nr_parts = ARRAY_SIZE(eb_nor_partitions),
|
||||||
|
.set_vpp = nor_flash_set_vpp,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource nor_flash_resources[] = {
|
||||||
|
{
|
||||||
|
.start = AT91_CHIPSELECT_0,
|
||||||
|
.end = AT91_CHIPSELECT_0 + SZ_16M - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device nor_flash = {
|
||||||
|
.name = "physmap-flash",
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &nor_flash_data,
|
||||||
|
},
|
||||||
|
.resource = nor_flash_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(nor_flash_resources),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sam9_smc_config __initdata eb_nor_smc_config = {
|
||||||
|
.ncs_read_setup = 1,
|
||||||
|
.nrd_setup = 1,
|
||||||
|
.ncs_write_setup = 1,
|
||||||
|
.nwe_setup = 1,
|
||||||
|
|
||||||
|
.ncs_read_pulse = 7,
|
||||||
|
.nrd_pulse = 7,
|
||||||
|
.ncs_write_pulse = 7,
|
||||||
|
.nwe_pulse = 7,
|
||||||
|
|
||||||
|
.read_cycle = 9,
|
||||||
|
.write_cycle = 9,
|
||||||
|
|
||||||
|
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_32,
|
||||||
|
.tdf_cycles = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init eb_add_device_nor(void)
|
||||||
|
{
|
||||||
|
/* configure chip-select 0 (NOR) */
|
||||||
|
sam9_smc_configure(0, &eb_nor_smc_config);
|
||||||
|
platform_device_register(&nor_flash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAND flash
|
||||||
|
*/
|
||||||
|
static struct mtd_partition __initdata eb_nand_partition[] = {
|
||||||
|
{
|
||||||
|
.name = "Partition 1",
|
||||||
|
.offset = 0,
|
||||||
|
.size = SZ_16M,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "Partition 2",
|
||||||
|
.offset = MTDPART_OFS_NXTBLK,
|
||||||
|
.size = MTDPART_SIZ_FULL,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
|
||||||
|
{
|
||||||
|
*num_partitions = ARRAY_SIZE(eb_nand_partition);
|
||||||
|
return eb_nand_partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct atmel_nand_data __initdata eb_nand_data = {
|
||||||
|
.ale = 22,
|
||||||
|
.cle = 21,
|
||||||
|
/* .det_pin = ... not connected */
|
||||||
|
/* .rdy_pin = AT91_PIN_PC16, */
|
||||||
|
.enable_pin = AT91_PIN_PA15,
|
||||||
|
.partition_info = nand_partitions,
|
||||||
|
#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
|
||||||
|
.bus_width_16 = 1,
|
||||||
|
#else
|
||||||
|
.bus_width_16 = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sam9_smc_config __initdata eb_nand_smc_config = {
|
||||||
|
.ncs_read_setup = 0,
|
||||||
|
.nrd_setup = 0,
|
||||||
|
.ncs_write_setup = 1,
|
||||||
|
.nwe_setup = 1,
|
||||||
|
|
||||||
|
.ncs_read_pulse = 3,
|
||||||
|
.nrd_pulse = 3,
|
||||||
|
.ncs_write_pulse = 3,
|
||||||
|
.nwe_pulse = 3,
|
||||||
|
|
||||||
|
.read_cycle = 5,
|
||||||
|
.write_cycle = 5,
|
||||||
|
|
||||||
|
.mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
|
||||||
|
.tdf_cycles = 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init eb_add_device_nand(void)
|
||||||
|
{
|
||||||
|
/* setup bus-width (8 or 16) */
|
||||||
|
if (eb_nand_data.bus_width_16)
|
||||||
|
eb_nand_smc_config.mode |= AT91_SMC_DBW_16;
|
||||||
|
else
|
||||||
|
eb_nand_smc_config.mode |= AT91_SMC_DBW_8;
|
||||||
|
|
||||||
|
/* configure chip-select 3 (NAND) */
|
||||||
|
sam9_smc_configure(3, &eb_nand_smc_config);
|
||||||
|
|
||||||
|
at91_add_device_nand(&eb_nand_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI devices
|
||||||
|
*/
|
||||||
|
static struct resource rtc_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = AT572D940HF_ID_IRQ1,
|
||||||
|
.end = AT572D940HF_ID_IRQ1,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ds1305_platform_data ds1306_data = {
|
||||||
|
.is_ds1306 = true,
|
||||||
|
.en_1hz = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct spi_board_info eb_spi_devices[] = {
|
||||||
|
{ /* RTC Dallas DS1306 */
|
||||||
|
.modalias = "rtc-ds1305",
|
||||||
|
.chip_select = 3,
|
||||||
|
.mode = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA,
|
||||||
|
.max_speed_hz = 500000,
|
||||||
|
.bus_num = 0,
|
||||||
|
.irq = AT572D940HF_ID_IRQ1,
|
||||||
|
.platform_data = (void *) &ds1306_data,
|
||||||
|
},
|
||||||
|
#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
|
||||||
|
{ /* Dataflash card */
|
||||||
|
.modalias = "mtd_dataflash",
|
||||||
|
.chip_select = 0,
|
||||||
|
.max_speed_hz = 15 * 1000 * 1000,
|
||||||
|
.bus_num = 0,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init eb_board_init(void)
|
||||||
|
{
|
||||||
|
/* Serial */
|
||||||
|
at91_add_device_serial();
|
||||||
|
/* USB Host */
|
||||||
|
at91_add_device_usbh(&eb_usbh_data);
|
||||||
|
/* USB Device */
|
||||||
|
at91_add_device_udc(&eb_udc_data);
|
||||||
|
/* I2C */
|
||||||
|
at91_add_device_i2c(NULL, 0);
|
||||||
|
/* NOR */
|
||||||
|
eb_add_device_nor();
|
||||||
|
/* NAND */
|
||||||
|
eb_add_device_nand();
|
||||||
|
/* SPI */
|
||||||
|
at91_add_device_spi(eb_spi_devices, ARRAY_SIZE(eb_spi_devices));
|
||||||
|
/* MMC */
|
||||||
|
at91_add_device_mmc(0, &eb_mmc_data);
|
||||||
|
/* Ethernet */
|
||||||
|
at91_add_device_eth(&eb_eth_data);
|
||||||
|
/* mAgic */
|
||||||
|
at91_add_device_mAgic();
|
||||||
|
}
|
||||||
|
|
||||||
|
MACHINE_START(AT572D940HFEB, "Atmel AT91D940HF-EB")
|
||||||
|
/* Maintainer: Atmel <costa.antonior@gmail.com> */
|
||||||
|
.phys_io = AT91_BASE_SYS,
|
||||||
|
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
|
||||||
|
.boot_params = AT91_SDRAM_BASE + 0x100,
|
||||||
|
.timer = &at91sam926x_timer,
|
||||||
|
.map_io = eb_map_io,
|
||||||
|
.init_irq = eb_init_irq,
|
||||||
|
.init_machine = eb_board_init,
|
||||||
|
MACHINE_END
|
|
@ -29,6 +29,7 @@
|
||||||
#include <mach/cpu.h>
|
#include <mach/cpu.h>
|
||||||
|
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
|
#include "generic.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -628,7 +629,7 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
|
||||||
at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
|
at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
|
||||||
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
|
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
|
||||||
cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
|
cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
|
||||||
cpu_is_at91sam9g10()) {
|
cpu_is_at91sam9g10() || cpu_is_at572d940hf()) {
|
||||||
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
|
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
|
||||||
udpck.pmc_mask = AT91SAM926x_PMC_UDP;
|
udpck.pmc_mask = AT91SAM926x_PMC_UDP;
|
||||||
} else if (cpu_is_at91cap9()) {
|
} else if (cpu_is_at91cap9()) {
|
||||||
|
@ -711,12 +712,13 @@ int __init at91_clock_init(unsigned long main_clock)
|
||||||
/*
|
/*
|
||||||
* USB HS clock init
|
* USB HS clock init
|
||||||
*/
|
*/
|
||||||
if (cpu_has_utmi())
|
if (cpu_has_utmi()) {
|
||||||
/*
|
/*
|
||||||
* multiplier is hard-wired to 40
|
* multiplier is hard-wired to 40
|
||||||
* (obtain the USB High Speed 480 MHz when input is 12 MHz)
|
* (obtain the USB High Speed 480 MHz when input is 12 MHz)
|
||||||
*/
|
*/
|
||||||
utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
|
utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USB FS clock init
|
* USB FS clock init
|
||||||
|
@ -746,7 +748,7 @@ int __init at91_clock_init(unsigned long main_clock)
|
||||||
mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
|
mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
|
||||||
freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
|
freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
|
||||||
} else {
|
} else {
|
||||||
mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
|
mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register the PMC's standard clocks */
|
/* Register the PMC's standard clocks */
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct clk {
|
||||||
struct clk *parent;
|
struct clk *parent;
|
||||||
u32 pmc_mask;
|
u32 pmc_mask;
|
||||||
void (*mode)(struct clk *, int);
|
void (*mode)(struct clk *, int);
|
||||||
unsigned id:2; /* PCK0..3, or 32k/main/a/b */
|
unsigned id:3; /* PCK0..4, or 32k/main/a/b */
|
||||||
unsigned type; /* clock type */
|
unsigned type; /* clock type */
|
||||||
u16 users;
|
u16 users;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,6 +17,7 @@ extern void __init at91sam9rl_initialize(unsigned long main_clock);
|
||||||
extern void __init at91sam9g45_initialize(unsigned long main_clock);
|
extern void __init at91sam9g45_initialize(unsigned long main_clock);
|
||||||
extern void __init at91x40_initialize(unsigned long main_clock);
|
extern void __init at91x40_initialize(unsigned long main_clock);
|
||||||
extern void __init at91cap9_initialize(unsigned long main_clock);
|
extern void __init at91cap9_initialize(unsigned long main_clock);
|
||||||
|
extern void __init at572d940hf_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[]);
|
||||||
|
@ -27,6 +28,7 @@ extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
|
||||||
extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
|
extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
|
||||||
extern void __init at91x40_init_interrupts(unsigned int priority[]);
|
extern void __init at91x40_init_interrupts(unsigned int priority[]);
|
||||||
extern void __init at91cap9_init_interrupts(unsigned int priority[]);
|
extern void __init at91cap9_init_interrupts(unsigned int priority[]);
|
||||||
|
extern void __init at572d940hf_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 */
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* include/mach/at572d940hf.h
|
||||||
|
*
|
||||||
|
* Antonio R. Costa <costa.antonior@gmail.com>
|
||||||
|
* Copyright (C) 2008 Atmel
|
||||||
|
*
|
||||||
|
* 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 AT572D940HF_H
|
||||||
|
#define AT572D940HF_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Peripheral identifiers/interrupts.
|
||||||
|
*/
|
||||||
|
#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
|
||||||
|
#define AT91_ID_SYS 1 /* System Peripherals */
|
||||||
|
#define AT572D940HF_ID_PIOA 2 /* Parallel IO Controller A */
|
||||||
|
#define AT572D940HF_ID_PIOB 3 /* Parallel IO Controller B */
|
||||||
|
#define AT572D940HF_ID_PIOC 4 /* Parallel IO Controller C */
|
||||||
|
#define AT572D940HF_ID_EMAC 5 /* MACB ethernet controller */
|
||||||
|
#define AT572D940HF_ID_US0 6 /* USART 0 */
|
||||||
|
#define AT572D940HF_ID_US1 7 /* USART 1 */
|
||||||
|
#define AT572D940HF_ID_US2 8 /* USART 2 */
|
||||||
|
#define AT572D940HF_ID_MCI 9 /* Multimedia Card Interface */
|
||||||
|
#define AT572D940HF_ID_UDP 10 /* USB Device Port */
|
||||||
|
#define AT572D940HF_ID_TWI0 11 /* Two-Wire Interface 0 */
|
||||||
|
#define AT572D940HF_ID_SPI0 12 /* Serial Peripheral Interface 0 */
|
||||||
|
#define AT572D940HF_ID_SPI1 13 /* Serial Peripheral Interface 1 */
|
||||||
|
#define AT572D940HF_ID_SSC0 14 /* Serial Synchronous Controller 0 */
|
||||||
|
#define AT572D940HF_ID_SSC1 15 /* Serial Synchronous Controller 1 */
|
||||||
|
#define AT572D940HF_ID_SSC2 16 /* Serial Synchronous Controller 2 */
|
||||||
|
#define AT572D940HF_ID_TC0 17 /* Timer Counter 0 */
|
||||||
|
#define AT572D940HF_ID_TC1 18 /* Timer Counter 1 */
|
||||||
|
#define AT572D940HF_ID_TC2 19 /* Timer Counter 2 */
|
||||||
|
#define AT572D940HF_ID_UHP 20 /* USB Host port */
|
||||||
|
#define AT572D940HF_ID_SSC3 21 /* Serial Synchronous Controller 3 */
|
||||||
|
#define AT572D940HF_ID_TWI1 22 /* Two-Wire Interface 1 */
|
||||||
|
#define AT572D940HF_ID_CAN0 23 /* CAN Controller 0 */
|
||||||
|
#define AT572D940HF_ID_CAN1 24 /* CAN Controller 1 */
|
||||||
|
#define AT572D940HF_ID_MHALT 25 /* mAgicV HALT line */
|
||||||
|
#define AT572D940HF_ID_MSIRQ0 26 /* mAgicV SIRQ0 line */
|
||||||
|
#define AT572D940HF_ID_MEXC 27 /* mAgicV exception line */
|
||||||
|
#define AT572D940HF_ID_MEDMA 28 /* mAgicV end of DMA line */
|
||||||
|
#define AT572D940HF_ID_IRQ0 29 /* External Interrupt Source (IRQ0) */
|
||||||
|
#define AT572D940HF_ID_IRQ1 30 /* External Interrupt Source (IRQ1) */
|
||||||
|
#define AT572D940HF_ID_IRQ2 31 /* External Interrupt Source (IRQ2) */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User Peripheral physical base addresses.
|
||||||
|
*/
|
||||||
|
#define AT572D940HF_BASE_TCB 0xfffa0000
|
||||||
|
#define AT572D940HF_BASE_TC0 0xfffa0000
|
||||||
|
#define AT572D940HF_BASE_TC1 0xfffa0040
|
||||||
|
#define AT572D940HF_BASE_TC2 0xfffa0080
|
||||||
|
#define AT572D940HF_BASE_UDP 0xfffa4000
|
||||||
|
#define AT572D940HF_BASE_MCI 0xfffa8000
|
||||||
|
#define AT572D940HF_BASE_TWI0 0xfffac000
|
||||||
|
#define AT572D940HF_BASE_US0 0xfffb0000
|
||||||
|
#define AT572D940HF_BASE_US1 0xfffb4000
|
||||||
|
#define AT572D940HF_BASE_US2 0xfffb8000
|
||||||
|
#define AT572D940HF_BASE_SSC0 0xfffbc000
|
||||||
|
#define AT572D940HF_BASE_SSC1 0xfffc0000
|
||||||
|
#define AT572D940HF_BASE_SSC2 0xfffc4000
|
||||||
|
#define AT572D940HF_BASE_SPI0 0xfffc8000
|
||||||
|
#define AT572D940HF_BASE_SPI1 0xfffcc000
|
||||||
|
#define AT572D940HF_BASE_SSC3 0xfffd0000
|
||||||
|
#define AT572D940HF_BASE_TWI1 0xfffd4000
|
||||||
|
#define AT572D940HF_BASE_EMAC 0xfffd8000
|
||||||
|
#define AT572D940HF_BASE_CAN0 0xfffdc000
|
||||||
|
#define AT572D940HF_BASE_CAN1 0xfffe0000
|
||||||
|
#define AT91_BASE_SYS 0xffffea00
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System Peripherals (offset from AT91_BASE_SYS)
|
||||||
|
*/
|
||||||
|
#define AT91_SDRAMC (0xffffea00 - AT91_BASE_SYS)
|
||||||
|
#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
|
||||||
|
#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
|
||||||
|
#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
|
||||||
|
#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS)
|
||||||
|
#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS)
|
||||||
|
#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS)
|
||||||
|
#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS)
|
||||||
|
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
|
||||||
|
#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
|
||||||
|
#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
|
||||||
|
#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
|
||||||
|
#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
|
||||||
|
|
||||||
|
#define AT91_USART0 AT572D940HF_ID_US0
|
||||||
|
#define AT91_USART1 AT572D940HF_ID_US1
|
||||||
|
#define AT91_USART2 AT572D940HF_ID_US2
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal Memory.
|
||||||
|
*/
|
||||||
|
#define AT572D940HF_SRAM_BASE 0x00300000 /* Internal SRAM base address */
|
||||||
|
#define AT572D940HF_SRAM_SIZE (48 * SZ_1K) /* Internal SRAM size (48Kb) */
|
||||||
|
|
||||||
|
#define AT572D940HF_ROM_BASE 0x00400000 /* Internal ROM base address */
|
||||||
|
#define AT572D940HF_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */
|
||||||
|
|
||||||
|
#define AT572D940HF_UHP_BASE 0x00500000 /* USB Host controller */
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* include/mach//at572d940hf_matrix.h
|
||||||
|
*
|
||||||
|
* Antonio R. Costa <costa.antonior@gmail.com>
|
||||||
|
* Copyright (C) 2008 Atmel
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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 AT572D940HF_MATRIX_H
|
||||||
|
#define AT572D940HF_MATRIX_H
|
||||||
|
|
||||||
|
#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
|
||||||
|
#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
|
||||||
|
#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
|
||||||
|
#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
|
||||||
|
#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
|
||||||
|
#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
|
||||||
|
|
||||||
|
#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
|
||||||
|
#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
|
||||||
|
#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
|
||||||
|
#define AT91_MATRIX_ULBT_FOUR (2 << 0)
|
||||||
|
#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
|
||||||
|
#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
|
||||||
|
|
||||||
|
#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
|
||||||
|
#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
|
||||||
|
#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
|
||||||
|
#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
|
||||||
|
#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
|
||||||
|
#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
|
||||||
|
#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
|
||||||
|
#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
|
||||||
|
#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
|
||||||
|
#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
|
||||||
|
#define AT91_MATRIX_FIXED_DEFMSTR (0x7 << 18) /* Fixed Index of Default Master */
|
||||||
|
#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
|
||||||
|
#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
|
||||||
|
#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
|
||||||
|
|
||||||
|
#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
|
||||||
|
#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
|
||||||
|
#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
|
||||||
|
#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
|
||||||
|
#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
|
||||||
|
|
||||||
|
#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
|
||||||
|
#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
|
||||||
|
#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
|
||||||
|
#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
|
||||||
|
#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
|
||||||
|
#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
|
||||||
|
#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
|
||||||
|
|
||||||
|
#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
|
||||||
|
#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
|
||||||
|
#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
|
||||||
|
|
||||||
|
#define AT91_MATRIX_SFR0 (AT91_MATRIX + 0x110) /* Special Function Register 0 */
|
||||||
|
#define AT91_MATRIX_SFR1 (AT91_MATRIX + 0x114) /* Special Function Register 1 */
|
||||||
|
#define AT91_MATRIX_SFR2 (AT91_MATRIX + 0x118) /* Special Function Register 2 */
|
||||||
|
#define AT91_MATRIX_SFR3 (AT91_MATRIX + 0x11C) /* Special Function Register 3 */
|
||||||
|
#define AT91_MATRIX_SFR4 (AT91_MATRIX + 0x120) /* Special Function Register 4 */
|
||||||
|
#define AT91_MATRIX_SFR5 (AT91_MATRIX + 0x124) /* Special Function Register 5 */
|
||||||
|
#define AT91_MATRIX_SFR6 (AT91_MATRIX + 0x128) /* Special Function Register 6 */
|
||||||
|
#define AT91_MATRIX_SFR7 (AT91_MATRIX + 0x12C) /* Special Function Register 7 */
|
||||||
|
#define AT91_MATRIX_SFR8 (AT91_MATRIX + 0x130) /* Special Function Register 8 */
|
||||||
|
#define AT91_MATRIX_SFR9 (AT91_MATRIX + 0x134) /* Special Function Register 9 */
|
||||||
|
#define AT91_MATRIX_SFR10 (AT91_MATRIX + 0x138) /* Special Function Register 10 */
|
||||||
|
#define AT91_MATRIX_SFR11 (AT91_MATRIX + 0x13C) /* Special Function Register 11 */
|
||||||
|
#define AT91_MATRIX_SFR12 (AT91_MATRIX + 0x140) /* Special Function Register 12 */
|
||||||
|
#define AT91_MATRIX_SFR13 (AT91_MATRIX + 0x144) /* Special Function Register 13 */
|
||||||
|
#define AT91_MATRIX_SFR14 (AT91_MATRIX + 0x148) /* Special Function Register 14 */
|
||||||
|
#define AT91_MATRIX_SFR15 (AT91_MATRIX + 0x14C) /* Special Function Register 15 */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following registers / bits are not defined in the Datasheet (Revision A)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AT91_MATRIX_TCR (AT91_MATRIX + 0x100) /* TCM Configuration Register */
|
||||||
|
#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
|
||||||
|
#define AT91_MATRIX_ITCM_0 (0 << 0)
|
||||||
|
#define AT91_MATRIX_ITCM_16 (5 << 0)
|
||||||
|
#define AT91_MATRIX_ITCM_32 (6 << 0)
|
||||||
|
#define AT91_MATRIX_ITCM_64 (7 << 0)
|
||||||
|
#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
|
||||||
|
#define AT91_MATRIX_DTCM_0 (0 << 4)
|
||||||
|
#define AT91_MATRIX_DTCM_16 (5 << 4)
|
||||||
|
#define AT91_MATRIX_DTCM_32 (6 << 4)
|
||||||
|
#define AT91_MATRIX_DTCM_64 (7 << 4)
|
||||||
|
|
||||||
|
#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x11C) /* EBI Chip Select Assignment Register */
|
||||||
|
#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */
|
||||||
|
#define AT91_MATRIX_CS1A_SMC (0 << 1)
|
||||||
|
#define AT91_MATRIX_CS1A_SDRAMC (1 << 1)
|
||||||
|
#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */
|
||||||
|
#define AT91_MATRIX_CS3A_SMC (0 << 3)
|
||||||
|
#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3)
|
||||||
|
#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */
|
||||||
|
#define AT91_MATRIX_CS4A_SMC (0 << 4)
|
||||||
|
#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4)
|
||||||
|
#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */
|
||||||
|
#define AT91_MATRIX_CS5A_SMC (0 << 5)
|
||||||
|
#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5)
|
||||||
|
#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
|
||||||
|
|
||||||
|
#endif
|
|
@ -32,6 +32,7 @@
|
||||||
#define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */
|
#define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */
|
||||||
#define AT91_PMC_PCK2 (1 << 10) /* Programmable Clock 2 */
|
#define AT91_PMC_PCK2 (1 << 10) /* Programmable Clock 2 */
|
||||||
#define AT91_PMC_PCK3 (1 << 11) /* Programmable Clock 3 */
|
#define AT91_PMC_PCK3 (1 << 11) /* Programmable Clock 3 */
|
||||||
|
#define AT91_PMC_PCK4 (1 << 12) /* Programmable Clock 4 [AT572D940HF only] */
|
||||||
#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */
|
#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */
|
||||||
#define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */
|
#define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ struct at91_eth_data {
|
||||||
extern void __init at91_add_device_eth(struct at91_eth_data *data);
|
extern void __init at91_add_device_eth(struct at91_eth_data *data);
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
|
#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
|
||||||
|| defined(CONFIG_ARCH_AT91SAM9G45)
|
|| defined(CONFIG_ARCH_AT91SAM9G45) || defined(CONFIG_ARCH_AT572D940HF)
|
||||||
#define eth_platform_data at91_eth_data
|
#define eth_platform_data at91_eth_data
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -205,6 +205,9 @@ extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
|
||||||
extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
|
extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
|
||||||
extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
|
extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
|
||||||
|
|
||||||
|
/* AT572D940HF DSP */
|
||||||
|
extern void __init at91_add_device_mAgic(void);
|
||||||
|
|
||||||
/* FIXME: this needs a better location, but gets stuff building again */
|
/* FIXME: this needs a better location, but gets stuff building again */
|
||||||
extern int at91_suspend_entering_slow_clock(void);
|
extern int at91_suspend_entering_slow_clock(void);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#define ARCH_ID_AT91SAM9XE256 0x329a93a0
|
#define ARCH_ID_AT91SAM9XE256 0x329a93a0
|
||||||
#define ARCH_ID_AT91SAM9XE512 0x329aa3a0
|
#define ARCH_ID_AT91SAM9XE512 0x329aa3a0
|
||||||
|
|
||||||
|
#define ARCH_ID_AT572D940HF 0x0e0303e0
|
||||||
|
|
||||||
#define ARCH_ID_AT91M40800 0x14080044
|
#define ARCH_ID_AT91M40800 0x14080044
|
||||||
#define ARCH_ID_AT91R40807 0x44080746
|
#define ARCH_ID_AT91R40807 0x44080746
|
||||||
#define ARCH_ID_AT91M40807 0x14080745
|
#define ARCH_ID_AT91M40807 0x14080745
|
||||||
|
@ -141,6 +143,12 @@ static inline unsigned long at91cap9_rev_identify(void)
|
||||||
#define cpu_is_at91cap9_revC() (0)
|
#define cpu_is_at91cap9_revC() (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_AT572D940HF
|
||||||
|
#define cpu_is_at572d940hf() (at91_cpu_identify() == ARCH_ID_AT572D940HF)
|
||||||
|
#else
|
||||||
|
#define cpu_is_at572d940hf() (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since this is ARM, we will never run on any AVR32 CPU. But these
|
* Since this is ARM, we will never run on any AVR32 CPU. But these
|
||||||
* definitions may reduce clutter in common drivers.
|
* definitions may reduce clutter in common drivers.
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <mach/at91_dbgu.h>
|
#include <mach/at91_dbgu.h>
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
ldreq \rx, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address)
|
ldreq \rx, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address)
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include <mach/at91cap9.h>
|
#include <mach/at91cap9.h>
|
||||||
#elif defined(CONFIG_ARCH_AT91X40)
|
#elif defined(CONFIG_ARCH_AT91X40)
|
||||||
#include <mach/at91x40.h>
|
#include <mach/at91x40.h>
|
||||||
|
#elif defined(CONFIG_ARCH_AT572D940HF)
|
||||||
|
#include <mach/at572d940hf.h>
|
||||||
#else
|
#else
|
||||||
#error "Unsupported AT91 processor"
|
#error "Unsupported AT91 processor"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -82,6 +82,11 @@
|
||||||
#define AT91X40_MASTER_CLOCK 40000000
|
#define AT91X40_MASTER_CLOCK 40000000
|
||||||
#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK)
|
#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK)
|
||||||
|
|
||||||
|
#elif defined(CONFIG_ARCH_AT572D940HF)
|
||||||
|
|
||||||
|
#define AT572D940HF_MASTER_CLOCK 80000000
|
||||||
|
#define CLOCK_TICK_RATE (AT572D940HF_MASTER_CLOCK/16)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -142,8 +142,7 @@ void __init bcmring_amba_init(void)
|
||||||
|
|
||||||
chipcHw_busInterfaceClockEnable(bus_clock);
|
chipcHw_busInterfaceClockEnable(bus_clock);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(lookups); i++)
|
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||||
clkdev_add(&lookups[i]);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||||
struct amba_device *d = amba_devs[i];
|
struct amba_device *d = amba_devs[i];
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include <asm/hardware/clps7111.h>
|
#include <asm/hardware/clps7111.h>
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
moveq \rx, #CLPS7111_PHYS_BASE
|
moveq \rx, #CLPS7111_PHYS_BASE
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <linux/serial_reg.h>
|
#include <linux/serial_reg.h>
|
||||||
#define UART_SHIFT 2
|
#define UART_SHIFT 2
|
||||||
|
|
||||||
.macro addruart, rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
moveq \rx, #0x01000000 @ physical base address
|
moveq \rx, #0x01000000 @ physical base address
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
/*
|
/*
|
||||||
* I/O mapping
|
* I/O mapping
|
||||||
*/
|
*/
|
||||||
#define IO_PHYS 0x01c00000
|
#define IO_PHYS 0x01c00000UL
|
||||||
#define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */
|
#define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */
|
||||||
#define IO_SIZE 0x00400000
|
#define IO_SIZE 0x00400000
|
||||||
#define IO_VIRT (IO_PHYS + IO_OFFSET)
|
#define IO_VIRT (IO_PHYS + IO_OFFSET)
|
||||||
|
|
|
@ -24,7 +24,7 @@ void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
|
||||||
if (BETWEEN(p, IO_PHYS, IO_SIZE))
|
if (BETWEEN(p, IO_PHYS, IO_SIZE))
|
||||||
return XLATE(p, IO_PHYS, IO_VIRT);
|
return XLATE(p, IO_PHYS, IO_VIRT);
|
||||||
|
|
||||||
return __arm_ioremap(p, size, type);
|
return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(davinci_ioremap);
|
EXPORT_SYMBOL(davinci_ioremap);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include <mach/bridge-regs.h>
|
#include <mach/bridge-regs.h>
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
ldreq \rx, =DOVE_SB_REGS_PHYS_BASE
|
ldreq \rx, =DOVE_SB_REGS_PHYS_BASE
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
* arch/arm/mach-dove/include/mach/vmalloc.h
|
* arch/arm/mach-dove/include/mach/vmalloc.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VMALLOC_END 0xfd800000
|
#define VMALLOC_END 0xfd800000UL
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mov \rx, #0xf0000000
|
mov \rx, #0xf0000000
|
||||||
orr \rx, \rx, #0x00000be0
|
orr \rx, \rx, #0x00000be0
|
||||||
.endm
|
.endm
|
||||||
|
|
|
@ -161,6 +161,20 @@ config MACH_MICRO9S
|
||||||
Say 'Y' here if you want your kernel to support the
|
Say 'Y' here if you want your kernel to support the
|
||||||
Contec Micro9-Slim board.
|
Contec Micro9-Slim board.
|
||||||
|
|
||||||
|
config MACH_SIM_ONE
|
||||||
|
bool "Support Simplemachines Sim.One board"
|
||||||
|
depends on EP93XX_SDCE0_PHYS_OFFSET
|
||||||
|
help
|
||||||
|
Say 'Y' here if you want your kernel to support the
|
||||||
|
Simplemachines Sim.One board.
|
||||||
|
|
||||||
|
config MACH_SNAPPER_CL15
|
||||||
|
bool "Support Bluewater Systems Snapper CL15 Module"
|
||||||
|
depends on EP93XX_SDCE0_PHYS_OFFSET
|
||||||
|
help
|
||||||
|
Say 'Y' here if you want your kernel to support the Bluewater
|
||||||
|
Systems Snapper CL15 Module.
|
||||||
|
|
||||||
config MACH_TS72XX
|
config MACH_TS72XX
|
||||||
bool "Support Technologic Systems TS-72xx SBC"
|
bool "Support Technologic Systems TS-72xx SBC"
|
||||||
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
|
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
|
||||||
|
|
|
@ -10,4 +10,6 @@ obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o
|
||||||
obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o
|
obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o
|
||||||
obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o
|
obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o
|
||||||
obj-$(CONFIG_MACH_MICRO9) += micro9.o
|
obj-$(CONFIG_MACH_MICRO9) += micro9.o
|
||||||
|
obj-$(CONFIG_MACH_SIM_ONE) += simone.o
|
||||||
|
obj-$(CONFIG_MACH_SNAPPER_CL15) += snappercl15.o
|
||||||
obj-$(CONFIG_MACH_TS72XX) += ts72xx.o
|
obj-$(CONFIG_MACH_TS72XX) += ts72xx.o
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
* your option) any later version.
|
* your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
@ -445,37 +447,39 @@ static void __init ep93xx_dma_clock_init(void)
|
||||||
static int __init ep93xx_clock_init(void)
|
static int __init ep93xx_clock_init(void)
|
||||||
{
|
{
|
||||||
u32 value;
|
u32 value;
|
||||||
int i;
|
|
||||||
|
|
||||||
value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
|
/* Determine the bootloader configured pll1 rate */
|
||||||
if (!(value & 0x00800000)) { /* PLL1 bypassed? */
|
value = __raw_readl(EP93XX_SYSCON_CLKSET1);
|
||||||
|
if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
|
||||||
clk_pll1.rate = clk_xtali.rate;
|
clk_pll1.rate = clk_xtali.rate;
|
||||||
} else {
|
else
|
||||||
clk_pll1.rate = calc_pll_rate(value);
|
clk_pll1.rate = calc_pll_rate(value);
|
||||||
}
|
|
||||||
|
/* Initialize the pll1 derived clocks */
|
||||||
clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
|
clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
|
||||||
clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
|
clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
|
||||||
clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
|
clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
|
||||||
ep93xx_dma_clock_init();
|
ep93xx_dma_clock_init();
|
||||||
|
|
||||||
value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
|
/* Determine the bootloader configured pll2 rate */
|
||||||
if (!(value & 0x00080000)) { /* PLL2 bypassed? */
|
value = __raw_readl(EP93XX_SYSCON_CLKSET2);
|
||||||
|
if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
|
||||||
clk_pll2.rate = clk_xtali.rate;
|
clk_pll2.rate = clk_xtali.rate;
|
||||||
} else if (value & 0x00040000) { /* PLL2 enabled? */
|
else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
|
||||||
clk_pll2.rate = calc_pll_rate(value);
|
clk_pll2.rate = calc_pll_rate(value);
|
||||||
} else {
|
else
|
||||||
clk_pll2.rate = 0;
|
clk_pll2.rate = 0;
|
||||||
}
|
|
||||||
|
/* Initialize the pll2 derived clocks */
|
||||||
clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
|
clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
|
||||||
|
|
||||||
printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
|
pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
|
||||||
clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
|
clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
|
||||||
printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
|
pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
|
||||||
clk_f.rate / 1000000, clk_h.rate / 1000000,
|
clk_f.rate / 1000000, clk_h.rate / 1000000,
|
||||||
clk_p.rate / 1000000);
|
clk_p.rate / 1000000);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(clocks); i++)
|
clkdev_add_table(clocks, ARRAY_SIZE(clocks));
|
||||||
clkdev_add(&clocks[i]);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
arch_initcall(ep93xx_clock_init);
|
arch_initcall(ep93xx_clock_init);
|
||||||
|
|
|
@ -14,12 +14,15 @@
|
||||||
* your option) any later version.
|
* your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/timex.h>
|
#include <linux/timex.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
|
@ -35,7 +38,6 @@
|
||||||
|
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
#include <asm/mach/time.h>
|
#include <asm/mach/time.h>
|
||||||
#include <asm/mach/irq.h>
|
|
||||||
|
|
||||||
#include <asm/hardware/vic.h>
|
#include <asm/hardware/vic.h>
|
||||||
|
|
||||||
|
@ -82,13 +84,40 @@ void __init ep93xx_map_io(void)
|
||||||
* to use this timer for something else. We also use timer 4 for keeping
|
* to use this timer for something else. We also use timer 4 for keeping
|
||||||
* track of lost jiffies.
|
* track of lost jiffies.
|
||||||
*/
|
*/
|
||||||
static unsigned int last_jiffy_time;
|
#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
|
||||||
|
#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
|
||||||
|
#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
|
||||||
|
#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08)
|
||||||
|
#define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7)
|
||||||
|
#define EP93XX_TIMER123_CONTROL_MODE (1 << 6)
|
||||||
|
#define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3)
|
||||||
|
#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c)
|
||||||
|
#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
|
||||||
|
#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
|
||||||
|
#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
|
||||||
|
#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
|
||||||
|
#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60)
|
||||||
|
#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64)
|
||||||
|
#define EP93XX_TIMER4_VALUE_HIGH_ENABLE (1 << 8)
|
||||||
|
#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80)
|
||||||
|
#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84)
|
||||||
|
#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
|
||||||
|
#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
|
||||||
|
|
||||||
|
#define EP93XX_TIMER123_CLOCK 508469
|
||||||
|
#define EP93XX_TIMER4_CLOCK 983040
|
||||||
|
|
||||||
|
#define TIMER1_RELOAD ((EP93XX_TIMER123_CLOCK / HZ) - 1)
|
||||||
#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
|
#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
|
||||||
|
|
||||||
|
static unsigned int last_jiffy_time;
|
||||||
|
|
||||||
static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
|
static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
|
/* Writing any value clears the timer interrupt */
|
||||||
__raw_writel(1, EP93XX_TIMER1_CLEAR);
|
__raw_writel(1, EP93XX_TIMER1_CLEAR);
|
||||||
|
|
||||||
|
/* Recover lost jiffies */
|
||||||
while ((signed long)
|
while ((signed long)
|
||||||
(__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
|
(__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
|
||||||
>= TIMER4_TICKS_PER_JIFFY) {
|
>= TIMER4_TICKS_PER_JIFFY) {
|
||||||
|
@ -107,13 +136,18 @@ static struct irqaction ep93xx_timer_irq = {
|
||||||
|
|
||||||
static void __init ep93xx_timer_init(void)
|
static void __init ep93xx_timer_init(void)
|
||||||
{
|
{
|
||||||
|
u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
|
||||||
|
EP93XX_TIMER123_CONTROL_CLKSEL;
|
||||||
|
|
||||||
/* Enable periodic HZ timer. */
|
/* Enable periodic HZ timer. */
|
||||||
__raw_writel(0x48, EP93XX_TIMER1_CONTROL);
|
__raw_writel(tmode, EP93XX_TIMER1_CONTROL);
|
||||||
__raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD);
|
__raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD);
|
||||||
__raw_writel(0xc8, EP93XX_TIMER1_CONTROL);
|
__raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
|
||||||
|
EP93XX_TIMER1_CONTROL);
|
||||||
|
|
||||||
/* Enable lost jiffy timer. */
|
/* Enable lost jiffy timer. */
|
||||||
__raw_writel(0x100, EP93XX_TIMER4_VALUE_HIGH);
|
__raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
|
||||||
|
EP93XX_TIMER4_VALUE_HIGH);
|
||||||
|
|
||||||
setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
|
setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
|
||||||
}
|
}
|
||||||
|
@ -134,238 +168,17 @@ struct sys_timer ep93xx_timer = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
* GPIO handling for EP93xx
|
|
||||||
*************************************************************************/
|
|
||||||
static unsigned char gpio_int_unmasked[3];
|
|
||||||
static unsigned char gpio_int_enabled[3];
|
|
||||||
static unsigned char gpio_int_type1[3];
|
|
||||||
static unsigned char gpio_int_type2[3];
|
|
||||||
static unsigned char gpio_int_debounce[3];
|
|
||||||
|
|
||||||
/* Port ordering is: A B F */
|
|
||||||
static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c };
|
|
||||||
static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 };
|
|
||||||
static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
|
|
||||||
static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
|
|
||||||
static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
|
|
||||||
|
|
||||||
void ep93xx_gpio_update_int_params(unsigned port)
|
|
||||||
{
|
|
||||||
BUG_ON(port > 2);
|
|
||||||
|
|
||||||
__raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
|
|
||||||
|
|
||||||
__raw_writeb(gpio_int_type2[port],
|
|
||||||
EP93XX_GPIO_REG(int_type2_register_offset[port]));
|
|
||||||
|
|
||||||
__raw_writeb(gpio_int_type1[port],
|
|
||||||
EP93XX_GPIO_REG(int_type1_register_offset[port]));
|
|
||||||
|
|
||||||
__raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
|
|
||||||
EP93XX_GPIO_REG(int_en_register_offset[port]));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ep93xx_gpio_int_mask(unsigned line)
|
|
||||||
{
|
|
||||||
gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
|
|
||||||
{
|
|
||||||
int line = irq_to_gpio(irq);
|
|
||||||
int port = line >> 3;
|
|
||||||
int port_mask = 1 << (line & 7);
|
|
||||||
|
|
||||||
if (enable)
|
|
||||||
gpio_int_debounce[port] |= port_mask;
|
|
||||||
else
|
|
||||||
gpio_int_debounce[port] &= ~port_mask;
|
|
||||||
|
|
||||||
__raw_writeb(gpio_int_debounce[port],
|
|
||||||
EP93XX_GPIO_REG(int_debounce_register_offset[port]));
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* EP93xx IRQ handling
|
* EP93xx IRQ handling
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
|
extern void ep93xx_gpio_init_irq(void);
|
||||||
{
|
|
||||||
unsigned char status;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (status & (1 << i)) {
|
|
||||||
int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
|
|
||||||
generic_handle_irq(gpio_irq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (status & (1 << i)) {
|
|
||||||
int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
|
|
||||||
generic_handle_irq(gpio_irq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* map discontiguous hw irq range to continous sw irq range:
|
|
||||||
*
|
|
||||||
* IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
|
|
||||||
*/
|
|
||||||
int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
|
|
||||||
int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
|
|
||||||
|
|
||||||
generic_handle_irq(gpio_irq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ep93xx_gpio_irq_ack(unsigned int irq)
|
|
||||||
{
|
|
||||||
int line = irq_to_gpio(irq);
|
|
||||||
int port = line >> 3;
|
|
||||||
int port_mask = 1 << (line & 7);
|
|
||||||
|
|
||||||
if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
|
|
||||||
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
|
|
||||||
ep93xx_gpio_update_int_params(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
|
|
||||||
{
|
|
||||||
int line = irq_to_gpio(irq);
|
|
||||||
int port = line >> 3;
|
|
||||||
int port_mask = 1 << (line & 7);
|
|
||||||
|
|
||||||
if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
|
|
||||||
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
|
|
||||||
|
|
||||||
gpio_int_unmasked[port] &= ~port_mask;
|
|
||||||
ep93xx_gpio_update_int_params(port);
|
|
||||||
|
|
||||||
__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ep93xx_gpio_irq_mask(unsigned int irq)
|
|
||||||
{
|
|
||||||
int line = irq_to_gpio(irq);
|
|
||||||
int port = line >> 3;
|
|
||||||
|
|
||||||
gpio_int_unmasked[port] &= ~(1 << (line & 7));
|
|
||||||
ep93xx_gpio_update_int_params(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ep93xx_gpio_irq_unmask(unsigned int irq)
|
|
||||||
{
|
|
||||||
int line = irq_to_gpio(irq);
|
|
||||||
int port = line >> 3;
|
|
||||||
|
|
||||||
gpio_int_unmasked[port] |= 1 << (line & 7);
|
|
||||||
ep93xx_gpio_update_int_params(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* gpio_int_type1 controls whether the interrupt is level (0) or
|
|
||||||
* edge (1) triggered, while gpio_int_type2 controls whether it
|
|
||||||
* triggers on low/falling (0) or high/rising (1).
|
|
||||||
*/
|
|
||||||
static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
|
|
||||||
{
|
|
||||||
struct irq_desc *desc = irq_desc + irq;
|
|
||||||
const int gpio = irq_to_gpio(irq);
|
|
||||||
const int port = gpio >> 3;
|
|
||||||
const int port_mask = 1 << (gpio & 7);
|
|
||||||
|
|
||||||
gpio_direction_input(gpio);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case IRQ_TYPE_EDGE_RISING:
|
|
||||||
gpio_int_type1[port] |= port_mask;
|
|
||||||
gpio_int_type2[port] |= port_mask;
|
|
||||||
desc->handle_irq = handle_edge_irq;
|
|
||||||
break;
|
|
||||||
case IRQ_TYPE_EDGE_FALLING:
|
|
||||||
gpio_int_type1[port] |= port_mask;
|
|
||||||
gpio_int_type2[port] &= ~port_mask;
|
|
||||||
desc->handle_irq = handle_edge_irq;
|
|
||||||
break;
|
|
||||||
case IRQ_TYPE_LEVEL_HIGH:
|
|
||||||
gpio_int_type1[port] &= ~port_mask;
|
|
||||||
gpio_int_type2[port] |= port_mask;
|
|
||||||
desc->handle_irq = handle_level_irq;
|
|
||||||
break;
|
|
||||||
case IRQ_TYPE_LEVEL_LOW:
|
|
||||||
gpio_int_type1[port] &= ~port_mask;
|
|
||||||
gpio_int_type2[port] &= ~port_mask;
|
|
||||||
desc->handle_irq = handle_level_irq;
|
|
||||||
break;
|
|
||||||
case IRQ_TYPE_EDGE_BOTH:
|
|
||||||
gpio_int_type1[port] |= port_mask;
|
|
||||||
/* set initial polarity based on current input level */
|
|
||||||
if (gpio_get_value(gpio))
|
|
||||||
gpio_int_type2[port] &= ~port_mask; /* falling */
|
|
||||||
else
|
|
||||||
gpio_int_type2[port] |= port_mask; /* rising */
|
|
||||||
desc->handle_irq = handle_edge_irq;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pr_err("ep93xx: failed to set irq type %d for gpio %d\n",
|
|
||||||
type, gpio);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_int_enabled[port] |= port_mask;
|
|
||||||
|
|
||||||
desc->status &= ~IRQ_TYPE_SENSE_MASK;
|
|
||||||
desc->status |= type & IRQ_TYPE_SENSE_MASK;
|
|
||||||
|
|
||||||
ep93xx_gpio_update_int_params(port);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip ep93xx_gpio_irq_chip = {
|
|
||||||
.name = "GPIO",
|
|
||||||
.ack = ep93xx_gpio_irq_ack,
|
|
||||||
.mask_ack = ep93xx_gpio_irq_mask_ack,
|
|
||||||
.mask = ep93xx_gpio_irq_mask,
|
|
||||||
.unmask = ep93xx_gpio_irq_unmask,
|
|
||||||
.set_type = ep93xx_gpio_irq_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void __init ep93xx_init_irq(void)
|
void __init ep93xx_init_irq(void)
|
||||||
{
|
{
|
||||||
int gpio_irq;
|
|
||||||
|
|
||||||
vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
|
vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
|
||||||
vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
|
vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
|
||||||
|
|
||||||
for (gpio_irq = gpio_to_irq(0);
|
ep93xx_gpio_init_irq();
|
||||||
gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
|
|
||||||
set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
|
|
||||||
set_irq_handler(gpio_irq, handle_level_irq);
|
|
||||||
set_irq_flags(gpio_irq, IRQF_VALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
|
|
||||||
set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -572,9 +385,9 @@ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
|
||||||
* CMOS driver.
|
* CMOS driver.
|
||||||
*/
|
*/
|
||||||
if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
|
if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
|
||||||
pr_warning("ep93xx: sda != EEDAT, open drain has no effect\n");
|
pr_warning("sda != EEDAT, open drain has no effect\n");
|
||||||
if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
|
if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
|
||||||
pr_warning("ep93xx: scl != EECLK, open drain has no effect\n");
|
pr_warning("scl != EECLK, open drain has no effect\n");
|
||||||
|
|
||||||
__raw_writel((data->sda_is_open_drain << 1) |
|
__raw_writel((data->sda_is_open_drain << 1) |
|
||||||
(data->scl_is_open_drain << 0),
|
(data->scl_is_open_drain << 0),
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
* with this implementation.
|
* with this implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
@ -173,7 +175,7 @@ static irqreturn_t m2p_irq(int irq, void *dev_id)
|
||||||
|
|
||||||
switch (m2p_channel_state(ch)) {
|
switch (m2p_channel_state(ch)) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
pr_crit("m2p_irq: dma interrupt without a dma buffer\n");
|
pr_crit("dma interrupt without a dma buffer\n");
|
||||||
BUG();
|
BUG();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -197,7 +199,7 @@ static irqreturn_t m2p_irq(int irq, void *dev_id)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_NEXT:
|
case STATE_NEXT:
|
||||||
pr_crit("m2p_irq: dma interrupt while next\n");
|
pr_crit("dma interrupt while next\n");
|
||||||
BUG();
|
BUG();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,12 +118,33 @@ static void __init edb93xx_register_i2c(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* EDB93xx pwm
|
||||||
|
*************************************************************************/
|
||||||
|
static void __init edb93xx_register_pwm(void)
|
||||||
|
{
|
||||||
|
if (machine_is_edb9301() ||
|
||||||
|
machine_is_edb9302() || machine_is_edb9302a()) {
|
||||||
|
/* EP9301 and EP9302 only have pwm.1 (EGPIO14) */
|
||||||
|
ep93xx_register_pwm(0, 1);
|
||||||
|
} else if (machine_is_edb9307() || machine_is_edb9307a()) {
|
||||||
|
/* EP9307 only has pwm.0 (PWMOUT) */
|
||||||
|
ep93xx_register_pwm(1, 0);
|
||||||
|
} else {
|
||||||
|
/* EP9312 and EP9315 have both */
|
||||||
|
ep93xx_register_pwm(1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void __init edb93xx_init_machine(void)
|
static void __init edb93xx_init_machine(void)
|
||||||
{
|
{
|
||||||
ep93xx_init_devices();
|
ep93xx_init_devices();
|
||||||
edb93xx_register_flash();
|
edb93xx_register_flash();
|
||||||
ep93xx_register_eth(&edb93xx_eth_data, 1);
|
ep93xx_register_eth(&edb93xx_eth_data, 1);
|
||||||
edb93xx_register_i2c();
|
edb93xx_register_i2c();
|
||||||
|
edb93xx_register_pwm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
@ -22,6 +24,235 @@
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* GPIO handling for EP93xx
|
||||||
|
*************************************************************************/
|
||||||
|
static unsigned char gpio_int_unmasked[3];
|
||||||
|
static unsigned char gpio_int_enabled[3];
|
||||||
|
static unsigned char gpio_int_type1[3];
|
||||||
|
static unsigned char gpio_int_type2[3];
|
||||||
|
static unsigned char gpio_int_debounce[3];
|
||||||
|
|
||||||
|
/* Port ordering is: A B F */
|
||||||
|
static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c };
|
||||||
|
static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 };
|
||||||
|
static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
|
||||||
|
static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
|
||||||
|
static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
|
||||||
|
|
||||||
|
void ep93xx_gpio_update_int_params(unsigned port)
|
||||||
|
{
|
||||||
|
BUG_ON(port > 2);
|
||||||
|
|
||||||
|
__raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
|
||||||
|
|
||||||
|
__raw_writeb(gpio_int_type2[port],
|
||||||
|
EP93XX_GPIO_REG(int_type2_register_offset[port]));
|
||||||
|
|
||||||
|
__raw_writeb(gpio_int_type1[port],
|
||||||
|
EP93XX_GPIO_REG(int_type1_register_offset[port]));
|
||||||
|
|
||||||
|
__raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
|
||||||
|
EP93XX_GPIO_REG(int_en_register_offset[port]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ep93xx_gpio_int_mask(unsigned line)
|
||||||
|
{
|
||||||
|
gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
|
||||||
|
{
|
||||||
|
int line = irq_to_gpio(irq);
|
||||||
|
int port = line >> 3;
|
||||||
|
int port_mask = 1 << (line & 7);
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
gpio_int_debounce[port] |= port_mask;
|
||||||
|
else
|
||||||
|
gpio_int_debounce[port] &= ~port_mask;
|
||||||
|
|
||||||
|
__raw_writeb(gpio_int_debounce[port],
|
||||||
|
EP93XX_GPIO_REG(int_debounce_register_offset[port]));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
|
||||||
|
|
||||||
|
static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
unsigned char status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (status & (1 << i)) {
|
||||||
|
int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
|
||||||
|
generic_handle_irq(gpio_irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (status & (1 << i)) {
|
||||||
|
int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
|
||||||
|
generic_handle_irq(gpio_irq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* map discontiguous hw irq range to continous sw irq range:
|
||||||
|
*
|
||||||
|
* IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
|
||||||
|
*/
|
||||||
|
int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
|
||||||
|
int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
|
||||||
|
|
||||||
|
generic_handle_irq(gpio_irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ep93xx_gpio_irq_ack(unsigned int irq)
|
||||||
|
{
|
||||||
|
int line = irq_to_gpio(irq);
|
||||||
|
int port = line >> 3;
|
||||||
|
int port_mask = 1 << (line & 7);
|
||||||
|
|
||||||
|
if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
|
||||||
|
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
|
||||||
|
ep93xx_gpio_update_int_params(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
|
||||||
|
{
|
||||||
|
int line = irq_to_gpio(irq);
|
||||||
|
int port = line >> 3;
|
||||||
|
int port_mask = 1 << (line & 7);
|
||||||
|
|
||||||
|
if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
|
||||||
|
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
|
||||||
|
|
||||||
|
gpio_int_unmasked[port] &= ~port_mask;
|
||||||
|
ep93xx_gpio_update_int_params(port);
|
||||||
|
|
||||||
|
__raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ep93xx_gpio_irq_mask(unsigned int irq)
|
||||||
|
{
|
||||||
|
int line = irq_to_gpio(irq);
|
||||||
|
int port = line >> 3;
|
||||||
|
|
||||||
|
gpio_int_unmasked[port] &= ~(1 << (line & 7));
|
||||||
|
ep93xx_gpio_update_int_params(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ep93xx_gpio_irq_unmask(unsigned int irq)
|
||||||
|
{
|
||||||
|
int line = irq_to_gpio(irq);
|
||||||
|
int port = line >> 3;
|
||||||
|
|
||||||
|
gpio_int_unmasked[port] |= 1 << (line & 7);
|
||||||
|
ep93xx_gpio_update_int_params(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gpio_int_type1 controls whether the interrupt is level (0) or
|
||||||
|
* edge (1) triggered, while gpio_int_type2 controls whether it
|
||||||
|
* triggers on low/falling (0) or high/rising (1).
|
||||||
|
*/
|
||||||
|
static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
|
||||||
|
{
|
||||||
|
struct irq_desc *desc = irq_desc + irq;
|
||||||
|
const int gpio = irq_to_gpio(irq);
|
||||||
|
const int port = gpio >> 3;
|
||||||
|
const int port_mask = 1 << (gpio & 7);
|
||||||
|
|
||||||
|
gpio_direction_input(gpio);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case IRQ_TYPE_EDGE_RISING:
|
||||||
|
gpio_int_type1[port] |= port_mask;
|
||||||
|
gpio_int_type2[port] |= port_mask;
|
||||||
|
desc->handle_irq = handle_edge_irq;
|
||||||
|
break;
|
||||||
|
case IRQ_TYPE_EDGE_FALLING:
|
||||||
|
gpio_int_type1[port] |= port_mask;
|
||||||
|
gpio_int_type2[port] &= ~port_mask;
|
||||||
|
desc->handle_irq = handle_edge_irq;
|
||||||
|
break;
|
||||||
|
case IRQ_TYPE_LEVEL_HIGH:
|
||||||
|
gpio_int_type1[port] &= ~port_mask;
|
||||||
|
gpio_int_type2[port] |= port_mask;
|
||||||
|
desc->handle_irq = handle_level_irq;
|
||||||
|
break;
|
||||||
|
case IRQ_TYPE_LEVEL_LOW:
|
||||||
|
gpio_int_type1[port] &= ~port_mask;
|
||||||
|
gpio_int_type2[port] &= ~port_mask;
|
||||||
|
desc->handle_irq = handle_level_irq;
|
||||||
|
break;
|
||||||
|
case IRQ_TYPE_EDGE_BOTH:
|
||||||
|
gpio_int_type1[port] |= port_mask;
|
||||||
|
/* set initial polarity based on current input level */
|
||||||
|
if (gpio_get_value(gpio))
|
||||||
|
gpio_int_type2[port] &= ~port_mask; /* falling */
|
||||||
|
else
|
||||||
|
gpio_int_type2[port] |= port_mask; /* rising */
|
||||||
|
desc->handle_irq = handle_edge_irq;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_int_enabled[port] |= port_mask;
|
||||||
|
|
||||||
|
desc->status &= ~IRQ_TYPE_SENSE_MASK;
|
||||||
|
desc->status |= type & IRQ_TYPE_SENSE_MASK;
|
||||||
|
|
||||||
|
ep93xx_gpio_update_int_params(port);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip ep93xx_gpio_irq_chip = {
|
||||||
|
.name = "GPIO",
|
||||||
|
.ack = ep93xx_gpio_irq_ack,
|
||||||
|
.mask_ack = ep93xx_gpio_irq_mask_ack,
|
||||||
|
.mask = ep93xx_gpio_irq_mask,
|
||||||
|
.unmask = ep93xx_gpio_irq_unmask,
|
||||||
|
.set_type = ep93xx_gpio_irq_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init ep93xx_gpio_init_irq(void)
|
||||||
|
{
|
||||||
|
int gpio_irq;
|
||||||
|
|
||||||
|
for (gpio_irq = gpio_to_irq(0);
|
||||||
|
gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
|
||||||
|
set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
|
||||||
|
set_irq_handler(gpio_irq, handle_level_irq);
|
||||||
|
set_irq_flags(gpio_irq, IRQF_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* gpiolib interface for EP93xx on-chip GPIOs
|
||||||
|
*************************************************************************/
|
||||||
struct ep93xx_gpio_chip {
|
struct ep93xx_gpio_chip {
|
||||||
struct gpio_chip chip;
|
struct gpio_chip chip;
|
||||||
|
|
||||||
|
@ -31,10 +262,6 @@ struct ep93xx_gpio_chip {
|
||||||
|
|
||||||
#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
|
#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
|
||||||
|
|
||||||
/* From core.c */
|
|
||||||
extern void ep93xx_gpio_int_mask(unsigned line);
|
|
||||||
extern void ep93xx_gpio_update_int_params(unsigned port);
|
|
||||||
|
|
||||||
static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||||
{
|
{
|
||||||
struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
|
struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*/
|
*/
|
||||||
#include <mach/ep93xx-regs.h>
|
#include <mach/ep93xx-regs.h>
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
ldreq \rx, =EP93XX_APB_PHYS_BASE @ Physical base
|
ldreq \rx, =EP93XX_APB_PHYS_BASE @ Physical base
|
||||||
|
|
|
@ -92,21 +92,6 @@
|
||||||
|
|
||||||
/* APB peripherals */
|
/* APB peripherals */
|
||||||
#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000)
|
#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000)
|
||||||
#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
|
|
||||||
#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
|
|
||||||
#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
|
|
||||||
#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08)
|
|
||||||
#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c)
|
|
||||||
#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
|
|
||||||
#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
|
|
||||||
#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
|
|
||||||
#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
|
|
||||||
#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60)
|
|
||||||
#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64)
|
|
||||||
#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80)
|
|
||||||
#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84)
|
|
||||||
#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
|
|
||||||
#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
|
|
||||||
|
|
||||||
#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
|
#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
|
||||||
|
|
||||||
|
@ -167,8 +152,11 @@
|
||||||
#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 (1<<16)
|
#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 (1<<16)
|
||||||
#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08)
|
#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08)
|
||||||
#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
|
#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
|
||||||
#define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20)
|
#define EP93XX_SYSCON_CLKSET1 EP93XX_SYSCON_REG(0x20)
|
||||||
#define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24)
|
#define EP93XX_SYSCON_CLKSET1_NBYP1 (1<<23)
|
||||||
|
#define EP93XX_SYSCON_CLKSET2 EP93XX_SYSCON_REG(0x24)
|
||||||
|
#define EP93XX_SYSCON_CLKSET2_NBYP2 (1<<19)
|
||||||
|
#define EP93XX_SYSCON_CLKSET2_PLL2_EN (1<<18)
|
||||||
#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80)
|
#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80)
|
||||||
#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31)
|
#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31)
|
||||||
#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30)
|
#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30)
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
* arch/arm/mach-ep93xx/include/mach/vmalloc.h
|
* arch/arm/mach-ep93xx/include/mach/vmalloc.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VMALLOC_END 0xfe800000
|
#define VMALLOC_END 0xfe800000UL
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* arch/arm/mach-ep93xx/simone.c
|
||||||
|
* Simplemachines Sim.One support.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.com>
|
||||||
|
*
|
||||||
|
* Based on the 2.6.24.7 support:
|
||||||
|
* Copyright (C) 2009 Simplemachines
|
||||||
|
* MMC support by Peter Ivanov <ivanovp@gmail.com>, 2007
|
||||||
|
*
|
||||||
|
* 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/platform_device.h>
|
||||||
|
#include <linux/mtd/physmap.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/i2c-gpio.h>
|
||||||
|
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
#include <mach/fb.h>
|
||||||
|
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
|
||||||
|
static struct physmap_flash_data simone_flash_data = {
|
||||||
|
.width = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource simone_flash_resource = {
|
||||||
|
.start = EP93XX_CS6_PHYS_BASE,
|
||||||
|
.end = EP93XX_CS6_PHYS_BASE + SZ_8M - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device simone_flash = {
|
||||||
|
.name = "physmap-flash",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = 1,
|
||||||
|
.resource = &simone_flash_resource,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &simone_flash_data,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ep93xx_eth_data simone_eth_data = {
|
||||||
|
.phy_id = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ep93xxfb_mach_info simone_fb_info = {
|
||||||
|
.num_modes = EP93XXFB_USE_MODEDB,
|
||||||
|
.bpp = 16,
|
||||||
|
.flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_gpio_platform_data simone_i2c_gpio_data = {
|
||||||
|
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
|
||||||
|
.sda_is_open_drain = 0,
|
||||||
|
.scl_pin = EP93XX_GPIO_LINE_EECLK,
|
||||||
|
.scl_is_open_drain = 0,
|
||||||
|
.udelay = 0,
|
||||||
|
.timeout = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_board_info __initdata simone_i2c_board_info[] = {
|
||||||
|
{
|
||||||
|
I2C_BOARD_INFO("ds1337", 0x68),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init simone_init_machine(void)
|
||||||
|
{
|
||||||
|
ep93xx_init_devices();
|
||||||
|
|
||||||
|
platform_device_register(&simone_flash);
|
||||||
|
ep93xx_register_eth(&simone_eth_data, 1);
|
||||||
|
ep93xx_register_fb(&simone_fb_info);
|
||||||
|
ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
|
||||||
|
ARRAY_SIZE(simone_i2c_board_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
|
||||||
|
/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
|
||||||
|
.phys_io = EP93XX_APB_PHYS_BASE,
|
||||||
|
.io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
|
||||||
|
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
|
||||||
|
.map_io = ep93xx_map_io,
|
||||||
|
.init_irq = ep93xx_init_irq,
|
||||||
|
.timer = &ep93xx_timer,
|
||||||
|
.init_machine = simone_init_machine,
|
||||||
|
MACHINE_END
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* arch/arm/mach-ep93xx/snappercl15.c
|
||||||
|
* Bluewater Systems Snapper CL15 system module
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Bluewater Systems Ltd
|
||||||
|
* Author: Ryan Mallon <ryan@bluewatersys.com>
|
||||||
|
*
|
||||||
|
* NAND code adapted from driver by:
|
||||||
|
* Andre Renaud <andre@bluewatersys.com>
|
||||||
|
* James R. McKaskill
|
||||||
|
*
|
||||||
|
* 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/platform_device.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/i2c-gpio.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
|
||||||
|
#include <linux/mtd/partitions.h>
|
||||||
|
#include <linux/mtd/nand.h>
|
||||||
|
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
#include <mach/fb.h>
|
||||||
|
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
|
||||||
|
#define SNAPPERCL15_NAND_BASE (EP93XX_CS7_PHYS_BASE + SZ_16M)
|
||||||
|
|
||||||
|
#define SNAPPERCL15_NAND_WPN (1 << 8) /* Write protect (active low) */
|
||||||
|
#define SNAPPERCL15_NAND_ALE (1 << 9) /* Address latch */
|
||||||
|
#define SNAPPERCL15_NAND_CLE (1 << 10) /* Command latch */
|
||||||
|
#define SNAPPERCL15_NAND_CEN (1 << 11) /* Chip enable (active low) */
|
||||||
|
#define SNAPPERCL15_NAND_RDY (1 << 14) /* Device ready */
|
||||||
|
|
||||||
|
#define NAND_CTRL_ADDR(chip) (chip->IO_ADDR_W + 0x40)
|
||||||
|
|
||||||
|
static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
||||||
|
unsigned int ctrl)
|
||||||
|
{
|
||||||
|
struct nand_chip *chip = mtd->priv;
|
||||||
|
static u16 nand_state = SNAPPERCL15_NAND_WPN;
|
||||||
|
u16 set;
|
||||||
|
|
||||||
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
|
set = SNAPPERCL15_NAND_CEN | SNAPPERCL15_NAND_WPN;
|
||||||
|
|
||||||
|
if (ctrl & NAND_NCE)
|
||||||
|
set &= ~SNAPPERCL15_NAND_CEN;
|
||||||
|
if (ctrl & NAND_CLE)
|
||||||
|
set |= SNAPPERCL15_NAND_CLE;
|
||||||
|
if (ctrl & NAND_ALE)
|
||||||
|
set |= SNAPPERCL15_NAND_ALE;
|
||||||
|
|
||||||
|
nand_state &= ~(SNAPPERCL15_NAND_CEN |
|
||||||
|
SNAPPERCL15_NAND_CLE |
|
||||||
|
SNAPPERCL15_NAND_ALE);
|
||||||
|
nand_state |= set;
|
||||||
|
__raw_writew(nand_state, NAND_CTRL_ADDR(chip));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd != NAND_CMD_NONE)
|
||||||
|
__raw_writew((cmd & 0xff) | nand_state, chip->IO_ADDR_W);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
|
||||||
|
{
|
||||||
|
struct nand_chip *chip = mtd->priv;
|
||||||
|
|
||||||
|
return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *snappercl15_nand_part_probes[] = {"cmdlinepart", NULL};
|
||||||
|
|
||||||
|
static struct mtd_partition snappercl15_nand_parts[] = {
|
||||||
|
{
|
||||||
|
.name = "Kernel",
|
||||||
|
.offset = 0,
|
||||||
|
.size = SZ_2M,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "Filesystem",
|
||||||
|
.offset = MTDPART_OFS_APPEND,
|
||||||
|
.size = MTDPART_SIZ_FULL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_nand_data snappercl15_nand_data = {
|
||||||
|
.chip = {
|
||||||
|
.nr_chips = 1,
|
||||||
|
.part_probe_types = snappercl15_nand_part_probes,
|
||||||
|
.partitions = snappercl15_nand_parts,
|
||||||
|
.nr_partitions = ARRAY_SIZE(snappercl15_nand_parts),
|
||||||
|
.options = NAND_NO_AUTOINCR,
|
||||||
|
.chip_delay = 25,
|
||||||
|
},
|
||||||
|
.ctrl = {
|
||||||
|
.dev_ready = snappercl15_nand_dev_ready,
|
||||||
|
.cmd_ctrl = snappercl15_nand_cmd_ctrl,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource snappercl15_nand_resource[] = {
|
||||||
|
{
|
||||||
|
.start = SNAPPERCL15_NAND_BASE,
|
||||||
|
.end = SNAPPERCL15_NAND_BASE + SZ_4K - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device snappercl15_nand_device = {
|
||||||
|
.name = "gen_nand",
|
||||||
|
.id = -1,
|
||||||
|
.dev.platform_data = &snappercl15_nand_data,
|
||||||
|
.resource = snappercl15_nand_resource,
|
||||||
|
.num_resources = ARRAY_SIZE(snappercl15_nand_resource),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ep93xx_eth_data snappercl15_eth_data = {
|
||||||
|
.phy_id = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_gpio_platform_data snappercl15_i2c_gpio_data = {
|
||||||
|
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
|
||||||
|
.sda_is_open_drain = 0,
|
||||||
|
.scl_pin = EP93XX_GPIO_LINE_EECLK,
|
||||||
|
.scl_is_open_drain = 0,
|
||||||
|
.udelay = 0,
|
||||||
|
.timeout = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_board_info __initdata snappercl15_i2c_data[] = {
|
||||||
|
{
|
||||||
|
/* Audio codec */
|
||||||
|
I2C_BOARD_INFO("tlv320aic23", 0x1a),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ep93xxfb_mach_info snappercl15_fb_info = {
|
||||||
|
.num_modes = EP93XXFB_USE_MODEDB,
|
||||||
|
.bpp = 16,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init snappercl15_init_machine(void)
|
||||||
|
{
|
||||||
|
ep93xx_init_devices();
|
||||||
|
ep93xx_register_eth(&snappercl15_eth_data, 1);
|
||||||
|
ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data,
|
||||||
|
ARRAY_SIZE(snappercl15_i2c_data));
|
||||||
|
ep93xx_register_fb(&snappercl15_fb_info);
|
||||||
|
platform_device_register(&snappercl15_nand_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
|
||||||
|
/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
|
||||||
|
.phys_io = EP93XX_APB_PHYS_BASE,
|
||||||
|
.io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
|
||||||
|
.boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
|
||||||
|
.map_io = ep93xx_map_io,
|
||||||
|
.init_irq = ep93xx_init_irq,
|
||||||
|
.timer = &ep93xx_timer,
|
||||||
|
.init_machine = snappercl15_init_machine,
|
||||||
|
MACHINE_END
|
|
@ -32,12 +32,13 @@ unsigned int mem_fclk_21285 = 50000000;
|
||||||
|
|
||||||
EXPORT_SYMBOL(mem_fclk_21285);
|
EXPORT_SYMBOL(mem_fclk_21285);
|
||||||
|
|
||||||
static void __init early_fclk(char **arg)
|
static int __init early_fclk(char *arg)
|
||||||
{
|
{
|
||||||
mem_fclk_21285 = simple_strtoul(*arg, arg, 0);
|
mem_fclk_21285 = simple_strtoul(arg, NULL, 0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__early_param("mem_fclk_21285=", early_fclk);
|
early_param("mem_fclk_21285", early_fclk);
|
||||||
|
|
||||||
static int __init parse_tag_memclk(const struct tag *tag)
|
static int __init parse_tag_memclk(const struct tag *tag)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#ifndef CONFIG_DEBUG_DC21285_PORT
|
#ifndef CONFIG_DEBUG_DC21285_PORT
|
||||||
/* For NetWinder debugging */
|
/* For NetWinder debugging */
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
moveq \rx, #0x7c000000 @ physical
|
moveq \rx, #0x7c000000 @ physical
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
.equ dc21285_high, ARMCSR_BASE & 0xff000000
|
.equ dc21285_high, ARMCSR_BASE & 0xff000000
|
||||||
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff
|
.equ dc21285_low, ARMCSR_BASE & 0x00ffffff
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
moveq \rx, #0x42000000
|
moveq \rx, #0x42000000
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*/
|
*/
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
ldreq \rx, =GEMINI_UART_BASE @ physical
|
ldreq \rx, =GEMINI_UART_BASE @ physical
|
||||||
|
|
|
@ -7,4 +7,4 @@
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VMALLOC_END 0xF0000000
|
#define VMALLOC_END 0xf0000000UL
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
.equ io_virt, IO_BASE
|
.equ io_virt, IO_BASE
|
||||||
.equ io_phys, IO_START
|
.equ io_phys, IO_START
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
moveq \rx, #io_phys @ physical base address
|
moveq \rx, #io_phys @ physical base address
|
||||||
|
|
|
@ -144,8 +144,7 @@ static int __init integrator_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(lookups); i++)
|
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||||
clkdev_add(&lookups[i]);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||||
struct amba_device *d = amba_devs[i];
|
struct amba_device *d = amba_devs[i];
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
moveq \rx, #0x16000000 @ physical base address
|
moveq \rx, #0x16000000 @ physical base address
|
||||||
|
|
|
@ -558,9 +558,7 @@ static void __init intcp_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cp_lookups); i++)
|
clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
|
||||||
clkdev_add(&cp_lookups[i]);
|
|
||||||
|
|
||||||
platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
|
platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.macro addruart, rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ mmu enabled?
|
tst \rx, #1 @ mmu enabled?
|
||||||
moveq \rx, #0xff000000 @ physical
|
moveq \rx, #0xff000000 @ physical
|
||||||
|
|
|
@ -61,9 +61,9 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
|
||||||
(cookie - IOP13XX_PCIE_LOWER_MEM_RA));
|
(cookie - IOP13XX_PCIE_LOWER_MEM_RA));
|
||||||
break;
|
break;
|
||||||
case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
|
case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
|
||||||
retval = __arm_ioremap(IOP13XX_PBI_LOWER_MEM_PA +
|
retval = __arm_ioremap_caller(IOP13XX_PBI_LOWER_MEM_PA +
|
||||||
(cookie - IOP13XX_PBI_LOWER_MEM_RA),
|
(cookie - IOP13XX_PBI_LOWER_MEM_RA),
|
||||||
size, mtype);
|
size, mtype, __builtin_return_address(0));
|
||||||
break;
|
break;
|
||||||
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
|
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
|
||||||
retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
|
retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
|
||||||
|
@ -75,7 +75,8 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
|
||||||
retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
|
retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
retval = __arm_ioremap(cookie, size, mtype);
|
retval = __arm_ioremap_caller(cookie, size, mtype,
|
||||||
|
__builtin_return_address(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.macro addruart, rx
|
.macro addruart, rx, tmp
|
||||||
mov \rx, #0xfe000000 @ physical as well as virtual
|
mov \rx, #0xfe000000 @ physical as well as virtual
|
||||||
orr \rx, \rx, #0x00800000 @ location of the UART
|
orr \rx, \rx, #0x00800000 @ location of the UART
|
||||||
.endm
|
.endm
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
* arch/arm/mach-iop32x/include/mach/vmalloc.h
|
* arch/arm/mach-iop32x/include/mach/vmalloc.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VMALLOC_END 0xfe000000
|
#define VMALLOC_END 0xfe000000UL
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.macro addruart, rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ mmu enabled?
|
tst \rx, #1 @ mmu enabled?
|
||||||
moveq \rx, #0xff000000 @ physical
|
moveq \rx, #0xff000000 @ physical
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
* arch/arm/mach-iop33x/include/mach/vmalloc.h
|
* arch/arm/mach-iop33x/include/mach/vmalloc.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VMALLOC_END 0xfe000000
|
#define VMALLOC_END 0xfe000000UL
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ MMU enabled?
|
tst \rx, #1 @ MMU enabled?
|
||||||
moveq \rx, #0xc0000000 @ Physical base
|
moveq \rx, #0xc0000000 @ Physical base
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
|
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
|
||||||
* area for the same reason. ;)
|
* area for the same reason. ;)
|
||||||
*/
|
*/
|
||||||
#define VMALLOC_END 0xfb000000
|
#define VMALLOC_END 0xfb000000UL
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
*/
|
*/
|
||||||
#include <mach/ixp23xx.h>
|
#include <mach/ixp23xx.h>
|
||||||
|
|
||||||
.macro addruart,rx
|
.macro addruart, rx, tmp
|
||||||
mrc p15, 0, \rx, c1, c0
|
mrc p15, 0, \rx, c1, c0
|
||||||
tst \rx, #1 @ mmu enabled?
|
tst \rx, #1 @ mmu enabled?
|
||||||
ldreq \rx, =IXP23XX_PERIPHERAL_PHYS @ physical
|
ldreq \rx, =IXP23XX_PERIPHERAL_PHYS @ physical
|
||||||
|
|
|
@ -7,4 +7,4 @@
|
||||||
* specific static I/O.
|
* specific static I/O.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VMALLOC_END (0xec000000)
|
#define VMALLOC_END (0xec000000UL)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue