mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (50 commits) [ARM] sa1100: remove boot time RTC initialisation [ARM] sa1100: stop doing our own rtc management over suspend [ARM] 4474/1: Do not check the PSR_F_BIT in valid_user_regs [ARM] 4473/2: Take the HWCAP definitions out of the elf.h file [ARM] pxa: move platform devices to separate header file [ARM] pxa: move device registration into CPU-specific file [ARM] pxa: remove boot time RTC initialisation [ARM] pxa: stop doing our own rtc management over suspend [ARM] 4451/1: pxa: make dma.c generic and remove cpu specific dma code [ARM] 4450/1: pxa: add pxa25x_init_irq() and pxa27x_init_irq() [ARM] 4440/1: PXA: enable the checking of ICIP2 for IRQs [ARM] 4438/1: PXA: remove #ifdef .. #endif from pxa_gpio_demux_handler() [ARM] 4437/1: PXA: move the GPIO IRQ initialization code to pxa_init_irq_gpio() [ARM] 4436/1: PXA: move low IRQ initialization code to pxa_init_irq_low() [ARM] 4435/1: PXA: remove PXA_INTERNAL_IRQS [ARM] 4434/1: PXA: remove PXA_IRQ_SKIP [ARM] pxa: Fix PXA27x suspend type validation, remove pxa_pm_prepare() [ARM] pxa: move pm_ops structure into CPU specific files [ARM] pxa: introduce cpu_is_pxaXXX macros [ARM] pxa: remove MMC register defines from pxa-regs.h ...
This commit is contained in:
commit
4aabab2181
84 changed files with 3204 additions and 489 deletions
|
@ -241,6 +241,9 @@ config ARCH_H720X
|
|||
|
||||
config ARCH_IMX
|
||||
bool "IMX"
|
||||
select GENERIC_GPIO
|
||||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
help
|
||||
Support for Motorola's i.MX family of processors (MX1, MXL).
|
||||
|
||||
|
@ -308,6 +311,7 @@ config ARCH_L7200
|
|||
|
||||
config ARCH_KS8695
|
||||
bool "Micrel/Kendin KS8695"
|
||||
select GENERIC_GPIO
|
||||
help
|
||||
Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
|
||||
System-on-Chip devices.
|
||||
|
@ -384,6 +388,7 @@ config ARCH_DAVINCI
|
|||
bool "TI DaVinci"
|
||||
select GENERIC_TIME
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_GPIO
|
||||
help
|
||||
Support for TI's DaVinci platform.
|
||||
|
||||
|
|
1
arch/arm/boot/compressed/.gitignore
vendored
1
arch/arm/boot/compressed/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
piggy.gz
|
||||
font.c
|
||||
|
|
|
@ -6,15 +6,13 @@
|
|||
|
||||
HEAD = head.o
|
||||
OBJS = misc.o
|
||||
FONTC = drivers/video/console/font_acorn_8x8.c
|
||||
|
||||
FONT = $(addprefix ../../../../drivers/video/console/, font_acorn_8x8.o)
|
||||
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
|
||||
|
||||
#
|
||||
# Architecture dependencies
|
||||
#
|
||||
ifeq ($(CONFIG_ARCH_ACORN),y)
|
||||
OBJS += ll_char_wr.o $(FONT)
|
||||
OBJS += ll_char_wr.o font.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_SHARK),y)
|
||||
|
@ -73,7 +71,7 @@ endif
|
|||
|
||||
SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
|
||||
|
||||
targets := vmlinux vmlinux.lds piggy.gz piggy.o $(FONT) \
|
||||
targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \
|
||||
head.o misc.o $(OBJS)
|
||||
EXTRA_CFLAGS := -fpic
|
||||
EXTRA_AFLAGS :=
|
||||
|
@ -105,7 +103,10 @@ $(obj)/piggy.gz: $(obj)/../Image FORCE
|
|||
|
||||
$(obj)/piggy.o: $(obj)/piggy.gz FORCE
|
||||
|
||||
CFLAGS_font_acorn_8x8.o := -Dstatic=
|
||||
CFLAGS_font.o := -Dstatic=
|
||||
|
||||
$(obj)/font.c: $(FONTC)
|
||||
$(call cmd,shipped)
|
||||
|
||||
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
|
||||
@sed "$(SEDFLAGS)" < $< > $@
|
||||
|
|
|
@ -41,11 +41,6 @@ __XScale_start:
|
|||
mov r7, #MACH_TYPE_COTULLA_IDP
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACH_GTWX5715
|
||||
mov r7, #(MACH_TYPE_GTWX5715 & 0xff)
|
||||
orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_IXP2000
|
||||
mov r1, #-1
|
||||
mov r0, #0xd6000000
|
||||
|
|
|
@ -436,6 +436,28 @@ __armv4_mmu_cache_on:
|
|||
mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
|
||||
mov pc, r12
|
||||
|
||||
__armv7_mmu_cache_on:
|
||||
mov r12, lr
|
||||
mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0
|
||||
tst r11, #0xf @ VMSA
|
||||
blne __setup_mmu
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
|
||||
tst r11, #0xf @ VMSA
|
||||
mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read control reg
|
||||
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
|
||||
orr r0, r0, #0x003c @ write buffer
|
||||
orrne r0, r0, #1 @ MMU enabled
|
||||
movne r1, #-1
|
||||
mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
|
||||
mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
|
||||
mcr p15, 0, r0, c1, c0, 0 @ load control register
|
||||
mrc p15, 0, r0, c1, c0, 0 @ and read it back
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 4 @ ISB
|
||||
mov pc, r12
|
||||
|
||||
__arm6_mmu_cache_on:
|
||||
mov r12, lr
|
||||
bl __setup_mmu
|
||||
|
@ -622,11 +644,17 @@ proc_types:
|
|||
b __armv4_mmu_cache_flush
|
||||
|
||||
.word 0x0007b000 @ ARMv6
|
||||
.word 0x0007f000
|
||||
.word 0x000ff000
|
||||
b __armv4_mmu_cache_on
|
||||
b __armv4_mmu_cache_off
|
||||
b __armv6_mmu_cache_flush
|
||||
|
||||
.word 0x000f0000 @ new CPU Id
|
||||
.word 0x000f0000
|
||||
b __armv7_mmu_cache_on
|
||||
b __armv7_mmu_cache_off
|
||||
b __armv7_mmu_cache_flush
|
||||
|
||||
.word 0 @ unrecognised type
|
||||
.word 0
|
||||
mov pc, lr
|
||||
|
@ -674,6 +702,16 @@ __armv4_mmu_cache_off:
|
|||
mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
|
||||
mov pc, lr
|
||||
|
||||
__armv7_mmu_cache_off:
|
||||
mrc p15, 0, r0, c1, c0
|
||||
bic r0, r0, #0x000d
|
||||
mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
|
||||
mov r12, lr
|
||||
bl __armv7_mmu_cache_flush
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB
|
||||
mov pc, r12
|
||||
|
||||
__arm6_mmu_cache_off:
|
||||
mov r0, #0x00000030 @ ARM6 control reg.
|
||||
b __armv3_mmu_cache_off
|
||||
|
@ -730,6 +768,59 @@ __armv6_mmu_cache_flush:
|
|||
mcr p15, 0, r1, c7, c10, 4 @ drain WB
|
||||
mov pc, lr
|
||||
|
||||
__armv7_mmu_cache_flush:
|
||||
mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1
|
||||
tst r10, #0xf << 16 @ hierarchical cache (ARMv7)
|
||||
beq hierarchical
|
||||
mov r10, #0
|
||||
mcr p15, 0, r10, c7, c14, 0 @ clean+invalidate D
|
||||
b iflush
|
||||
hierarchical:
|
||||
stmfd sp!, {r0-r5, r7, r9-r11}
|
||||
mrc p15, 1, r0, c0, c0, 1 @ read clidr
|
||||
ands r3, r0, #0x7000000 @ extract loc from clidr
|
||||
mov r3, r3, lsr #23 @ left align loc bit field
|
||||
beq finished @ if loc is 0, then no need to clean
|
||||
mov r10, #0 @ start clean at cache level 0
|
||||
loop1:
|
||||
add r2, r10, r10, lsr #1 @ work out 3x current cache level
|
||||
mov r1, r0, lsr r2 @ extract cache type bits from clidr
|
||||
and r1, r1, #7 @ mask of the bits for current cache only
|
||||
cmp r1, #2 @ see what cache we have at this level
|
||||
blt skip @ skip if no cache, or just i-cache
|
||||
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
|
||||
mcr p15, 0, r10, c7, c5, 4 @ isb to sych the new cssr&csidr
|
||||
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
|
||||
and r2, r1, #7 @ extract the length of the cache lines
|
||||
add r2, r2, #4 @ add 4 (line length offset)
|
||||
ldr r4, =0x3ff
|
||||
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
|
||||
.word 0xe16f5f14 @ clz r5, r4 - find bit position of way size increment
|
||||
ldr r7, =0x7fff
|
||||
ands r7, r7, r1, lsr #13 @ extract max number of the index size
|
||||
loop2:
|
||||
mov r9, r4 @ create working copy of max way size
|
||||
loop3:
|
||||
orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
|
||||
orr r11, r11, r7, lsl r2 @ factor index number into r11
|
||||
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
|
||||
subs r9, r9, #1 @ decrement the way
|
||||
bge loop3
|
||||
subs r7, r7, #1 @ decrement the index
|
||||
bge loop2
|
||||
skip:
|
||||
add r10, r10, #2 @ increment cache number
|
||||
cmp r3, r10
|
||||
bgt loop1
|
||||
finished:
|
||||
mov r10, #0 @ swith back to cache level 0
|
||||
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
|
||||
ldmfd sp!, {r0-r5, r7, r9-r11}
|
||||
iflush:
|
||||
mcr p15, 0, r10, c7, c5, 0 @ invalidate I+BTB
|
||||
mcr p15, 0, r10, c7, c10, 4 @ drain WB
|
||||
mov pc, lr
|
||||
|
||||
__armv4_mmu_cache_flush:
|
||||
mov r2, #64*1024 @ default: 32K dcache size (*2)
|
||||
mov r11, #32 @ default: 32 byte line size
|
||||
|
|
|
@ -766,9 +766,7 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
|
|||
}
|
||||
|
||||
static struct pm_ops sharpsl_pm_ops = {
|
||||
.prepare = pxa_pm_prepare,
|
||||
.enter = corgi_pxa_pm_enter,
|
||||
.finish = pxa_pm_finish,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ __switch_data:
|
|||
.long _end @ r7
|
||||
.long processor_id @ r4
|
||||
.long __machine_arch_type @ r5
|
||||
.long cr_alignment @ r6
|
||||
.long __atags_pointer @ r6
|
||||
.long cr_alignment @ r7
|
||||
.long init_thread_union + THREAD_START_SP @ sp
|
||||
|
||||
/*
|
||||
|
@ -29,6 +30,7 @@ __switch_data:
|
|||
*
|
||||
* r0 = cp#15 control register
|
||||
* r1 = machine ID
|
||||
* r2 = atags pointer
|
||||
* r9 = processor ID
|
||||
*/
|
||||
.type __mmap_switched, %function
|
||||
|
@ -47,11 +49,12 @@ __mmap_switched:
|
|||
strcc fp, [r6],#4
|
||||
bcc 1b
|
||||
|
||||
ldmia r3, {r4, r5, r6, sp}
|
||||
ldmia r3, {r4, r5, r6, r7, sp}
|
||||
str r9, [r4] @ Save processor ID
|
||||
str r1, [r5] @ Save machine type
|
||||
str r2, [r6] @ Save atags pointer
|
||||
bic r4, r0, #CR_A @ Clear 'A' bit
|
||||
stmia r6, {r0, r4} @ Save control register values
|
||||
stmia r7, {r0, r4} @ Save control register values
|
||||
b start_kernel
|
||||
|
||||
/*
|
||||
|
@ -215,3 +218,34 @@ ENTRY(lookup_machine_type)
|
|||
bl __lookup_machine_type
|
||||
mov r0, r5
|
||||
ldmfd sp!, {r4 - r6, pc}
|
||||
|
||||
/* Determine validity of the r2 atags pointer. The heuristic requires
|
||||
* that the pointer be aligned, in the first 16k of physical RAM and
|
||||
* that the ATAG_CORE marker is first and present. Future revisions
|
||||
* of this function may be more lenient with the physical address and
|
||||
* may also be able to move the ATAGS block if necessary.
|
||||
*
|
||||
* r8 = machinfo
|
||||
*
|
||||
* Returns:
|
||||
* r2 either valid atags pointer, or zero
|
||||
* r5, r6 corrupted
|
||||
*/
|
||||
|
||||
.type __vet_atags, %function
|
||||
__vet_atags:
|
||||
tst r2, #0x3 @ aligned?
|
||||
bne 1f
|
||||
|
||||
ldr r5, [r2, #0] @ is first tag ATAG_CORE?
|
||||
subs r5, r5, #ATAG_CORE_SIZE
|
||||
bne 1f
|
||||
ldr r5, [r2, #4]
|
||||
ldr r6, =ATAG_CORE
|
||||
cmp r5, r6
|
||||
bne 1f
|
||||
|
||||
mov pc, lr @ atag pointer is ok
|
||||
|
||||
1: mov r2, #0
|
||||
mov pc, lr
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
|
||||
#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
|
||||
|
||||
#define ATAG_CORE 0x54410001
|
||||
#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
|
||||
|
||||
|
||||
/*
|
||||
* swapper_pg_dir is the virtual address of the initial page table.
|
||||
* We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
|
||||
|
@ -61,7 +65,7 @@
|
|||
*
|
||||
* This is normally called from the decompressor code. The requirements
|
||||
* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
|
||||
* r1 = machine nr.
|
||||
* r1 = machine nr, r2 = atags pointer.
|
||||
*
|
||||
* This code is mostly position independent, so if you link the kernel at
|
||||
* 0xc0008000, you call this at __pa(0xc0008000).
|
||||
|
@ -85,6 +89,7 @@ ENTRY(stext)
|
|||
bl __lookup_machine_type @ r5=machinfo
|
||||
movs r8, r5 @ invalid machine (r5=0)?
|
||||
beq __error_a @ yes, error 'a'
|
||||
bl __vet_atags
|
||||
bl __create_page_tables
|
||||
|
||||
/*
|
||||
|
|
|
@ -44,6 +44,10 @@ static const char *processor_modes[] = {
|
|||
"UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
|
||||
};
|
||||
|
||||
static const char *isa_modes[] = {
|
||||
"ARM" , "Thumb" , "Jazelle", "ThumbEE"
|
||||
};
|
||||
|
||||
extern void setup_mm_for_reboot(char mode);
|
||||
|
||||
static volatile int hlt_counter;
|
||||
|
@ -230,11 +234,11 @@ void __show_regs(struct pt_regs *regs)
|
|||
buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
|
||||
buf[4] = '\0';
|
||||
|
||||
printk("Flags: %s IRQs o%s FIQs o%s Mode %s%s Segment %s\n",
|
||||
printk("Flags: %s IRQs o%s FIQs o%s Mode %s ISA %s Segment %s\n",
|
||||
buf, interrupts_enabled(regs) ? "n" : "ff",
|
||||
fast_interrupts_enabled(regs) ? "n" : "ff",
|
||||
processor_modes[processor_mode(regs)],
|
||||
thumb_mode(regs) ? " (T)" : "",
|
||||
isa_modes[isa_mode(regs)],
|
||||
get_fs() == get_ds() ? "kernel" : "user");
|
||||
#ifdef CONFIG_CPU_CP15
|
||||
{
|
||||
|
|
|
@ -63,6 +63,8 @@ unsigned int processor_id;
|
|||
unsigned int __machine_arch_type;
|
||||
EXPORT_SYMBOL(__machine_arch_type);
|
||||
|
||||
unsigned int __atags_pointer __initdata;
|
||||
|
||||
unsigned int system_rev;
|
||||
EXPORT_SYMBOL(system_rev);
|
||||
|
||||
|
@ -780,7 +782,9 @@ void __init setup_arch(char **cmdline_p)
|
|||
if (mdesc->soft_reboot)
|
||||
reboot_setup("s");
|
||||
|
||||
if (mdesc->boot_params)
|
||||
if (__atags_pointer)
|
||||
tags = phys_to_virt(__atags_pointer);
|
||||
else if (mdesc->boot_params)
|
||||
tags = phys_to_virt(mdesc->boot_params);
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,6 +27,11 @@
|
|||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/ads7846.h>
|
||||
#include <linux/dm9000.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/setup.h>
|
||||
|
@ -271,6 +276,127 @@ static struct spi_board_info ek_spi_devices[] = {
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
* LCD Controller
|
||||
*/
|
||||
#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
|
||||
static struct fb_videomode at91_tft_vga_modes[] = {
|
||||
{
|
||||
.name = "TX09D50VM1CCA @ 60",
|
||||
.refresh = 60,
|
||||
.xres = 240, .yres = 320,
|
||||
.pixclock = KHZ2PICOS(4965),
|
||||
|
||||
.left_margin = 1, .right_margin = 33,
|
||||
.upper_margin = 1, .lower_margin = 0,
|
||||
.hsync_len = 5, .vsync_len = 1,
|
||||
|
||||
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
|
||||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct fb_monspecs at91fb_default_monspecs = {
|
||||
.manufacturer = "HIT",
|
||||
.monitor = "TX09D50VM1CCA",
|
||||
|
||||
.modedb = at91_tft_vga_modes,
|
||||
.modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
|
||||
.hfmin = 15000,
|
||||
.hfmax = 64000,
|
||||
.vfmin = 50,
|
||||
.vfmax = 150,
|
||||
};
|
||||
|
||||
#define AT91SAM9261_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
|
||||
| ATMEL_LCDC_DISTYPE_TFT \
|
||||
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
|
||||
|
||||
static void at91_lcdc_power_control(int on)
|
||||
{
|
||||
if (on)
|
||||
at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */
|
||||
else
|
||||
at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */
|
||||
}
|
||||
|
||||
/* Driver datas */
|
||||
static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
|
||||
.default_bpp = 16,
|
||||
.default_dmacon = ATMEL_LCDC_DMAEN,
|
||||
.default_lcdcon2 = AT91SAM9261_DEFAULT_LCDCON2,
|
||||
.default_monspecs = &at91fb_default_monspecs,
|
||||
.atmel_lcdfb_power_control = at91_lcdc_power_control,
|
||||
.guard_time = 1,
|
||||
};
|
||||
|
||||
#else
|
||||
static struct atmel_lcdfb_info __initdata ek_lcdc_data;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* GPIO Buttons
|
||||
*/
|
||||
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
|
||||
static struct gpio_keys_button ek_buttons[] = {
|
||||
{
|
||||
.gpio = AT91_PIN_PA27,
|
||||
.keycode = BTN_0,
|
||||
.desc = "Button 0",
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.gpio = AT91_PIN_PA26,
|
||||
.keycode = BTN_1,
|
||||
.desc = "Button 1",
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.gpio = AT91_PIN_PA25,
|
||||
.keycode = BTN_2,
|
||||
.desc = "Button 2",
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.gpio = AT91_PIN_PA24,
|
||||
.keycode = BTN_3,
|
||||
.desc = "Button 3",
|
||||
.active_low = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data ek_button_data = {
|
||||
.buttons = ek_buttons,
|
||||
.nbuttons = ARRAY_SIZE(ek_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device ek_button_device = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.num_resources = 0,
|
||||
.dev = {
|
||||
.platform_data = &ek_button_data,
|
||||
}
|
||||
};
|
||||
|
||||
static void __init ek_add_device_buttons(void)
|
||||
{
|
||||
at91_set_gpio_input(AT91_PIN_PB27, 0); /* btn0 */
|
||||
at91_set_deglitch(AT91_PIN_PB27, 1);
|
||||
at91_set_gpio_input(AT91_PIN_PB26, 0); /* btn1 */
|
||||
at91_set_deglitch(AT91_PIN_PB26, 1);
|
||||
at91_set_gpio_input(AT91_PIN_PB25, 0); /* btn2 */
|
||||
at91_set_deglitch(AT91_PIN_PB25, 1);
|
||||
at91_set_gpio_input(AT91_PIN_PB24, 0); /* btn3 */
|
||||
at91_set_deglitch(AT91_PIN_PB24, 1);
|
||||
|
||||
platform_device_register(&ek_button_device);
|
||||
}
|
||||
#else
|
||||
static void __init ek_add_device_buttons(void) {}
|
||||
#endif
|
||||
|
||||
static void __init ek_board_init(void)
|
||||
{
|
||||
/* Serial */
|
||||
|
@ -296,6 +422,10 @@ static void __init ek_board_init(void)
|
|||
/* MMC */
|
||||
at91_add_device_mmc(0, &ek_mmc_data);
|
||||
#endif
|
||||
/* LCD Controller */
|
||||
at91_add_device_lcdc(&ek_lcdc_data);
|
||||
/* Push Buttons */
|
||||
ek_add_device_buttons();
|
||||
}
|
||||
|
||||
MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/ads7846.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include <video/atmel_lcdc.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/setup.h>
|
||||
|
@ -201,6 +204,65 @@ static struct at91_nand_data __initdata ek_nand_data = {
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
* LCD Controller
|
||||
*/
|
||||
#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
|
||||
static struct fb_videomode at91_tft_vga_modes[] = {
|
||||
{
|
||||
.name = "TX09D50VM1CCA @ 60",
|
||||
.refresh = 60,
|
||||
.xres = 240, .yres = 320,
|
||||
.pixclock = KHZ2PICOS(4965),
|
||||
|
||||
.left_margin = 1, .right_margin = 33,
|
||||
.upper_margin = 1, .lower_margin = 0,
|
||||
.hsync_len = 5, .vsync_len = 1,
|
||||
|
||||
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
|
||||
.vmode = FB_VMODE_NONINTERLACED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct fb_monspecs at91fb_default_monspecs = {
|
||||
.manufacturer = "HIT",
|
||||
.monitor = "TX09D70VM1CCA",
|
||||
|
||||
.modedb = at91_tft_vga_modes,
|
||||
.modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
|
||||
.hfmin = 15000,
|
||||
.hfmax = 64000,
|
||||
.vfmin = 50,
|
||||
.vfmax = 150,
|
||||
};
|
||||
|
||||
#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
|
||||
| ATMEL_LCDC_DISTYPE_TFT \
|
||||
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
|
||||
|
||||
static void at91_lcdc_power_control(int on)
|
||||
{
|
||||
if (on)
|
||||
at91_set_gpio_value(AT91_PIN_PD12, 0); /* power up */
|
||||
else
|
||||
at91_set_gpio_value(AT91_PIN_PD12, 1); /* power down */
|
||||
}
|
||||
|
||||
/* Driver datas */
|
||||
static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
|
||||
.default_bpp = 16,
|
||||
.default_dmacon = ATMEL_LCDC_DMAEN,
|
||||
.default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2,
|
||||
.default_monspecs = &at91fb_default_monspecs,
|
||||
.atmel_lcdfb_power_control = at91_lcdc_power_control,
|
||||
.guard_time = 1,
|
||||
};
|
||||
|
||||
#else
|
||||
static struct atmel_lcdfb_info __initdata ek_lcdc_data;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* AC97
|
||||
*/
|
||||
|
@ -230,6 +292,8 @@ static void __init ek_board_init(void)
|
|||
at91_add_device_nand(&ek_nand_data);
|
||||
/* I2C */
|
||||
at91_add_device_i2c();
|
||||
/* LCD Controller */
|
||||
at91_add_device_lcdc(&ek_lcdc_data);
|
||||
/* AC97 */
|
||||
at91_add_device_ac97(&ek_ac97_data);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
#
|
||||
|
||||
# Common objects
|
||||
obj-y := time.o irq.o serial.o io.o id.o psc.o
|
||||
obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
|
||||
gpio.o mux.o
|
||||
|
||||
# Board specific
|
||||
obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
void __init davinci_psc_init(void);
|
||||
void __init davinci_irq_init(void);
|
||||
void __init davinci_map_common_io(void);
|
||||
void __init davinci_init_common_hw(void);
|
||||
|
||||
/* NOR Flash base address set to CS0 by default */
|
||||
#define NOR_FLASH_PHYS 0x02000000
|
||||
|
@ -116,6 +117,7 @@ static __init void davinci_evm_init(void)
|
|||
|
||||
static __init void davinci_evm_irq_init(void)
|
||||
{
|
||||
davinci_init_common_hw();
|
||||
davinci_irq_init();
|
||||
}
|
||||
|
||||
|
|
323
arch/arm/mach-davinci/clock.c
Normal file
323
arch/arm/mach-davinci/clock.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* TI DaVinci clock config file
|
||||
*
|
||||
* Copyright (C) 2006 Texas Instruments.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/arch/psc.h>
|
||||
#include "clock.h"
|
||||
|
||||
/* PLL/Reset register offsets */
|
||||
#define PLLM 0x110
|
||||
|
||||
static LIST_HEAD(clocks);
|
||||
static DEFINE_MUTEX(clocks_mutex);
|
||||
static DEFINE_SPINLOCK(clockfw_lock);
|
||||
|
||||
static unsigned int commonrate;
|
||||
static unsigned int armrate;
|
||||
static unsigned int fixedrate = 27000000; /* 27 MHZ */
|
||||
|
||||
extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
|
||||
|
||||
/*
|
||||
* Returns a clock. Note that we first try to use device id on the bus
|
||||
* and clock name. If this fails, we try to use clock name only.
|
||||
*/
|
||||
struct clk *clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk *p, *clk = ERR_PTR(-ENOENT);
|
||||
int idno;
|
||||
|
||||
if (dev == NULL || dev->bus != &platform_bus_type)
|
||||
idno = -1;
|
||||
else
|
||||
idno = to_platform_device(dev)->id;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
|
||||
list_for_each_entry(p, &clocks, node) {
|
||||
if (p->id == idno &&
|
||||
strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
|
||||
clk = p;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(p, &clocks, node) {
|
||||
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
|
||||
clk = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
found:
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get);
|
||||
|
||||
void clk_put(struct clk *clk)
|
||||
{
|
||||
if (clk && !IS_ERR(clk))
|
||||
module_put(clk->owner);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_put);
|
||||
|
||||
static int __clk_enable(struct clk *clk)
|
||||
{
|
||||
if (clk->flags & ALWAYS_ENABLED)
|
||||
return 0;
|
||||
|
||||
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __clk_disable(struct clk *clk)
|
||||
{
|
||||
if (clk->usecount)
|
||||
return;
|
||||
|
||||
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
|
||||
}
|
||||
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
if (clk->usecount++ == 0) {
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
ret = __clk_enable(clk);
|
||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_enable);
|
||||
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
|
||||
if (clk->usecount > 0 && !(--clk->usecount)) {
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
__clk_disable(clk);
|
||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(clk_disable);
|
||||
|
||||
unsigned long clk_get_rate(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
return *(clk->rate);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_rate);
|
||||
|
||||
long clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
return *(clk->rate);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_round_rate);
|
||||
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
/* changing the clk rate is not supported */
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_set_rate);
|
||||
|
||||
int clk_register(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
list_add(&clk->node, &clocks);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_register);
|
||||
|
||||
void clk_unregister(struct clk *clk)
|
||||
{
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return;
|
||||
|
||||
mutex_lock(&clocks_mutex);
|
||||
list_del(&clk->node);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_unregister);
|
||||
|
||||
static struct clk davinci_clks[] = {
|
||||
{
|
||||
.name = "ARMCLK",
|
||||
.rate = &armrate,
|
||||
.lpsc = -1,
|
||||
.flags = ALWAYS_ENABLED,
|
||||
},
|
||||
{
|
||||
.name = "UART",
|
||||
.rate = &fixedrate,
|
||||
.lpsc = DAVINCI_LPSC_UART0,
|
||||
},
|
||||
{
|
||||
.name = "EMACCLK",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
|
||||
},
|
||||
{
|
||||
.name = "I2CCLK",
|
||||
.rate = &fixedrate,
|
||||
.lpsc = DAVINCI_LPSC_I2C,
|
||||
},
|
||||
{
|
||||
.name = "IDECLK",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_ATA,
|
||||
},
|
||||
{
|
||||
.name = "McBSPCLK",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_McBSP,
|
||||
},
|
||||
{
|
||||
.name = "MMCSDCLK",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_MMC_SD,
|
||||
},
|
||||
{
|
||||
.name = "SPICLK",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_SPI,
|
||||
},
|
||||
{
|
||||
.name = "gpio",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_GPIO,
|
||||
},
|
||||
{
|
||||
.name = "AEMIFCLK",
|
||||
.rate = &commonrate,
|
||||
.lpsc = DAVINCI_LPSC_AEMIF,
|
||||
.usecount = 1,
|
||||
}
|
||||
};
|
||||
|
||||
int __init davinci_clk_init(void)
|
||||
{
|
||||
struct clk *clkp;
|
||||
int count = 0;
|
||||
u32 pll_mult;
|
||||
|
||||
pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
|
||||
commonrate = ((pll_mult + 1) * 27000000) / 6;
|
||||
armrate = ((pll_mult + 1) * 27000000) / 2;
|
||||
|
||||
for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks);
|
||||
count++, clkp++) {
|
||||
clk_register(clkp);
|
||||
|
||||
/* Turn on clocks that have been enabled in the
|
||||
* table above */
|
||||
if (clkp->usecount)
|
||||
clk_enable(clkp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
return *pos < 1 ? (void *)1 : NULL;
|
||||
}
|
||||
|
||||
static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
{
|
||||
++*pos;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void davinci_ck_stop(struct seq_file *m, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
static int davinci_ck_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct clk *cp;
|
||||
|
||||
list_for_each_entry(cp, &clocks, node)
|
||||
seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct seq_operations davinci_ck_op = {
|
||||
.start = davinci_ck_start,
|
||||
.next = davinci_ck_next,
|
||||
.stop = davinci_ck_stop,
|
||||
.show = davinci_ck_show
|
||||
};
|
||||
|
||||
static int davinci_ck_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &davinci_ck_op);
|
||||
}
|
||||
|
||||
static struct file_operations proc_davinci_ck_operations = {
|
||||
.open = davinci_ck_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init davinci_ck_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *entry;
|
||||
|
||||
entry = create_proc_entry("davinci_clocks", 0, NULL);
|
||||
if (entry)
|
||||
entry->proc_fops = &proc_davinci_ck_operations;
|
||||
return 0;
|
||||
|
||||
}
|
||||
__initcall(davinci_ck_proc_init);
|
||||
#endif /* CONFIG_DEBUG_PROC_FS */
|
33
arch/arm/mach-davinci/clock.h
Normal file
33
arch/arm/mach-davinci/clock.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* TI DaVinci clock definitions
|
||||
*
|
||||
* Copyright (C) 2006 Texas Instruments.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
|
||||
#define __ARCH_ARM_DAVINCI_CLOCK_H
|
||||
|
||||
struct clk {
|
||||
struct list_head node;
|
||||
struct module *owner;
|
||||
const char *name;
|
||||
unsigned int *rate;
|
||||
int id;
|
||||
__s8 usecount;
|
||||
__u8 flags;
|
||||
__u8 lpsc;
|
||||
};
|
||||
|
||||
/* Clock flags */
|
||||
#define RATE_CKCTL 1
|
||||
#define RATE_FIXED 2
|
||||
#define RATE_PROPAGATES 4
|
||||
#define VIRTUAL_CLOCK 8
|
||||
#define ALWAYS_ENABLED 16
|
||||
#define ENABLE_REG_32BIT 32
|
||||
|
||||
#endif
|
286
arch/arm/mach-davinci/gpio.c
Normal file
286
arch/arm/mach-davinci/gpio.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* TI DaVinci GPIO Support
|
||||
*
|
||||
* Copyright (c) 2006 David Brownell
|
||||
* Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
static DEFINE_SPINLOCK(gpio_lock);
|
||||
static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
|
||||
|
||||
int gpio_request(unsigned gpio, const char *tag)
|
||||
{
|
||||
if (gpio >= DAVINCI_N_GPIO)
|
||||
return -EINVAL;
|
||||
|
||||
if (test_and_set_bit(gpio, gpio_in_use))
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_request);
|
||||
|
||||
void gpio_free(unsigned gpio)
|
||||
{
|
||||
if (gpio >= DAVINCI_N_GPIO)
|
||||
return;
|
||||
|
||||
clear_bit(gpio, gpio_in_use);
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_free);
|
||||
|
||||
/* create a non-inlined version */
|
||||
static struct gpio_controller *__iomem gpio2controller(unsigned gpio)
|
||||
{
|
||||
return __gpio_to_controller(gpio);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assuming the pin is muxed as a gpio output, set its output value.
|
||||
*/
|
||||
void __gpio_set(unsigned gpio, int value)
|
||||
{
|
||||
struct gpio_controller *__iomem g = gpio2controller(gpio);
|
||||
|
||||
__raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data);
|
||||
}
|
||||
EXPORT_SYMBOL(__gpio_set);
|
||||
|
||||
|
||||
/*
|
||||
* Read the pin's value (works even if it's set up as output);
|
||||
* returns zero/nonzero.
|
||||
*
|
||||
* Note that changes are synched to the GPIO clock, so reading values back
|
||||
* right after you've set them may give old values.
|
||||
*/
|
||||
int __gpio_get(unsigned gpio)
|
||||
{
|
||||
struct gpio_controller *__iomem g = gpio2controller(gpio);
|
||||
|
||||
return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
|
||||
}
|
||||
EXPORT_SYMBOL(__gpio_get);
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* board setup code *MUST* set PINMUX0 and PINMUX1 as
|
||||
* needed, and enable the GPIO clock.
|
||||
*/
|
||||
|
||||
int gpio_direction_input(unsigned gpio)
|
||||
{
|
||||
struct gpio_controller *__iomem g = gpio2controller(gpio);
|
||||
u32 temp;
|
||||
u32 mask;
|
||||
|
||||
if (!g)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&gpio_lock);
|
||||
mask = __gpio_mask(gpio);
|
||||
temp = __raw_readl(&g->dir);
|
||||
temp |= mask;
|
||||
__raw_writel(temp, &g->dir);
|
||||
spin_unlock(&gpio_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_direction_input);
|
||||
|
||||
int gpio_direction_output(unsigned gpio, int value)
|
||||
{
|
||||
struct gpio_controller *__iomem g = gpio2controller(gpio);
|
||||
u32 temp;
|
||||
u32 mask;
|
||||
|
||||
if (!g)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&gpio_lock);
|
||||
mask = __gpio_mask(gpio);
|
||||
temp = __raw_readl(&g->dir);
|
||||
temp &= ~mask;
|
||||
__raw_writel(mask, value ? &g->set_data : &g->clr_data);
|
||||
__raw_writel(temp, &g->dir);
|
||||
spin_unlock(&gpio_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_direction_output);
|
||||
|
||||
/*
|
||||
* We expect irqs will normally be set up as input pins, but they can also be
|
||||
* used as output pins ... which is convenient for testing.
|
||||
*
|
||||
* NOTE: GPIO0..GPIO7 also have direct INTC hookups, which work in addition
|
||||
* to their GPIOBNK0 irq (but with a bit less overhead). But we don't have
|
||||
* a good way to hook those up ...
|
||||
*
|
||||
* All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
|
||||
* serve as EDMA event triggers.
|
||||
*/
|
||||
|
||||
static void gpio_irq_disable(unsigned irq)
|
||||
{
|
||||
struct gpio_controller *__iomem g = get_irq_chip_data(irq);
|
||||
u32 mask = __gpio_mask(irq_to_gpio(irq));
|
||||
|
||||
__raw_writel(mask, &g->clr_falling);
|
||||
__raw_writel(mask, &g->clr_rising);
|
||||
}
|
||||
|
||||
static void gpio_irq_enable(unsigned irq)
|
||||
{
|
||||
struct gpio_controller *__iomem g = get_irq_chip_data(irq);
|
||||
u32 mask = __gpio_mask(irq_to_gpio(irq));
|
||||
|
||||
if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
|
||||
__raw_writel(mask, &g->set_falling);
|
||||
if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
|
||||
__raw_writel(mask, &g->set_rising);
|
||||
}
|
||||
|
||||
static int gpio_irq_type(unsigned irq, unsigned trigger)
|
||||
{
|
||||
struct gpio_controller *__iomem g = get_irq_chip_data(irq);
|
||||
u32 mask = __gpio_mask(irq_to_gpio(irq));
|
||||
|
||||
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
|
||||
return -EINVAL;
|
||||
|
||||
irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
|
||||
irq_desc[irq].status |= trigger;
|
||||
|
||||
__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
|
||||
? &g->set_falling : &g->clr_falling);
|
||||
__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
|
||||
? &g->set_rising : &g->clr_rising);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip gpio_irqchip = {
|
||||
.name = "GPIO",
|
||||
.enable = gpio_irq_enable,
|
||||
.disable = gpio_irq_disable,
|
||||
.set_type = gpio_irq_type,
|
||||
};
|
||||
|
||||
static void
|
||||
gpio_irq_handler(unsigned irq, struct irq_desc *desc)
|
||||
{
|
||||
struct gpio_controller *__iomem g = get_irq_chip_data(irq);
|
||||
u32 mask = 0xffff;
|
||||
|
||||
/* we only care about one bank */
|
||||
if (irq & 1)
|
||||
mask <<= 16;
|
||||
|
||||
/* temporarily mask (level sensitive) parent IRQ */
|
||||
desc->chip->ack(irq);
|
||||
while (1) {
|
||||
u32 status;
|
||||
struct irq_desc *gpio;
|
||||
int n;
|
||||
int res;
|
||||
|
||||
/* ack any irqs */
|
||||
status = __raw_readl(&g->intstat) & mask;
|
||||
if (!status)
|
||||
break;
|
||||
__raw_writel(status, &g->intstat);
|
||||
if (irq & 1)
|
||||
status >>= 16;
|
||||
|
||||
/* now demux them to the right lowlevel handler */
|
||||
n = (int)get_irq_data(irq);
|
||||
gpio = &irq_desc[n];
|
||||
while (status) {
|
||||
res = ffs(status);
|
||||
n += res;
|
||||
gpio += res;
|
||||
desc_handle_irq(n - 1, gpio - 1);
|
||||
status >>= res;
|
||||
}
|
||||
}
|
||||
desc->chip->unmask(irq);
|
||||
/* now it may re-trigger */
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: for suspend/resume, probably best to make a sysdev (and class)
|
||||
* with its suspend/resume calls hooking into the results of the set_wake()
|
||||
* calls ... so if no gpios are wakeup events the clock can be disabled,
|
||||
* with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
|
||||
* can be set appropriately for GPIOV33 pins.
|
||||
*/
|
||||
|
||||
static int __init davinci_gpio_irq_setup(void)
|
||||
{
|
||||
unsigned gpio, irq, bank;
|
||||
struct clk *clk;
|
||||
|
||||
clk = clk_get(NULL, "gpio");
|
||||
if (IS_ERR(clk)) {
|
||||
printk(KERN_ERR "Error %ld getting gpio clock?\n",
|
||||
PTR_ERR(clk));
|
||||
return 0;
|
||||
}
|
||||
|
||||
clk_enable(clk);
|
||||
|
||||
for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
|
||||
gpio < DAVINCI_N_GPIO; bank++) {
|
||||
struct gpio_controller *__iomem g = gpio2controller(gpio);
|
||||
unsigned i;
|
||||
|
||||
__raw_writel(~0, &g->clr_falling);
|
||||
__raw_writel(~0, &g->clr_rising);
|
||||
|
||||
/* set up all irqs in this bank */
|
||||
set_irq_chained_handler(bank, gpio_irq_handler);
|
||||
set_irq_chip_data(bank, g);
|
||||
set_irq_data(bank, (void *)irq);
|
||||
|
||||
for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
|
||||
i++, irq++, gpio++) {
|
||||
set_irq_chip(irq, &gpio_irqchip);
|
||||
set_irq_chip_data(irq, g);
|
||||
set_irq_handler(irq, handle_simple_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
/* BINTEN -- per-bank interrupt enable. genirq would also let these
|
||||
* bits be set/cleared dynamically.
|
||||
*/
|
||||
__raw_writel(0x1f, (void *__iomem)
|
||||
IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
|
||||
|
||||
printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(davinci_gpio_irq_setup);
|
|
@ -17,6 +17,7 @@
|
|||
#include <asm/memory.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
extern void davinci_check_revision(void);
|
||||
|
||||
|
@ -49,3 +50,8 @@ void __init davinci_map_common_io(void)
|
|||
*/
|
||||
davinci_check_revision();
|
||||
}
|
||||
|
||||
void __init davinci_init_common_hw(void)
|
||||
{
|
||||
davinci_clk_init();
|
||||
}
|
||||
|
|
41
arch/arm/mach-davinci/mux.c
Normal file
41
arch/arm/mach-davinci/mux.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* DaVinci pin multiplexing configurations
|
||||
*
|
||||
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/arch/mux.h>
|
||||
|
||||
/* System control register offsets */
|
||||
#define PINMUX0 0x00
|
||||
#define PINMUX1 0x04
|
||||
|
||||
static DEFINE_SPINLOCK(mux_lock);
|
||||
|
||||
void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
|
||||
{
|
||||
u32 pinmux, muxreg = PINMUX0;
|
||||
|
||||
if (mux >= DAVINCI_MUX_LEVEL2) {
|
||||
muxreg = PINMUX1;
|
||||
mux -= DAVINCI_MUX_LEVEL2;
|
||||
}
|
||||
|
||||
spin_lock(&mux_lock);
|
||||
pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
|
||||
if (enable)
|
||||
pinmux |= (1 << mux);
|
||||
else
|
||||
pinmux &= ~(1 << mux);
|
||||
davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
|
||||
spin_unlock(&mux_lock);
|
||||
}
|
|
@ -25,39 +25,40 @@
|
|||
#include <asm/io.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/arch/psc.h>
|
||||
#include <asm/arch/mux.h>
|
||||
|
||||
#define PTCMD __REG(0x01C41120)
|
||||
#define PDSTAT __REG(0x01C41200)
|
||||
#define PDCTL1 __REG(0x01C41304)
|
||||
#define EPCPR __REG(0x01C41070)
|
||||
#define PTSTAT __REG(0x01C41128)
|
||||
/* PSC register offsets */
|
||||
#define EPCPR 0x070
|
||||
#define PTCMD 0x120
|
||||
#define PTSTAT 0x128
|
||||
#define PDSTAT 0x200
|
||||
#define PDCTL1 0x304
|
||||
#define MDSTAT 0x800
|
||||
#define MDCTL 0xA00
|
||||
|
||||
#define MDSTAT IO_ADDRESS(0x01C41800)
|
||||
#define MDCTL IO_ADDRESS(0x01C41A00)
|
||||
|
||||
#define PINMUX0 __REG(0x01c40000)
|
||||
#define PINMUX1 __REG(0x01c40004)
|
||||
#define VDD3P3V_PWDN __REG(0x01C40048)
|
||||
/* System control register offsets */
|
||||
#define VDD3P3V_PWDN 0x48
|
||||
|
||||
static void davinci_psc_mux(unsigned int id)
|
||||
{
|
||||
switch (id) {
|
||||
case DAVINCI_LPSC_ATA:
|
||||
PINMUX0 |= (1 << 17) | (1 << 16);
|
||||
davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
|
||||
davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
|
||||
break;
|
||||
case DAVINCI_LPSC_MMC_SD:
|
||||
/* VDD power manupulations are done in U-Boot for CPMAC
|
||||
* so applies to MMC as well
|
||||
*/
|
||||
/*Set up the pull regiter for MMC */
|
||||
VDD3P3V_PWDN = 0x0;
|
||||
PINMUX1 &= (~(1 << 9));
|
||||
davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
|
||||
davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
|
||||
break;
|
||||
case DAVINCI_LPSC_I2C:
|
||||
PINMUX1 |= (1 << 7);
|
||||
davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
|
||||
break;
|
||||
case DAVINCI_LPSC_McBSP:
|
||||
PINMUX1 |= (1 << 10);
|
||||
davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -67,33 +68,59 @@ static void davinci_psc_mux(unsigned int id)
|
|||
/* Enable or disable a PSC domain */
|
||||
void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
|
||||
{
|
||||
volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id);
|
||||
volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id);
|
||||
u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
|
||||
|
||||
if (id < 0)
|
||||
return;
|
||||
|
||||
mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
|
||||
if (enable)
|
||||
*mdctl |= 0x00000003; /* Enable Module */
|
||||
mdctl |= 0x00000003; /* Enable Module */
|
||||
else
|
||||
*mdctl &= 0xFFFFFFF2; /* Disable Module */
|
||||
mdctl &= 0xFFFFFFF2; /* Disable Module */
|
||||
davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
|
||||
|
||||
if ((PDSTAT & 0x00000001) == 0) {
|
||||
PDCTL1 |= 0x1;
|
||||
PTCMD = (1 << domain);
|
||||
while ((((EPCPR >> domain) & 1) == 0));
|
||||
pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
|
||||
if ((pdstat & 0x00000001) == 0) {
|
||||
pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
|
||||
pdctl1 |= 0x1;
|
||||
davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
|
||||
|
||||
PDCTL1 |= 0x100;
|
||||
while (!(((PTSTAT >> domain) & 1) == 0));
|
||||
ptcmd = 1 << domain;
|
||||
davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
|
||||
|
||||
do {
|
||||
epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
|
||||
EPCPR);
|
||||
} while ((((epcpr >> domain) & 1) == 0));
|
||||
|
||||
pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
|
||||
pdctl1 |= 0x100;
|
||||
davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
|
||||
|
||||
do {
|
||||
ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
|
||||
PTSTAT);
|
||||
} while (!(((ptstat >> domain) & 1) == 0));
|
||||
} else {
|
||||
PTCMD = (1 << domain);
|
||||
while (!(((PTSTAT >> domain) & 1) == 0));
|
||||
ptcmd = 1 << domain;
|
||||
davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
|
||||
|
||||
do {
|
||||
ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
|
||||
PTSTAT);
|
||||
} while (!(((ptstat >> domain) & 1) == 0));
|
||||
}
|
||||
|
||||
if (enable)
|
||||
while (!((*mdstat & 0x0000001F) == 0x3));
|
||||
mdstat_mask = 0x3;
|
||||
else
|
||||
while (!((*mdstat & 0x0000001F) == 0x2));
|
||||
mdstat_mask = 0x2;
|
||||
|
||||
do {
|
||||
mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
|
||||
MDSTAT + 4 * id);
|
||||
} while (!((mdstat & 0x0000001F) == mdstat_mask));
|
||||
|
||||
if (enable)
|
||||
davinci_psc_mux(id);
|
||||
|
|
|
@ -28,12 +28,16 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/imxfb.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/arch/mmc.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
unsigned long imx_gpio_alloc_map[(GPIO_PORT_MAX + 1) * 32 / BITS_PER_LONG];
|
||||
|
||||
void imx_gpio_mode(int gpio_mode)
|
||||
{
|
||||
|
@ -95,6 +99,120 @@ void imx_gpio_mode(int gpio_mode)
|
|||
|
||||
EXPORT_SYMBOL(imx_gpio_mode);
|
||||
|
||||
int imx_gpio_request(unsigned gpio, const char *label)
|
||||
{
|
||||
if(gpio >= (GPIO_PORT_MAX + 1) * 32)
|
||||
printk(KERN_ERR "imx_gpio: Attempt to request nonexistent GPIO %d for \"%s\"\n",
|
||||
gpio, label ? label : "?");
|
||||
return -EINVAL;
|
||||
|
||||
if(test_and_set_bit(gpio, imx_gpio_alloc_map)) {
|
||||
printk(KERN_ERR "imx_gpio: GPIO %d already used. Allocation for \"%s\" failed\n",
|
||||
gpio, label ? label : "?");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(imx_gpio_request);
|
||||
|
||||
void imx_gpio_free(unsigned gpio)
|
||||
{
|
||||
if(gpio >= (GPIO_PORT_MAX + 1) * 32)
|
||||
return;
|
||||
|
||||
clear_bit(gpio, imx_gpio_alloc_map);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(imx_gpio_free);
|
||||
|
||||
int imx_gpio_direction_input(unsigned gpio)
|
||||
{
|
||||
imx_gpio_mode(gpio| GPIO_IN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(imx_gpio_direction_input);
|
||||
|
||||
int imx_gpio_direction_output(unsigned gpio, int value)
|
||||
{
|
||||
imx_gpio_set_value(gpio, value);
|
||||
imx_gpio_mode(gpio| GPIO_OUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(imx_gpio_direction_output);
|
||||
|
||||
int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
|
||||
int alloc_mode, const char *label)
|
||||
{
|
||||
const int *p = pin_list;
|
||||
int i;
|
||||
unsigned gpio;
|
||||
unsigned mode;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
|
||||
mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK);
|
||||
|
||||
if (gpio >= (GPIO_PORT_MAX + 1) * 32)
|
||||
goto setup_error;
|
||||
|
||||
if (alloc_mode & IMX_GPIO_ALLOC_MODE_RELEASE)
|
||||
imx_gpio_free(gpio);
|
||||
else if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_NO_ALLOC))
|
||||
if (imx_gpio_request(gpio, label))
|
||||
if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
|
||||
goto setup_error;
|
||||
|
||||
if (!(alloc_mode & (IMX_GPIO_ALLOC_MODE_ALLOC_ONLY |
|
||||
IMX_GPIO_ALLOC_MODE_RELEASE)))
|
||||
imx_gpio_mode(gpio | mode);
|
||||
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
|
||||
setup_error:
|
||||
if(alloc_mode & (IMX_GPIO_ALLOC_MODE_NO_ALLOC |
|
||||
IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
|
||||
return -EINVAL;
|
||||
|
||||
while (p != pin_list) {
|
||||
p--;
|
||||
gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
|
||||
imx_gpio_free(gpio);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(imx_gpio_setup_multiple_pins);
|
||||
|
||||
void __imx_gpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
imx_gpio_set_value_inline(gpio, value);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__imx_gpio_set_value);
|
||||
|
||||
int imx_gpio_to_irq(unsigned gpio)
|
||||
{
|
||||
return IRQ_GPIOA(0) + gpio;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(imx_gpio_to_irq);
|
||||
|
||||
int imx_irq_to_gpio(unsigned irq)
|
||||
{
|
||||
if (irq < IRQ_GPIOA(0))
|
||||
return -EINVAL;
|
||||
return irq - IRQ_GPIOA(0);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(imx_irq_to_gpio);
|
||||
|
||||
/*
|
||||
* get the system pll clock in Hz
|
||||
*
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2000-2001 Deep Blue Solutions
|
||||
* Copyright (C) 2002 Shane Nay (shane@minirl.com)
|
||||
* Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -15,6 +16,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/clockchips.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -25,7 +27,8 @@
|
|||
/* Use timer 1 as system timer */
|
||||
#define TIMER_BASE IMX_TIM1_BASE
|
||||
|
||||
static unsigned long evt_diff;
|
||||
static struct clock_event_device clockevent_imx;
|
||||
static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
|
||||
|
||||
/*
|
||||
* IRQ handler for the timer
|
||||
|
@ -33,25 +36,20 @@ static unsigned long evt_diff;
|
|||
static irqreturn_t
|
||||
imx_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = &clockevent_imx;
|
||||
uint32_t tstat;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
/* clear the interrupt */
|
||||
tstat = IMX_TSTAT(TIMER_BASE);
|
||||
IMX_TSTAT(TIMER_BASE) = 0;
|
||||
|
||||
if (tstat & TSTAT_COMP) {
|
||||
do {
|
||||
|
||||
write_seqlock(&xtime_lock);
|
||||
timer_tick();
|
||||
write_sequnlock(&xtime_lock);
|
||||
IMX_TCMP(TIMER_BASE) += evt_diff;
|
||||
|
||||
} while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE)
|
||||
- IMX_TCN(TIMER_BASE)) < 0));
|
||||
evt->event_handler(evt);
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct irqaction imx_timer_irq = {
|
||||
|
@ -70,10 +68,8 @@ static void __init imx_timer_hardware_init(void)
|
|||
*/
|
||||
IMX_TCTL(TIMER_BASE) = 0;
|
||||
IMX_TPRER(TIMER_BASE) = 0;
|
||||
IMX_TCMP(TIMER_BASE) = LATCH - 1;
|
||||
|
||||
IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_IRQEN | TCTL_TEN;
|
||||
evt_diff = LATCH;
|
||||
IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_TEN;
|
||||
}
|
||||
|
||||
cycle_t imx_get_cycles(void)
|
||||
|
@ -99,11 +95,108 @@ static int __init imx_clocksource_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int imx_set_next_event(unsigned long evt,
|
||||
struct clock_event_device *unused)
|
||||
{
|
||||
unsigned long tcmp;
|
||||
|
||||
tcmp = IMX_TCN(TIMER_BASE) + evt;
|
||||
IMX_TCMP(TIMER_BASE) = tcmp;
|
||||
|
||||
return (int32_t)(tcmp - IMX_TCN(TIMER_BASE)) < 0 ? -ETIME : 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char *clock_event_mode_label[]={
|
||||
[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
|
||||
[CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
|
||||
[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
|
||||
[CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
|
||||
};
|
||||
#endif /*DEBUG*/
|
||||
|
||||
static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* The timer interrupt generation is disabled at least
|
||||
* for enough time to call imx_set_next_event()
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
/* Disable interrupt in GPT module */
|
||||
IMX_TCTL(TIMER_BASE) &= ~TCTL_IRQEN;
|
||||
if (mode != clockevent_mode) {
|
||||
/* Set event time into far-far future */
|
||||
IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3;
|
||||
/* Clear pending interrupt */
|
||||
IMX_TSTAT(TIMER_BASE) &= ~TSTAT_COMP;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printk(KERN_INFO "imx_set_mode: changing mode from %s to %s\n",
|
||||
clock_event_mode_label[clockevent_mode], clock_event_mode_label[mode]);
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* Remember timer mode */
|
||||
clockevent_mode = mode;
|
||||
local_irq_restore(flags);
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
printk(KERN_ERR "imx_set_mode: Periodic mode is not supported for i.MX\n");
|
||||
break;
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
/*
|
||||
* Do not put overhead of interrupt enable/disable into
|
||||
* imx_set_next_event(), the core has about 4 minutes
|
||||
* to call imx_set_next_event() or shutdown clock after
|
||||
* mode switching
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN;
|
||||
local_irq_restore(flags);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
/* Left event sources disabled, no more interrupts appears */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct clock_event_device clockevent_imx = {
|
||||
.name = "imx_timer1",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.shift = 32,
|
||||
.set_mode = imx_set_mode,
|
||||
.set_next_event = imx_set_next_event,
|
||||
.rating = 200,
|
||||
};
|
||||
|
||||
static int __init imx_clockevent_init(void)
|
||||
{
|
||||
clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC,
|
||||
clockevent_imx.shift);
|
||||
clockevent_imx.max_delta_ns =
|
||||
clockevent_delta2ns(0xfffffffe, &clockevent_imx);
|
||||
clockevent_imx.min_delta_ns =
|
||||
clockevent_delta2ns(0xf, &clockevent_imx);
|
||||
|
||||
clockevent_imx.cpumask = cpumask_of_cpu(0);
|
||||
|
||||
clockevents_register_device(&clockevent_imx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void __init imx_timer_init(void)
|
||||
{
|
||||
imx_timer_hardware_init();
|
||||
imx_clocksource_init();
|
||||
|
||||
imx_clockevent_init();
|
||||
|
||||
/*
|
||||
* Make irqs happen for the system timer
|
||||
*/
|
||||
|
|
|
@ -29,13 +29,15 @@
|
|||
#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
|
||||
#define IOP13XX_TPMI_MEM(dev) IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
|
||||
#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
|
||||
#define IOP13XX_TPMI_IOP_CTRL(dev) (IOP13XX_TPMI_CTRL(dev) + 0x2000)
|
||||
#define IOP13XX_TPMI_MMR_SIZE (SZ_4K - 1)
|
||||
#define IOP13XX_TPMI_MEM_SIZE (255)
|
||||
#define IOP13XX_TPMI_MEM_CTRL (SZ_1K - 1)
|
||||
#define IOP13XX_TPMI_RESOURCE_MMR 0
|
||||
#define IOP13XX_TPMI_RESOURCE_MEM 1
|
||||
#define IOP13XX_TPMI_RESOURCE_CTRL 2
|
||||
#define IOP13XX_TPMI_RESOURCE_IRQ 3
|
||||
#define IOP13XX_TPMI_RESOURCE_IOP_CTRL 3
|
||||
#define IOP13XX_TPMI_RESOURCE_IRQ 4
|
||||
|
||||
static struct resource iop13xx_tpmi_0_resources[] = {
|
||||
[IOP13XX_TPMI_RESOURCE_MMR] = {
|
||||
|
@ -53,6 +55,11 @@ static struct resource iop13xx_tpmi_0_resources[] = {
|
|||
.end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
|
||||
.start = IOP13XX_TPMI_IOP_CTRL(0),
|
||||
.end = IOP13XX_TPMI_IOP_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[IOP13XX_TPMI_RESOURCE_IRQ] = {
|
||||
.start = IRQ_IOP13XX_TPMI0_OUT,
|
||||
.end = IRQ_IOP13XX_TPMI0_OUT,
|
||||
|
@ -76,6 +83,11 @@ static struct resource iop13xx_tpmi_1_resources[] = {
|
|||
.end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
|
||||
.start = IOP13XX_TPMI_IOP_CTRL(1),
|
||||
.end = IOP13XX_TPMI_IOP_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[IOP13XX_TPMI_RESOURCE_IRQ] = {
|
||||
.start = IRQ_IOP13XX_TPMI1_OUT,
|
||||
.end = IRQ_IOP13XX_TPMI1_OUT,
|
||||
|
@ -99,6 +111,11 @@ static struct resource iop13xx_tpmi_2_resources[] = {
|
|||
.end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
|
||||
.start = IOP13XX_TPMI_IOP_CTRL(2),
|
||||
.end = IOP13XX_TPMI_IOP_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[IOP13XX_TPMI_RESOURCE_IRQ] = {
|
||||
.start = IRQ_IOP13XX_TPMI2_OUT,
|
||||
.end = IRQ_IOP13XX_TPMI2_OUT,
|
||||
|
@ -122,6 +139,11 @@ static struct resource iop13xx_tpmi_3_resources[] = {
|
|||
.end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
|
||||
.start = IOP13XX_TPMI_IOP_CTRL(3),
|
||||
.end = IOP13XX_TPMI_IOP_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[IOP13XX_TPMI_RESOURCE_IRQ] = {
|
||||
.start = IRQ_IOP13XX_TPMI3_OUT,
|
||||
.end = IRQ_IOP13XX_TPMI3_OUT,
|
||||
|
@ -133,7 +155,7 @@ u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
|
|||
static struct platform_device iop13xx_tpmi_0_device = {
|
||||
.name = "iop-tpmi",
|
||||
.id = 0,
|
||||
.num_resources = 4,
|
||||
.num_resources = ARRAY_SIZE(iop13xx_tpmi_0_resources),
|
||||
.resource = iop13xx_tpmi_0_resources,
|
||||
.dev = {
|
||||
.dma_mask = &iop13xx_tpmi_mask,
|
||||
|
@ -144,7 +166,7 @@ static struct platform_device iop13xx_tpmi_0_device = {
|
|||
static struct platform_device iop13xx_tpmi_1_device = {
|
||||
.name = "iop-tpmi",
|
||||
.id = 1,
|
||||
.num_resources = 4,
|
||||
.num_resources = ARRAY_SIZE(iop13xx_tpmi_1_resources),
|
||||
.resource = iop13xx_tpmi_1_resources,
|
||||
.dev = {
|
||||
.dma_mask = &iop13xx_tpmi_mask,
|
||||
|
@ -155,7 +177,7 @@ static struct platform_device iop13xx_tpmi_1_device = {
|
|||
static struct platform_device iop13xx_tpmi_2_device = {
|
||||
.name = "iop-tpmi",
|
||||
.id = 2,
|
||||
.num_resources = 4,
|
||||
.num_resources = ARRAY_SIZE(iop13xx_tpmi_2_resources),
|
||||
.resource = iop13xx_tpmi_2_resources,
|
||||
.dev = {
|
||||
.dma_mask = &iop13xx_tpmi_mask,
|
||||
|
@ -166,7 +188,7 @@ static struct platform_device iop13xx_tpmi_2_device = {
|
|||
static struct platform_device iop13xx_tpmi_3_device = {
|
||||
.name = "iop-tpmi",
|
||||
.id = 3,
|
||||
.num_resources = 4,
|
||||
.num_resources = ARRAY_SIZE(iop13xx_tpmi_3_resources),
|
||||
.resource = iop13xx_tpmi_3_resources,
|
||||
.dev = {
|
||||
.dma_mask = &iop13xx_tpmi_mask,
|
||||
|
|
|
@ -41,6 +41,22 @@ config ARCH_ADI_COYOTE
|
|||
Engineering Coyote Gateway Reference Platform. For more
|
||||
information on this platform, see <file:Documentation/arm/IXP4xx>.
|
||||
|
||||
config MACH_GATEWAY7001
|
||||
bool "Gateway 7001"
|
||||
select PCI
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support Gateway's
|
||||
7001 Access Point. For more information on this platform,
|
||||
see http://openwrt.org
|
||||
|
||||
config MACH_WG302V2
|
||||
bool "Netgear WG302 v2 / WAG302 v2"
|
||||
select PCI
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support Netgear's
|
||||
WG302 v2 or WAG302 v2 Access Points. For more information
|
||||
on this platform, see http://openwrt.org
|
||||
|
||||
config ARCH_IXDP425
|
||||
bool "IXDP425"
|
||||
help
|
||||
|
|
|
@ -13,6 +13,8 @@ obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
|
|||
obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o
|
||||
obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
|
||||
obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o
|
||||
obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o
|
||||
obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o
|
||||
|
||||
obj-y += common.o
|
||||
|
||||
|
@ -24,5 +26,7 @@ obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
|
|||
obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o
|
||||
obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o
|
||||
obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o
|
||||
obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
|
||||
obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o
|
||||
|
||||
obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
|
||||
|
|
63
arch/arm/mach-ixp4xx/gateway7001-pci.c
Normal file
63
arch/arm/mach-ixp4xx/gateway7001-pci.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* arch/arch/mach-ixp4xx/gateway7001-pci.c
|
||||
*
|
||||
* PCI setup routines for Gateway 7001
|
||||
*
|
||||
* Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* based on coyote-pci.c:
|
||||
* Copyright (C) 2002 Jungo Software Technologies.
|
||||
* Copyright (C) 2003 MontaVista Softwrae, Inc.
|
||||
*
|
||||
* Maintainer: Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/mach/pci.h>
|
||||
|
||||
void __init gateway7001_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
||||
static int __init gateway7001_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
if (slot == 1)
|
||||
return IRQ_IXP4XX_GPIO11;
|
||||
else if (slot == 2)
|
||||
return IRQ_IXP4XX_GPIO10;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
struct hw_pci gateway7001_pci __initdata = {
|
||||
.nr_controllers = 1,
|
||||
.preinit = gateway7001_pci_preinit,
|
||||
.swizzle = pci_std_swizzle,
|
||||
.setup = ixp4xx_setup,
|
||||
.scan = ixp4xx_scan_bus,
|
||||
.map_irq = gateway7001_map_irq,
|
||||
};
|
||||
|
||||
int __init gateway7001_pci_init(void)
|
||||
{
|
||||
if (machine_is_gateway7001())
|
||||
pci_common_init(&gateway7001_pci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(gateway7001_pci_init);
|
108
arch/arm/mach-ixp4xx/gateway7001-setup.c
Normal file
108
arch/arm/mach-ixp4xx/gateway7001-setup.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* arch/arm/mach-ixp4xx/gateway7001-setup.c
|
||||
*
|
||||
* Board setup for the Gateway 7001 board
|
||||
*
|
||||
* Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* based on coyote-setup.c:
|
||||
* Copyright (C) 2003-2005 MontaVista Software, Inc.
|
||||
*
|
||||
* Author: Imre Kaloz <Kaloz@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
static struct flash_platform_data gateway7001_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static struct resource gateway7001_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device gateway7001_flash = {
|
||||
.name = "IXP4XX-Flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &gateway7001_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &gateway7001_flash_resource,
|
||||
};
|
||||
|
||||
static struct resource gateway7001_uart_resource = {
|
||||
.start = IXP4XX_UART2_BASE_PHYS,
|
||||
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct plat_serial8250_port gateway7001_uart_data[] = {
|
||||
{
|
||||
.mapbase = IXP4XX_UART2_BASE_PHYS,
|
||||
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
|
||||
.irq = IRQ_IXP4XX_UART2,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = IXP4XX_UART_XTAL,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device gateway7001_uart = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = gateway7001_uart_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &gateway7001_uart_resource,
|
||||
};
|
||||
|
||||
static struct platform_device *gateway7001_devices[] __initdata = {
|
||||
&gateway7001_flash,
|
||||
&gateway7001_uart
|
||||
};
|
||||
|
||||
static void __init gateway7001_init(void)
|
||||
{
|
||||
ixp4xx_sys_init();
|
||||
|
||||
gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
|
||||
gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
|
||||
|
||||
*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
|
||||
*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
|
||||
|
||||
platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MACH_GATEWAY7001
|
||||
MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
|
||||
/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
.init_machine = gateway7001_init,
|
||||
MACHINE_END
|
||||
#endif
|
|
@ -25,17 +25,13 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/arch/gtwx5715.h>
|
||||
#include <asm/mach/pci.h>
|
||||
|
||||
extern void ixp4xx_pci_preinit(void);
|
||||
extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
|
||||
extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
|
||||
|
||||
|
||||
/*
|
||||
* The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
|
||||
* Slot 0 isn't actually populated with a card connector but
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
#include <linux/tty.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/setup.h>
|
||||
|
@ -24,6 +28,7 @@
|
|||
#include <asm/irq.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
static struct flash_platform_data ixdp425_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
|
@ -44,6 +49,77 @@ static struct platform_device ixdp425_flash = {
|
|||
.resource = &ixdp425_flash_resource,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
|
||||
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
const char *part_probes[] = { "cmdlinepart", NULL };
|
||||
|
||||
static struct mtd_partition ixdp425_partitions[] = {
|
||||
{
|
||||
.name = "ixp400 NAND FS 0",
|
||||
.offset = 0,
|
||||
.size = SZ_8M
|
||||
}, {
|
||||
.name = "ixp400 NAND FS 1",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = MTDPART_SIZ_FULL
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static void
|
||||
ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
||||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
int offset = (int)this->priv;
|
||||
|
||||
if (ctrl & NAND_CTRL_CHANGE) {
|
||||
if (ctrl & NAND_NCE) {
|
||||
gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW);
|
||||
udelay(5);
|
||||
} else
|
||||
gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH);
|
||||
|
||||
offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0;
|
||||
offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0;
|
||||
this->priv = (void *)offset;
|
||||
}
|
||||
|
||||
if (cmd != NAND_CMD_NONE)
|
||||
writeb(cmd, this->IO_ADDR_W + offset);
|
||||
}
|
||||
|
||||
static struct platform_nand_data ixdp425_flash_nand_data = {
|
||||
.chip = {
|
||||
.chip_delay = 30,
|
||||
.options = NAND_NO_AUTOINCR,
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
.part_probe_types = part_probes,
|
||||
.partitions = ixdp425_partitions,
|
||||
.nr_partitions = ARRAY_SIZE(ixdp425_partitions),
|
||||
#endif
|
||||
},
|
||||
.ctrl = {
|
||||
.cmd_ctrl = ixdp425_flash_nand_cmd_ctrl
|
||||
}
|
||||
};
|
||||
|
||||
static struct resource ixdp425_flash_nand_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device ixdp425_flash_nand = {
|
||||
.name = "gen_nand",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &ixdp425_flash_nand_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &ixdp425_flash_nand_resource,
|
||||
};
|
||||
#endif /* CONFIG_MTD_NAND_PLATFORM */
|
||||
|
||||
static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = {
|
||||
.sda_pin = IXDP425_SDA_PIN,
|
||||
.scl_pin = IXDP425_SCL_PIN,
|
||||
|
@ -104,6 +180,10 @@ static struct platform_device ixdp425_uart = {
|
|||
static struct platform_device *ixdp425_devices[] __initdata = {
|
||||
&ixdp425_i2c_controller,
|
||||
&ixdp425_flash,
|
||||
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
|
||||
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
|
||||
&ixdp425_flash_nand,
|
||||
#endif
|
||||
&ixdp425_uart
|
||||
};
|
||||
|
||||
|
@ -115,6 +195,22 @@ static void __init ixdp425_init(void)
|
|||
ixdp425_flash_resource.end =
|
||||
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
|
||||
|
||||
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
|
||||
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
|
||||
ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3),
|
||||
ixdp425_flash_nand_resource.end = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1;
|
||||
|
||||
gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT);
|
||||
|
||||
/* Configure expansion bus for NAND Flash */
|
||||
*IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN |
|
||||
IXP4XX_EXP_BUS_STROBE_T(1) | /* extend by 1 clock */
|
||||
IXP4XX_EXP_BUS_CYCLES(0) | /* Intel cycles */
|
||||
IXP4XX_EXP_BUS_SIZE(0) | /* 512bytes addr space*/
|
||||
IXP4XX_EXP_BUS_WR_EN |
|
||||
IXP4XX_EXP_BUS_BYTE_EN; /* 8 bit data bus */
|
||||
#endif
|
||||
|
||||
if (cpu_is_ixp43x()) {
|
||||
ixdp425_uart.num_resources = 1;
|
||||
ixdp425_uart_data[1].flags = 0;
|
||||
|
|
63
arch/arm/mach-ixp4xx/wg302v2-pci.c
Normal file
63
arch/arm/mach-ixp4xx/wg302v2-pci.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* arch/arch/mach-ixp4xx/wg302v2-pci.c
|
||||
*
|
||||
* PCI setup routines for the Netgear WG302 v2 and WAG302 v2
|
||||
*
|
||||
* Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* based on coyote-pci.c:
|
||||
* Copyright (C) 2002 Jungo Software Technologies.
|
||||
* Copyright (C) 2003 MontaVista Software, Inc.
|
||||
*
|
||||
* Maintainer: Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/mach/pci.h>
|
||||
|
||||
void __init wg302v2_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_IXP4XX_GPIO8, IRQT_LOW);
|
||||
set_irq_type(IRQ_IXP4XX_GPIO9, IRQT_LOW);
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
||||
static int __init wg302v2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
if (slot == 1)
|
||||
return IRQ_IXP4XX_GPIO8;
|
||||
else if (slot == 2)
|
||||
return IRQ_IXP4XX_GPIO9;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
struct hw_pci wg302v2_pci __initdata = {
|
||||
.nr_controllers = 1,
|
||||
.preinit = wg302v2_pci_preinit,
|
||||
.swizzle = pci_std_swizzle,
|
||||
.setup = ixp4xx_setup,
|
||||
.scan = ixp4xx_scan_bus,
|
||||
.map_irq = wg302v2_map_irq,
|
||||
};
|
||||
|
||||
int __init wg302v2_pci_init(void)
|
||||
{
|
||||
if (machine_is_wg302v2())
|
||||
pci_common_init(&wg302v2_pci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(wg302v2_pci_init);
|
109
arch/arm/mach-ixp4xx/wg302v2-setup.c
Normal file
109
arch/arm/mach-ixp4xx/wg302v2-setup.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* arch/arm/mach-ixp4xx/wg302-setup.c
|
||||
*
|
||||
* Board setup for the Netgear WG302 v2 and WAG302 v2
|
||||
*
|
||||
* Copyright (C) 2007 Imre Kaloz <Kaloz@openwrt.org>
|
||||
*
|
||||
* based on coyote-setup.c:
|
||||
* Copyright (C) 2003-2005 MontaVista Software, Inc.
|
||||
*
|
||||
* Author: Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
static struct flash_platform_data wg302v2_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static struct resource wg302v2_flash_resource = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device wg302v2_flash = {
|
||||
.name = "IXP4XX-Flash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &wg302v2_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &wg302v2_flash_resource,
|
||||
};
|
||||
|
||||
static struct resource wg302v2_uart_resource = {
|
||||
.start = IXP4XX_UART2_BASE_PHYS,
|
||||
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct plat_serial8250_port wg302v2_uart_data[] = {
|
||||
{
|
||||
.mapbase = IXP4XX_UART2_BASE_PHYS,
|
||||
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
|
||||
.irq = IRQ_IXP4XX_UART2,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = IXP4XX_UART_XTAL,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_device wg302v2_uart = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = wg302v2_uart_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &wg302v2_uart_resource,
|
||||
};
|
||||
|
||||
static struct platform_device *wg302v2_devices[] __initdata = {
|
||||
&wg302v2_flash,
|
||||
&wg302v2_uart,
|
||||
};
|
||||
|
||||
static void __init wg302v2_init(void)
|
||||
{
|
||||
ixp4xx_sys_init();
|
||||
|
||||
wg302v2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
|
||||
wg302v2_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
|
||||
|
||||
*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
|
||||
*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
|
||||
|
||||
platform_add_devices(wg302v2_devices, ARRAY_SIZE(wg302v2_devices));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MACH_WG302V2
|
||||
MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2")
|
||||
/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.boot_params = 0x0100,
|
||||
.init_machine = wg302v2_init,
|
||||
MACHINE_END
|
||||
#endif
|
|
@ -3,7 +3,7 @@
|
|||
# Makefile for KS8695 architecture support
|
||||
#
|
||||
|
||||
obj-y := cpu.o irq.o time.o devices.o
|
||||
obj-y := cpu.o irq.o time.o gpio.o devices.o
|
||||
obj-m :=
|
||||
obj-n :=
|
||||
obj- :=
|
||||
|
|
218
arch/arm/mach-ks8695/gpio.c
Normal file
218
arch/arm/mach-ks8695/gpio.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* arch/arm/mach-ks8695/gpio.c
|
||||
*
|
||||
* Copyright (C) 2006 Andrew Victor
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
/*
|
||||
* Configure a GPIO line for either GPIO function, or its internal
|
||||
* function (Interrupt, Timer, etc).
|
||||
*/
|
||||
static void __init_or_module ks8695_gpio_mode(unsigned int pin, short gpio)
|
||||
{
|
||||
unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
|
||||
unsigned long x, flags;
|
||||
|
||||
if (pin > KS8695_GPIO_5) /* only GPIO 0..5 have internal functions */
|
||||
return;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
|
||||
if (gpio) /* GPIO: set bit to 0 */
|
||||
x &= ~enable[pin];
|
||||
else /* Internal function: set bit to 1 */
|
||||
x |= enable[pin];
|
||||
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
|
||||
static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 };
|
||||
|
||||
/*
|
||||
* Configure GPIO pin as external interrupt source.
|
||||
*/
|
||||
int __init_or_module ks8695_gpio_interrupt(unsigned int pin, unsigned int type)
|
||||
{
|
||||
unsigned long x, flags;
|
||||
|
||||
if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */
|
||||
return -EINVAL;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* set pin as input */
|
||||
x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
|
||||
x &= ~IOPM_(pin);
|
||||
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
/* Set IRQ triggering type */
|
||||
set_irq_type(gpio_irq[pin], type);
|
||||
|
||||
/* enable interrupt mode */
|
||||
ks8695_gpio_mode(pin, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ks8695_gpio_interrupt);
|
||||
|
||||
|
||||
|
||||
/* .... Generic GPIO interface .............................................. */
|
||||
|
||||
/*
|
||||
* Configure the GPIO line as an input.
|
||||
*/
|
||||
int __init_or_module gpio_direction_input(unsigned int pin)
|
||||
{
|
||||
unsigned long x, flags;
|
||||
|
||||
if (pin > KS8695_GPIO_15)
|
||||
return -EINVAL;
|
||||
|
||||
/* set pin to GPIO mode */
|
||||
ks8695_gpio_mode(pin, 1);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* set pin as input */
|
||||
x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
|
||||
x &= ~IOPM_(pin);
|
||||
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_direction_input);
|
||||
|
||||
|
||||
/*
|
||||
* Configure the GPIO line as an output, with default state.
|
||||
*/
|
||||
int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state)
|
||||
{
|
||||
unsigned long x, flags;
|
||||
|
||||
if (pin > KS8695_GPIO_15)
|
||||
return -EINVAL;
|
||||
|
||||
/* set pin to GPIO mode */
|
||||
ks8695_gpio_mode(pin, 1);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* set line state */
|
||||
x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
|
||||
if (state)
|
||||
x |= (1 << pin);
|
||||
else
|
||||
x &= ~(1 << pin);
|
||||
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
|
||||
|
||||
/* set pin as output */
|
||||
x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
|
||||
x |= IOPM_(pin);
|
||||
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_direction_output);
|
||||
|
||||
|
||||
/*
|
||||
* Set the state of an output GPIO line.
|
||||
*/
|
||||
void gpio_set_value(unsigned int pin, unsigned int state)
|
||||
{
|
||||
unsigned long x, flags;
|
||||
|
||||
if (pin > KS8695_GPIO_15)
|
||||
return;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* set output line state */
|
||||
x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
|
||||
if (state)
|
||||
x |= (1 << pin);
|
||||
else
|
||||
x &= ~(1 << pin);
|
||||
__raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_set_value);
|
||||
|
||||
|
||||
/*
|
||||
* Read the state of a GPIO line.
|
||||
*/
|
||||
int gpio_get_value(unsigned int pin)
|
||||
{
|
||||
unsigned long x;
|
||||
|
||||
if (pin > KS8695_GPIO_15)
|
||||
return -EINVAL;
|
||||
|
||||
x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
|
||||
return (x & (1 << pin)) != 0;
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_get_value);
|
||||
|
||||
|
||||
/*
|
||||
* Map GPIO line to IRQ number.
|
||||
*/
|
||||
int gpio_to_irq(unsigned int pin)
|
||||
{
|
||||
if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */
|
||||
return -EINVAL;
|
||||
|
||||
return gpio_irq[pin];
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_to_irq);
|
||||
|
||||
|
||||
/*
|
||||
* Map IRQ number to GPIO line.
|
||||
*/
|
||||
int irq_to_gpio(unsigned int irq)
|
||||
{
|
||||
if ((irq < KS8695_IRQ_EXTERN0) || (irq > KS8695_IRQ_EXTERN3))
|
||||
return -EINVAL;
|
||||
|
||||
return (irq - KS8695_IRQ_EXTERN0);
|
||||
}
|
||||
EXPORT_SYMBOL(irq_to_gpio);
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
struct clk {
|
||||
struct list_head node;
|
||||
|
@ -25,21 +24,21 @@ struct clk {
|
|||
};
|
||||
|
||||
static LIST_HEAD(clocks);
|
||||
static DECLARE_MUTEX(clocks_sem);
|
||||
static DEFINE_MUTEX(clocks_mutex);
|
||||
static DEFINE_SPINLOCK(clocks_lock);
|
||||
|
||||
struct clk *clk_get(struct device *dev, const char *id)
|
||||
{
|
||||
struct clk *p, *clk = ERR_PTR(-ENOENT);
|
||||
|
||||
down(&clocks_sem);
|
||||
mutex_lock(&clocks_mutex);
|
||||
list_for_each_entry(p, &clocks, node) {
|
||||
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
|
||||
clk = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
up(&clocks_sem);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
@ -101,18 +100,18 @@ static struct clk clk_gpio27 = {
|
|||
|
||||
int clk_register(struct clk *clk)
|
||||
{
|
||||
down(&clocks_sem);
|
||||
mutex_lock(&clocks_mutex);
|
||||
list_add(&clk->node, &clocks);
|
||||
up(&clocks_sem);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_register);
|
||||
|
||||
void clk_unregister(struct clk *clk)
|
||||
{
|
||||
down(&clocks_sem);
|
||||
mutex_lock(&clocks_mutex);
|
||||
list_del(&clk->node);
|
||||
up(&clocks_sem);
|
||||
mutex_unlock(&clocks_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_unregister);
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <asm/hardware/scoop.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
#include "sharpsl.h"
|
||||
|
||||
|
||||
|
@ -368,7 +369,7 @@ MACHINE_START(CORGI, "SHARP Corgi")
|
|||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_corgi,
|
||||
.map_io = pxa_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.init_machine = corgi_init,
|
||||
.timer = &pxa_timer,
|
||||
MACHINE_END
|
||||
|
@ -380,7 +381,7 @@ MACHINE_START(SHEPHERD, "SHARP Shepherd")
|
|||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_corgi,
|
||||
.map_io = pxa_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.init_machine = corgi_init,
|
||||
.timer = &pxa_timer,
|
||||
MACHINE_END
|
||||
|
@ -392,7 +393,7 @@ MACHINE_START(HUSKY, "SHARP Husky")
|
|||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_corgi,
|
||||
.map_io = pxa_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.init_machine = corgi_init,
|
||||
.timer = &pxa_timer,
|
||||
MACHINE_END
|
||||
|
|
11
arch/arm/mach-pxa/devices.h
Normal file
11
arch/arm/mach-pxa/devices.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
extern struct platform_device pxamci_device;
|
||||
extern struct platform_device pxaudc_device;
|
||||
extern struct platform_device pxafb_device;
|
||||
extern struct platform_device ffuart_device;
|
||||
extern struct platform_device btuart_device;
|
||||
extern struct platform_device stuart_device;
|
||||
extern struct platform_device hwuart_device;
|
||||
extern struct platform_device pxai2c_device;
|
||||
extern struct platform_device pxai2s_device;
|
||||
extern struct platform_device pxaficp_device;
|
||||
extern struct platform_device pxartc_device;
|
|
@ -25,12 +25,15 @@
|
|||
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
|
||||
static struct dma_channel {
|
||||
struct dma_channel {
|
||||
char *name;
|
||||
pxa_dma_prio prio;
|
||||
void (*irq_handler)(int, void *);
|
||||
void *data;
|
||||
} dma_channels[PXA_DMA_CHANNELS];
|
||||
};
|
||||
|
||||
static struct dma_channel *dma_channels;
|
||||
static int num_dma_channels;
|
||||
|
||||
int pxa_request_dma (char *name, pxa_dma_prio prio,
|
||||
void (*irq_handler)(int, void *),
|
||||
|
@ -47,8 +50,9 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
|
|||
|
||||
do {
|
||||
/* try grabbing a DMA channel with the requested priority */
|
||||
pxa_for_each_dma_prio (i, prio) {
|
||||
if (!dma_channels[i].name) {
|
||||
for (i = 0; i < num_dma_channels; i++) {
|
||||
if ((dma_channels[i].prio == prio) &&
|
||||
!dma_channels[i].name) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -91,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
|
|||
{
|
||||
int i, dint = DINT;
|
||||
|
||||
for (i = 0; i < PXA_DMA_CHANNELS; i++) {
|
||||
for (i = 0; i < num_dma_channels; i++) {
|
||||
if (dint & (1 << i)) {
|
||||
struct dma_channel *channel = &dma_channels[i];
|
||||
if (channel->name && channel->irq_handler) {
|
||||
|
@ -109,18 +113,32 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __init pxa_dma_init (void)
|
||||
int __init pxa_init_dma(int num_ch)
|
||||
{
|
||||
int ret;
|
||||
int i, ret;
|
||||
|
||||
ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL);
|
||||
if (ret)
|
||||
dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
|
||||
if (dma_channels == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
|
||||
if (ret) {
|
||||
printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
|
||||
return ret;
|
||||
}
|
||||
kfree(dma_channels);
|
||||
return ret;
|
||||
}
|
||||
|
||||
arch_initcall(pxa_dma_init);
|
||||
/* dma channel priorities on pxa2xx processors:
|
||||
* ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH
|
||||
* ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM
|
||||
* ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW
|
||||
*/
|
||||
for (i = 0; i < num_ch; i++)
|
||||
dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
|
||||
|
||||
num_dma_channels = num_ch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(pxa_request_dma);
|
||||
EXPORT_SYMBOL(pxa_free_dma);
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <asm/arch/irda.h>
|
||||
#include <asm/arch/i2c.h>
|
||||
|
||||
#include "devices.h"
|
||||
#include "generic.h"
|
||||
|
||||
/*
|
||||
|
@ -242,7 +243,7 @@ static struct resource pxamci_resources[] = {
|
|||
|
||||
static u64 pxamci_dmamask = 0xffffffffUL;
|
||||
|
||||
static struct platform_device pxamci_device = {
|
||||
struct platform_device pxamci_device = {
|
||||
.name = "pxa2xx-mci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
|
@ -281,7 +282,7 @@ static struct resource pxa2xx_udc_resources[] = {
|
|||
|
||||
static u64 udc_dma_mask = ~(u32)0;
|
||||
|
||||
static struct platform_device udc_device = {
|
||||
struct platform_device pxaudc_device = {
|
||||
.name = "pxa2xx-udc",
|
||||
.id = -1,
|
||||
.resource = pxa2xx_udc_resources,
|
||||
|
@ -307,7 +308,7 @@ static struct resource pxafb_resources[] = {
|
|||
|
||||
static u64 fb_dma_mask = ~(u64)0;
|
||||
|
||||
static struct platform_device pxafb_device = {
|
||||
struct platform_device pxafb_device = {
|
||||
.name = "pxa2xx-fb",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
|
@ -328,24 +329,24 @@ void __init set_pxa_fb_parent(struct device *parent_dev)
|
|||
pxafb_device.dev.parent = parent_dev;
|
||||
}
|
||||
|
||||
static struct platform_device ffuart_device = {
|
||||
struct platform_device ffuart_device = {
|
||||
.name = "pxa2xx-uart",
|
||||
.id = 0,
|
||||
};
|
||||
static struct platform_device btuart_device = {
|
||||
struct platform_device btuart_device = {
|
||||
.name = "pxa2xx-uart",
|
||||
.id = 1,
|
||||
};
|
||||
static struct platform_device stuart_device = {
|
||||
struct platform_device stuart_device = {
|
||||
.name = "pxa2xx-uart",
|
||||
.id = 2,
|
||||
};
|
||||
static struct platform_device hwuart_device = {
|
||||
struct platform_device hwuart_device = {
|
||||
.name = "pxa2xx-uart",
|
||||
.id = 3,
|
||||
};
|
||||
|
||||
static struct resource i2c_resources[] = {
|
||||
static struct resource pxai2c_resources[] = {
|
||||
{
|
||||
.start = 0x40301680,
|
||||
.end = 0x403016a3,
|
||||
|
@ -357,40 +358,19 @@ static struct resource i2c_resources[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct platform_device i2c_device = {
|
||||
struct platform_device pxai2c_device = {
|
||||
.name = "pxa2xx-i2c",
|
||||
.id = 0,
|
||||
.resource = i2c_resources,
|
||||
.num_resources = ARRAY_SIZE(i2c_resources),
|
||||
.resource = pxai2c_resources,
|
||||
.num_resources = ARRAY_SIZE(pxai2c_resources),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
static struct resource i2c_power_resources[] = {
|
||||
{
|
||||
.start = 0x40f00180,
|
||||
.end = 0x40f001a3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = IRQ_PWRI2C,
|
||||
.end = IRQ_PWRI2C,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device i2c_power_device = {
|
||||
.name = "pxa2xx-i2c",
|
||||
.id = 1,
|
||||
.resource = i2c_power_resources,
|
||||
.num_resources = ARRAY_SIZE(i2c_resources),
|
||||
};
|
||||
#endif
|
||||
|
||||
void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
|
||||
{
|
||||
i2c_device.dev.platform_data = info;
|
||||
pxai2c_device.dev.platform_data = info;
|
||||
}
|
||||
|
||||
static struct resource i2s_resources[] = {
|
||||
static struct resource pxai2s_resources[] = {
|
||||
{
|
||||
.start = 0x40400000,
|
||||
.end = 0x40400083,
|
||||
|
@ -402,16 +382,16 @@ static struct resource i2s_resources[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct platform_device i2s_device = {
|
||||
struct platform_device pxai2s_device = {
|
||||
.name = "pxa2xx-i2s",
|
||||
.id = -1,
|
||||
.resource = i2s_resources,
|
||||
.num_resources = ARRAY_SIZE(i2s_resources),
|
||||
.resource = pxai2s_resources,
|
||||
.num_resources = ARRAY_SIZE(pxai2s_resources),
|
||||
};
|
||||
|
||||
static u64 pxaficp_dmamask = ~(u32)0;
|
||||
|
||||
static struct platform_device pxaficp_device = {
|
||||
struct platform_device pxaficp_device = {
|
||||
.name = "pxa2xx-ir",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
|
@ -425,42 +405,7 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
|
|||
pxaficp_device.dev.platform_data = info;
|
||||
}
|
||||
|
||||
static struct platform_device pxartc_device = {
|
||||
struct platform_device pxartc_device = {
|
||||
.name = "sa1100-rtc",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&pxamci_device,
|
||||
&udc_device,
|
||||
&pxafb_device,
|
||||
&ffuart_device,
|
||||
&btuart_device,
|
||||
&stuart_device,
|
||||
&pxaficp_device,
|
||||
&i2c_device,
|
||||
#ifdef CONFIG_PXA27x
|
||||
&i2c_power_device,
|
||||
#endif
|
||||
&i2s_device,
|
||||
&pxartc_device,
|
||||
};
|
||||
|
||||
static int __init pxa_init(void)
|
||||
{
|
||||
int cpuid, ret;
|
||||
|
||||
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
|
||||
cpuid = read_cpuid(CPUID_ID);
|
||||
if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
|
||||
((cpuid >> 4) & 0xfff) == 0x290)
|
||||
ret = platform_device_register(&hwuart_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
subsys_initcall(pxa_init);
|
||||
|
|
|
@ -12,8 +12,12 @@
|
|||
struct sys_timer;
|
||||
|
||||
extern struct sys_timer pxa_timer;
|
||||
extern void __init pxa_init_irq_low(void);
|
||||
extern void __init pxa_init_irq_high(void);
|
||||
extern void __init pxa_init_irq_gpio(int gpio_nr);
|
||||
extern void __init pxa25x_init_irq(void);
|
||||
extern void __init pxa27x_init_irq(void);
|
||||
extern void __init pxa_map_io(void);
|
||||
extern void __init pxa_init_irq(void);
|
||||
|
||||
extern unsigned int get_clk_frequency_khz(int info);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <asm/arch/mmc.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
||||
/* TODO:
|
||||
* - add pxa2xx_audio_ops_t device structure
|
||||
|
@ -152,7 +153,7 @@ static void __init idp_init(void)
|
|||
static void __init idp_init_irq(void)
|
||||
{
|
||||
|
||||
pxa_init_irq();
|
||||
pxa25x_init_irq();
|
||||
|
||||
set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE);
|
||||
}
|
||||
|
|
|
@ -30,12 +30,12 @@
|
|||
|
||||
static void pxa_mask_low_irq(unsigned int irq)
|
||||
{
|
||||
ICMR &= ~(1 << (irq + PXA_IRQ_SKIP));
|
||||
ICMR &= ~(1 << irq);
|
||||
}
|
||||
|
||||
static void pxa_unmask_low_irq(unsigned int irq)
|
||||
{
|
||||
ICMR |= (1 << (irq + PXA_IRQ_SKIP));
|
||||
ICMR |= (1 << irq);
|
||||
}
|
||||
|
||||
static int pxa_set_wake(unsigned int irq, unsigned int on)
|
||||
|
@ -67,7 +67,27 @@ static struct irq_chip pxa_internal_chip_low = {
|
|||
.set_wake = pxa_set_wake,
|
||||
};
|
||||
|
||||
#if PXA_INTERNAL_IRQS > 32
|
||||
void __init pxa_init_irq_low(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
/* disable all IRQs */
|
||||
ICMR = 0;
|
||||
|
||||
/* all IRQs are IRQ, not FIQ */
|
||||
ICLR = 0;
|
||||
|
||||
/* only unmasked interrupts kick us out of idle */
|
||||
ICCR = 1;
|
||||
|
||||
for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
|
||||
set_irq_chip(irq, &pxa_internal_chip_low);
|
||||
set_irq_handler(irq, handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
|
||||
/*
|
||||
* This is for the second set of internal IRQs as found on the PXA27x.
|
||||
|
@ -75,12 +95,12 @@ static struct irq_chip pxa_internal_chip_low = {
|
|||
|
||||
static void pxa_mask_high_irq(unsigned int irq)
|
||||
{
|
||||
ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP));
|
||||
ICMR2 &= ~(1 << (irq - 32));
|
||||
}
|
||||
|
||||
static void pxa_unmask_high_irq(unsigned int irq)
|
||||
{
|
||||
ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP));
|
||||
ICMR2 |= (1 << (irq - 32));
|
||||
}
|
||||
|
||||
static struct irq_chip pxa_internal_chip_high = {
|
||||
|
@ -90,6 +110,19 @@ static struct irq_chip pxa_internal_chip_high = {
|
|||
.unmask = pxa_unmask_high_irq,
|
||||
};
|
||||
|
||||
void __init pxa_init_irq_high(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
ICMR2 = 0;
|
||||
ICLR2 = 0;
|
||||
|
||||
for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
|
||||
set_irq_chip(irq, &pxa_internal_chip_high);
|
||||
set_irq_handler(irq, handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note that if an input/irq line ever gets changed to an output during
|
||||
|
@ -217,7 +250,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
|
|||
do {
|
||||
loop = 0;
|
||||
|
||||
mask = GEDR0 & ~3;
|
||||
mask = GEDR0 & GPIO_IRQ_mask[0] & ~3;
|
||||
if (mask) {
|
||||
GEDR0 = mask;
|
||||
irq = IRQ_GPIO(2);
|
||||
|
@ -233,7 +266,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
|
|||
loop = 1;
|
||||
}
|
||||
|
||||
mask = GEDR1;
|
||||
mask = GEDR1 & GPIO_IRQ_mask[1];
|
||||
if (mask) {
|
||||
GEDR1 = mask;
|
||||
irq = IRQ_GPIO(32);
|
||||
|
@ -248,7 +281,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
|
|||
loop = 1;
|
||||
}
|
||||
|
||||
mask = GEDR2;
|
||||
mask = GEDR2 & GPIO_IRQ_mask[2];
|
||||
if (mask) {
|
||||
GEDR2 = mask;
|
||||
irq = IRQ_GPIO(64);
|
||||
|
@ -263,8 +296,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
|
|||
loop = 1;
|
||||
}
|
||||
|
||||
#if PXA_LAST_GPIO >= 96
|
||||
mask = GEDR3;
|
||||
mask = GEDR3 & GPIO_IRQ_mask[3];
|
||||
if (mask) {
|
||||
GEDR3 = mask;
|
||||
irq = IRQ_GPIO(96);
|
||||
|
@ -278,7 +310,6 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
|
|||
} while (mask);
|
||||
loop = 1;
|
||||
}
|
||||
#endif
|
||||
} while (loop);
|
||||
}
|
||||
|
||||
|
@ -314,64 +345,27 @@ static struct irq_chip pxa_muxed_gpio_chip = {
|
|||
.set_wake = pxa_set_gpio_wake,
|
||||
};
|
||||
|
||||
|
||||
void __init pxa_init_irq(void)
|
||||
void __init pxa_init_irq_gpio(int gpio_nr)
|
||||
{
|
||||
int irq;
|
||||
|
||||
/* disable all IRQs */
|
||||
ICMR = 0;
|
||||
|
||||
/* all IRQs are IRQ, not FIQ */
|
||||
ICLR = 0;
|
||||
int irq, i;
|
||||
|
||||
/* clear all GPIO edge detects */
|
||||
GFER0 = 0;
|
||||
GFER1 = 0;
|
||||
GFER2 = 0;
|
||||
GRER0 = 0;
|
||||
GRER1 = 0;
|
||||
GRER2 = 0;
|
||||
GEDR0 = GEDR0;
|
||||
GEDR1 = GEDR1;
|
||||
GEDR2 = GEDR2;
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
/* And similarly for the extra regs on the PXA27x */
|
||||
ICMR2 = 0;
|
||||
ICLR2 = 0;
|
||||
GFER3 = 0;
|
||||
GRER3 = 0;
|
||||
GEDR3 = GEDR3;
|
||||
#endif
|
||||
|
||||
/* only unmasked interrupts kick us out of idle */
|
||||
ICCR = 1;
|
||||
for (i = 0; i < gpio_nr; i += 32) {
|
||||
GFER(i) = 0;
|
||||
GRER(i) = 0;
|
||||
GEDR(i) = GEDR(i);
|
||||
}
|
||||
|
||||
/* GPIO 0 and 1 must have their mask bit always set */
|
||||
GPIO_IRQ_mask[0] = 3;
|
||||
|
||||
for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
|
||||
set_irq_chip(irq, &pxa_internal_chip_low);
|
||||
set_irq_handler(irq, handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
|
||||
#if PXA_INTERNAL_IRQS > 32
|
||||
for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) {
|
||||
set_irq_chip(irq, &pxa_internal_chip_high);
|
||||
set_irq_handler(irq, handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
|
||||
set_irq_chip(irq, &pxa_low_gpio_chip);
|
||||
set_irq_handler(irq, handle_edge_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
|
||||
for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) {
|
||||
for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(gpio_nr); irq++) {
|
||||
set_irq_chip(irq, &pxa_muxed_gpio_chip);
|
||||
set_irq_handler(irq, handle_edge_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <asm/arch/ohci.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
||||
|
||||
static unsigned int lpd270_irq_enabled;
|
||||
|
@ -97,7 +98,7 @@ static void __init lpd270_init_irq(void)
|
|||
{
|
||||
int irq;
|
||||
|
||||
pxa_init_irq();
|
||||
pxa27x_init_irq();
|
||||
|
||||
__raw_writew(0, LPD270_INT_MASK);
|
||||
__raw_writew(0, LPD270_INT_STATUS);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <asm/arch/mmc.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
||||
|
||||
#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
|
||||
|
@ -103,7 +104,7 @@ static void __init lubbock_init_irq(void)
|
|||
{
|
||||
int irq;
|
||||
|
||||
pxa_init_irq();
|
||||
pxa25x_init_irq();
|
||||
|
||||
/* setup extra lubbock irqs */
|
||||
for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <asm/arch/ohci.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
||||
|
||||
static unsigned long mainstone_irq_enabled;
|
||||
|
@ -89,7 +90,7 @@ static void __init mainstone_init_irq(void)
|
|||
{
|
||||
int irq;
|
||||
|
||||
pxa_init_irq();
|
||||
pxa27x_init_irq();
|
||||
|
||||
/* setup extra Mainstone irqs */
|
||||
for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
|
||||
|
|
|
@ -77,7 +77,6 @@ int pxa_pm_enter(suspend_state_t state)
|
|||
{
|
||||
unsigned long sleep_save[SLEEP_SAVE_SIZE];
|
||||
unsigned long checksum = 0;
|
||||
struct timespec delta, rtc;
|
||||
int i;
|
||||
extern void pxa_cpu_pm_enter(suspend_state_t state);
|
||||
|
||||
|
@ -87,11 +86,6 @@ int pxa_pm_enter(suspend_state_t state)
|
|||
iwmmxt_task_disable(NULL);
|
||||
#endif
|
||||
|
||||
/* preserve current time */
|
||||
rtc.tv_sec = RCNR;
|
||||
rtc.tv_nsec = 0;
|
||||
save_time_delta(&delta, &rtc);
|
||||
|
||||
SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
|
||||
SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
|
||||
SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
|
||||
|
@ -183,10 +177,6 @@ int pxa_pm_enter(suspend_state_t state)
|
|||
|
||||
RESTORE(PSTR);
|
||||
|
||||
/* restore current time */
|
||||
rtc.tv_sec = RCNR;
|
||||
restore_time_delta(&delta, &rtc);
|
||||
|
||||
#ifdef DEBUG
|
||||
printk(KERN_DEBUG "*** made it back from resume\n");
|
||||
#endif
|
||||
|
@ -200,40 +190,3 @@ unsigned long sleep_phys_sp(void *sp)
|
|||
{
|
||||
return virt_to_phys(sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after processes are frozen, but before we shut down devices.
|
||||
*/
|
||||
int pxa_pm_prepare(suspend_state_t state)
|
||||
{
|
||||
extern int pxa_cpu_pm_prepare(suspend_state_t state);
|
||||
|
||||
return pxa_cpu_pm_prepare(state);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(pxa_pm_prepare);
|
||||
|
||||
/*
|
||||
* Called after devices are re-setup, but before processes are thawed.
|
||||
*/
|
||||
int pxa_pm_finish(suspend_state_t state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(pxa_pm_finish);
|
||||
|
||||
static struct pm_ops pxa_pm_ops = {
|
||||
.prepare = pxa_pm_prepare,
|
||||
.enter = pxa_pm_enter,
|
||||
.finish = pxa_pm_finish,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init pxa_pm_init(void)
|
||||
{
|
||||
pm_set_ops(&pxa_pm_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(pxa_pm_init);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <asm/mach/sharpsl_param.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
#include "sharpsl.h"
|
||||
|
||||
static struct resource poodle_scoop_resources[] = {
|
||||
|
@ -412,7 +413,7 @@ MACHINE_START(POODLE, "SHARP Poodle")
|
|||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_poodle,
|
||||
.map_io = pxa_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.timer = &pxa_timer,
|
||||
.init_machine = poodle_init,
|
||||
MACHINE_END
|
||||
|
|
|
@ -19,12 +19,17 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#include <asm/arch/pm.h>
|
||||
#include <asm/arch/dma.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
||||
/*
|
||||
* Various clock factors driven by the CCCR register.
|
||||
|
@ -105,18 +110,6 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
int pxa_cpu_pm_prepare(suspend_state_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_SUSPEND_MEM:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pxa_cpu_pm_enter(suspend_state_t state)
|
||||
{
|
||||
extern void pxa_cpu_suspend(unsigned int);
|
||||
|
@ -133,4 +126,49 @@ void pxa_cpu_pm_enter(suspend_state_t state)
|
|||
}
|
||||
}
|
||||
|
||||
static struct pm_ops pxa25x_pm_ops = {
|
||||
.enter = pxa_pm_enter,
|
||||
.valid = pm_valid_only_mem,
|
||||
};
|
||||
#endif
|
||||
|
||||
void __init pxa25x_init_irq(void)
|
||||
{
|
||||
pxa_init_irq_low();
|
||||
pxa_init_irq_gpio(85);
|
||||
}
|
||||
|
||||
static struct platform_device *pxa25x_devices[] __initdata = {
|
||||
&pxamci_device,
|
||||
&pxaudc_device,
|
||||
&pxafb_device,
|
||||
&ffuart_device,
|
||||
&btuart_device,
|
||||
&stuart_device,
|
||||
&pxai2c_device,
|
||||
&pxai2s_device,
|
||||
&pxaficp_device,
|
||||
&pxartc_device,
|
||||
};
|
||||
|
||||
static int __init pxa25x_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
|
||||
if ((ret = pxa_init_dma(16)))
|
||||
return ret;
|
||||
#ifdef CONFIG_PM
|
||||
pm_set_ops(&pxa25x_pm_ops);
|
||||
#endif
|
||||
ret = platform_add_devices(pxa25x_devices,
|
||||
ARRAY_SIZE(pxa25x_devices));
|
||||
}
|
||||
/* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
|
||||
if (cpu_is_pxa25x())
|
||||
ret = platform_device_register(&hwuart_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
subsys_initcall(pxa25x_init);
|
||||
|
|
|
@ -19,10 +19,14 @@
|
|||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/arch/irqs.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#include <asm/arch/ohci.h>
|
||||
#include <asm/arch/pm.h>
|
||||
#include <asm/arch/dma.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
||||
/* Crystal clock: 13MHz */
|
||||
#define BASE_CLK 13000000
|
||||
|
@ -122,17 +126,6 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
|
|||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
int pxa_cpu_pm_prepare(suspend_state_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_SUSPEND_MEM:
|
||||
case PM_SUSPEND_STANDBY:
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void pxa_cpu_pm_enter(suspend_state_t state)
|
||||
{
|
||||
extern void pxa_cpu_standby(void);
|
||||
|
@ -162,6 +155,15 @@ void pxa_cpu_pm_enter(suspend_state_t state)
|
|||
}
|
||||
}
|
||||
|
||||
static int pxa27x_pm_valid(suspend_state_t state)
|
||||
{
|
||||
return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
|
||||
}
|
||||
|
||||
static struct pm_ops pxa27x_pm_ops = {
|
||||
.enter = pxa_pm_enter,
|
||||
.valid = pxa27x_pm_valid,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -183,7 +185,7 @@ static struct resource pxa27x_ohci_resources[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct platform_device ohci_device = {
|
||||
static struct platform_device pxaohci_device = {
|
||||
.name = "pxa27x-ohci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
|
@ -196,16 +198,62 @@ static struct platform_device ohci_device = {
|
|||
|
||||
void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
|
||||
{
|
||||
ohci_device.dev.platform_data = info;
|
||||
pxaohci_device.dev.platform_data = info;
|
||||
}
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&ohci_device,
|
||||
static struct resource i2c_power_resources[] = {
|
||||
{
|
||||
.start = 0x40f00180,
|
||||
.end = 0x40f001a3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = IRQ_PWRI2C,
|
||||
.end = IRQ_PWRI2C,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device pxai2c_power_device = {
|
||||
.name = "pxa2xx-i2c",
|
||||
.id = 1,
|
||||
.resource = i2c_power_resources,
|
||||
.num_resources = ARRAY_SIZE(i2c_power_resources),
|
||||
};
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&pxamci_device,
|
||||
&pxaudc_device,
|
||||
&pxafb_device,
|
||||
&ffuart_device,
|
||||
&btuart_device,
|
||||
&stuart_device,
|
||||
&pxai2c_device,
|
||||
&pxai2c_power_device,
|
||||
&pxai2s_device,
|
||||
&pxaficp_device,
|
||||
&pxartc_device,
|
||||
&pxaohci_device,
|
||||
};
|
||||
|
||||
void __init pxa27x_init_irq(void)
|
||||
{
|
||||
pxa_init_irq_low();
|
||||
pxa_init_irq_high();
|
||||
pxa_init_irq_gpio(128);
|
||||
}
|
||||
|
||||
static int __init pxa27x_init(void)
|
||||
{
|
||||
return platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
int ret = 0;
|
||||
if (cpu_is_pxa27x()) {
|
||||
if ((ret = pxa_init_dma(32)))
|
||||
return ret;
|
||||
#ifdef CONFIG_PM
|
||||
pm_set_ops(&pxa27x_pm_ops);
|
||||
#endif
|
||||
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
subsys_initcall(pxa27x_init);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <asm/hardware/scoop.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
#include "sharpsl.h"
|
||||
|
||||
/*
|
||||
|
@ -560,7 +561,7 @@ MACHINE_START(SPITZ, "SHARP Spitz")
|
|||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_spitz,
|
||||
.map_io = pxa_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.init_machine = spitz_init,
|
||||
.timer = &pxa_timer,
|
||||
MACHINE_END
|
||||
|
@ -572,7 +573,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
|
|||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_spitz,
|
||||
.map_io = pxa_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.init_machine = spitz_init,
|
||||
.timer = &pxa_timer,
|
||||
MACHINE_END
|
||||
|
@ -584,7 +585,7 @@ MACHINE_START(AKITA, "SHARP Akita")
|
|||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_spitz,
|
||||
.map_io = pxa_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.init_machine = akita_init,
|
||||
.timer = &pxa_timer,
|
||||
MACHINE_END
|
||||
|
|
|
@ -30,11 +30,6 @@
|
|||
#include <asm/arch/pxa-regs.h>
|
||||
|
||||
|
||||
static inline unsigned long pxa_get_rtc_time(void)
|
||||
{
|
||||
return RCNR;
|
||||
}
|
||||
|
||||
static int pxa_set_rtc(void)
|
||||
{
|
||||
unsigned long current_time = xtime.tv_sec;
|
||||
|
@ -122,10 +117,6 @@ static void __init pxa_timer_init(void)
|
|||
|
||||
set_rtc = pxa_set_rtc;
|
||||
|
||||
tv.tv_nsec = 0;
|
||||
tv.tv_sec = pxa_get_rtc_time();
|
||||
do_settimeofday(&tv);
|
||||
|
||||
OIER = 0; /* disable any timer interrupts */
|
||||
OSSR = 0xf; /* clear status on all timers */
|
||||
setup_irq(IRQ_OST0, &pxa_timer_irq);
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include <asm/mach/sharpsl_param.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
/*
|
||||
* SCOOP Device
|
||||
|
@ -332,7 +332,7 @@ MACHINE_START(TOSA, "SHARP Tosa")
|
|||
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
|
||||
.fixup = fixup_tosa,
|
||||
.map_io = pxa_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.init_machine = tosa_init,
|
||||
.timer = &pxa_timer,
|
||||
MACHINE_END
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <asm/arch/ohci.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
||||
/********************************************************************************************
|
||||
* ONBOARD FLASH
|
||||
|
@ -503,7 +504,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
|
|||
.boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
|
||||
.init_machine = trizeps4_init,
|
||||
.map_io = trizeps4_map_io,
|
||||
.init_irq = pxa_init_irq,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.timer = &pxa_timer,
|
||||
MACHINE_END
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/dm9000.h>
|
||||
|
||||
#include <net/ax88796.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
@ -409,6 +411,61 @@ static struct s3c2410_platform_i2c bast_i2c_info = {
|
|||
.max_freq = 130*1000,
|
||||
};
|
||||
|
||||
/* Asix AX88796 10/100 ethernet controller */
|
||||
|
||||
static struct ax_plat_data bast_asix_platdata = {
|
||||
.flags = AXFLG_MAC_FROMDEV,
|
||||
.wordlength = 2,
|
||||
.dcr_val = 0x48,
|
||||
.rcr_val = 0x40,
|
||||
};
|
||||
|
||||
static struct resource bast_asix_resource[] = {
|
||||
[0] = {
|
||||
.start = S3C2410_CS5 + BAST_PA_ASIXNET,
|
||||
.end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
|
||||
.end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_ASIX,
|
||||
.end = IRQ_ASIX,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device bast_device_asix = {
|
||||
.name = "ax88796",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(bast_asix_resource),
|
||||
.resource = bast_asix_resource,
|
||||
.dev = {
|
||||
.platform_data = &bast_asix_platdata
|
||||
}
|
||||
};
|
||||
|
||||
/* Asix AX88796 10/100 ethernet controller parallel port */
|
||||
|
||||
static struct resource bast_asixpp_resource[] = {
|
||||
[0] = {
|
||||
.start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20),
|
||||
.end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device bast_device_axpp = {
|
||||
.name = "ax88796-pp",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(bast_asixpp_resource),
|
||||
.resource = bast_asixpp_resource,
|
||||
};
|
||||
|
||||
/* LCD/VGA controller */
|
||||
|
||||
static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
|
||||
.width = 640,
|
||||
|
@ -453,6 +510,8 @@ static struct platform_device *bast_devices[] __initdata = {
|
|||
&s3c_device_nand,
|
||||
&bast_device_nor,
|
||||
&bast_device_dm9k,
|
||||
&bast_device_asix,
|
||||
&bast_device_axpp,
|
||||
&bast_sio,
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include <linux/serial_core.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/sm501.h>
|
||||
#include <linux/sm501-regs.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
@ -42,6 +45,8 @@
|
|||
#include <linux/mtd/nand_ecc.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
#include <net/ax88796.h>
|
||||
|
||||
#include <asm/plat-s3c24xx/clock.h>
|
||||
#include <asm/plat-s3c24xx/devs.h>
|
||||
#include <asm/plat-s3c24xx/cpu.h>
|
||||
|
@ -153,6 +158,29 @@ static struct mtd_partition anubis_default_nand_part[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static struct mtd_partition anubis_default_nand_part_large[] = {
|
||||
[0] = {
|
||||
.name = "Boot Agent",
|
||||
.size = SZ_128K,
|
||||
.offset = 0,
|
||||
},
|
||||
[1] = {
|
||||
.name = "/boot",
|
||||
.size = SZ_4M - SZ_128K,
|
||||
.offset = SZ_128K,
|
||||
},
|
||||
[2] = {
|
||||
.name = "user1",
|
||||
.offset = SZ_4M,
|
||||
.size = SZ_32M - SZ_4M,
|
||||
},
|
||||
[3] = {
|
||||
.name = "user2",
|
||||
.offset = SZ_32M,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
}
|
||||
};
|
||||
|
||||
/* the Anubis has 3 selectable slots for nand-flash, the two
|
||||
* on-board chip areas, as well as the external slot.
|
||||
*
|
||||
|
@ -260,6 +288,104 @@ static struct platform_device anubis_device_ide1 = {
|
|||
.resource = anubis_ide1_resource,
|
||||
};
|
||||
|
||||
/* Asix AX88796 10/100 ethernet controller */
|
||||
|
||||
static struct ax_plat_data anubis_asix_platdata = {
|
||||
.flags = AXFLG_MAC_FROMDEV,
|
||||
.wordlength = 2,
|
||||
.dcr_val = 0x48,
|
||||
.rcr_val = 0x40,
|
||||
};
|
||||
|
||||
static struct resource anubis_asix_resource[] = {
|
||||
[0] = {
|
||||
.start = S3C2410_CS5,
|
||||
.end = S3C2410_CS5 + (0x20 * 0x20) -1,
|
||||
.flags = IORESOURCE_MEM
|
||||
},
|
||||
[1] = {
|
||||
.start = IRQ_ASIX,
|
||||
.end = IRQ_ASIX,
|
||||
.flags = IORESOURCE_IRQ
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device anubis_device_asix = {
|
||||
.name = "ax88796",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(anubis_asix_resource),
|
||||
.resource = anubis_asix_resource,
|
||||
.dev = {
|
||||
.platform_data = &anubis_asix_platdata,
|
||||
}
|
||||
};
|
||||
|
||||
/* SM501 */
|
||||
|
||||
static struct resource anubis_sm501_resource[] = {
|
||||
[0] = {
|
||||
.start = S3C2410_CS2,
|
||||
.end = S3C2410_CS2 + SZ_8M,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = S3C2410_CS2 + SZ_64M - SZ_2M,
|
||||
.end = S3C2410_CS2 + SZ_64M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_EINT0,
|
||||
.end = IRQ_EINT0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct sm501_initdata anubis_sm501_initdata = {
|
||||
.gpio_high = {
|
||||
.set = 0x3F000000, /* 24bit panel */
|
||||
.mask = 0x0,
|
||||
},
|
||||
.misc_timing = {
|
||||
.set = 0x010100, /* SDRAM timing */
|
||||
.mask = 0x1F1F00,
|
||||
},
|
||||
.misc_control = {
|
||||
.set = SM501_MISC_PNL_24BIT,
|
||||
.mask = 0,
|
||||
},
|
||||
|
||||
/* set the SDRAM and bus clocks */
|
||||
.mclk = 72 * MHZ,
|
||||
.m1xclk = 144 * MHZ,
|
||||
};
|
||||
|
||||
static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
|
||||
[0] = {
|
||||
.pin_scl = 44,
|
||||
.pin_sda = 45,
|
||||
},
|
||||
[1] = {
|
||||
.pin_scl = 40,
|
||||
.pin_sda = 41,
|
||||
},
|
||||
};
|
||||
|
||||
static struct sm501_platdata anubis_sm501_platdata = {
|
||||
.init = &anubis_sm501_initdata,
|
||||
.gpio_i2c = anubis_sm501_gpio_i2c,
|
||||
.gpio_i2c_nr = ARRAY_SIZE(anubis_sm501_gpio_i2c),
|
||||
};
|
||||
|
||||
static struct platform_device anubis_device_sm501 = {
|
||||
.name = "sm501",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(anubis_sm501_resource),
|
||||
.resource = anubis_sm501_resource,
|
||||
.dev = {
|
||||
.platform_data = &anubis_sm501_platdata,
|
||||
},
|
||||
};
|
||||
|
||||
/* Standard Anubis devices */
|
||||
|
||||
static struct platform_device *anubis_devices[] __initdata = {
|
||||
|
@ -271,6 +397,8 @@ static struct platform_device *anubis_devices[] __initdata = {
|
|||
&s3c_device_nand,
|
||||
&anubis_device_ide0,
|
||||
&anubis_device_ide1,
|
||||
&anubis_device_asix,
|
||||
&anubis_device_sm501,
|
||||
};
|
||||
|
||||
static struct clk *anubis_clocks[] = {
|
||||
|
@ -304,8 +432,17 @@ static void __init anubis_map_io(void)
|
|||
s3c24xx_init_clocks(0);
|
||||
s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
|
||||
|
||||
/* ensure that the GPIO is setup */
|
||||
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
|
||||
/* check for the newer revision boards with large page nand */
|
||||
|
||||
if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
|
||||
printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
|
||||
__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
|
||||
anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
|
||||
anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
|
||||
} else {
|
||||
/* ensure that the GPIO is setup */
|
||||
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init anubis_init(void)
|
||||
|
|
|
@ -166,6 +166,29 @@ static struct mtd_partition osiris_default_nand_part[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static struct mtd_partition osiris_default_nand_part_large[] = {
|
||||
[0] = {
|
||||
.name = "Boot Agent",
|
||||
.size = SZ_128K,
|
||||
.offset = 0,
|
||||
},
|
||||
[1] = {
|
||||
.name = "/boot",
|
||||
.size = SZ_4M - SZ_128K,
|
||||
.offset = SZ_128K,
|
||||
},
|
||||
[2] = {
|
||||
.name = "user1",
|
||||
.offset = SZ_4M,
|
||||
.size = SZ_32M - SZ_4M,
|
||||
},
|
||||
[3] = {
|
||||
.name = "user2",
|
||||
.offset = SZ_32M,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
}
|
||||
};
|
||||
|
||||
/* the Osiris has 3 selectable slots for nand-flash, the two
|
||||
* on-board chip areas, as well as the external slot.
|
||||
*
|
||||
|
@ -322,14 +345,23 @@ static void __init osiris_map_io(void)
|
|||
s3c24xx_init_clocks(0);
|
||||
s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
|
||||
|
||||
/* check for the newer revision boards with large page nand */
|
||||
|
||||
if ((__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK) >= 4) {
|
||||
printk(KERN_INFO "OSIRIS-B detected (revision %d)\n",
|
||||
__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK);
|
||||
osiris_nand_sets[0].partitions = osiris_default_nand_part_large;
|
||||
osiris_nand_sets[0].nr_partitions = ARRAY_SIZE(osiris_default_nand_part_large);
|
||||
} else {
|
||||
/* write-protect line to the NAND */
|
||||
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
|
||||
}
|
||||
|
||||
/* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
|
||||
|
||||
local_irq_save(flags);
|
||||
__raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
|
||||
local_irq_restore(flags);
|
||||
|
||||
/* write-protect line to the NAND */
|
||||
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
|
||||
}
|
||||
|
||||
static void __init osiris_init(void)
|
||||
|
|
|
@ -57,12 +57,7 @@ enum { SLEEP_SAVE_SP = 0,
|
|||
static int sa11x0_pm_enter(suspend_state_t state)
|
||||
{
|
||||
unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
|
||||
struct timespec delta, rtc;
|
||||
|
||||
/* preserve current time */
|
||||
rtc.tv_sec = RCNR;
|
||||
rtc.tv_nsec = 0;
|
||||
save_time_delta(&delta, &rtc);
|
||||
gpio = GPLR;
|
||||
|
||||
/* save vital registers */
|
||||
|
@ -119,10 +114,6 @@ static int sa11x0_pm_enter(suspend_state_t state)
|
|||
*/
|
||||
PSSR = PSSR_PH;
|
||||
|
||||
/* restore current time */
|
||||
rtc.tv_sec = RCNR;
|
||||
restore_time_delta(&delta, &rtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,25 +21,6 @@
|
|||
#define RTC_DEF_DIVIDER (32768 - 1)
|
||||
#define RTC_DEF_TRIM 0
|
||||
|
||||
static unsigned long __init sa1100_get_rtc_time(void)
|
||||
{
|
||||
/*
|
||||
* According to the manual we should be able to let RTTR be zero
|
||||
* and then a default divisor for a 32.768KHz clock is used.
|
||||
* Apparently this doesn't work, at least for my SA1110 rev 5.
|
||||
* If the clock divider is uninitialized then reset it to the
|
||||
* default value to get the 1Hz clock.
|
||||
*/
|
||||
if (RTTR == 0) {
|
||||
RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
|
||||
printk(KERN_WARNING "Warning: uninitialized Real Time Clock\n");
|
||||
/* The current RTC value probably doesn't make sense either */
|
||||
RCNR = 0;
|
||||
return 0;
|
||||
}
|
||||
return RCNR;
|
||||
}
|
||||
|
||||
static int sa1100_set_rtc(void)
|
||||
{
|
||||
unsigned long current_time = xtime.tv_sec;
|
||||
|
@ -117,15 +98,10 @@ static struct irqaction sa1100_timer_irq = {
|
|||
|
||||
static void __init sa1100_timer_init(void)
|
||||
{
|
||||
struct timespec tv;
|
||||
unsigned long flags;
|
||||
|
||||
set_rtc = sa1100_set_rtc;
|
||||
|
||||
tv.tv_nsec = 0;
|
||||
tv.tv_sec = sa1100_get_rtc_time();
|
||||
do_settimeofday(&tv);
|
||||
|
||||
OIER = 0; /* disable any timer interrupts */
|
||||
OSSR = 0xf; /* clear status on all timers */
|
||||
setup_irq(IRQ_OST0, &sa1100_timer_irq);
|
||||
|
|
|
@ -280,7 +280,10 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
|
|||
if (!type)
|
||||
return NULL;
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
/*
|
||||
* Page align the mapping size, taking account of any offset.
|
||||
*/
|
||||
size = PAGE_ALIGN(offset + size);
|
||||
|
||||
area = get_vm_area(size, VM_IOREMAP);
|
||||
if (!area)
|
||||
|
@ -325,11 +328,6 @@ __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
|
|||
if (!size || last_addr < phys_addr)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Page align the mapping size
|
||||
*/
|
||||
size = PAGE_ALIGN(last_addr + 1) - phys_addr;
|
||||
|
||||
return __arm_ioremap_pfn(pfn, offset, size, mtype);
|
||||
}
|
||||
EXPORT_SYMBOL(__arm_ioremap);
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
#undef MMC_STRPCL
|
||||
#undef MMC_STAT
|
||||
#undef MMC_CLKRT
|
||||
#undef MMC_SPI
|
||||
#undef MMC_CMDAT
|
||||
#undef MMC_RESTO
|
||||
#undef MMC_RDTO
|
||||
#undef MMC_BLKLEN
|
||||
#undef MMC_NOB
|
||||
#undef MMC_PRTBUF
|
||||
#undef MMC_I_MASK
|
||||
#undef END_CMD_RES
|
||||
#undef PRG_DONE
|
||||
#undef DATA_TRAN_DONE
|
||||
#undef MMC_I_REG
|
||||
#undef MMC_CMD
|
||||
#undef MMC_ARGH
|
||||
#undef MMC_ARGL
|
||||
#undef MMC_RES
|
||||
#undef MMC_RXFIFO
|
||||
#undef MMC_TXFIFO
|
||||
|
||||
#define MMC_STRPCL 0x0000
|
||||
#define STOP_CLOCK (1 << 0)
|
||||
#define START_CLOCK (2 << 0)
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
include include/asm-generic/Kbuild.asm
|
||||
|
||||
unifdef-y += hwcap.h
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#ifndef AT91_DBGU_H
|
||||
#define AT91_DBGU_H
|
||||
|
||||
#ifdef AT91_DBGU
|
||||
#define AT91_DBGU_CR (AT91_DBGU + 0x00) /* Control Register */
|
||||
#define AT91_DBGU_MR (AT91_DBGU + 0x04) /* Mode Register */
|
||||
#define AT91_DBGU_IER (AT91_DBGU + 0x08) /* Interrupt Enable Register */
|
||||
|
@ -30,6 +31,15 @@
|
|||
|
||||
#define AT91_DBGU_CIDR (AT91_DBGU + 0x40) /* Chip ID Register */
|
||||
#define AT91_DBGU_EXID (AT91_DBGU + 0x44) /* Chip ID Extension Register */
|
||||
#define AT91_DBGU_FNR (AT91_DBGU + 0x48) /* Force NTRST Register [SAM9 only] */
|
||||
#define AT91_DBGU_FNTRST (1 << 0) /* Force NTRST */
|
||||
|
||||
#endif /* AT91_DBGU */
|
||||
|
||||
/*
|
||||
* Some AT91 parts that don't have full DEBUG units still support the ID
|
||||
* and extensions register.
|
||||
*/
|
||||
#define AT91_CIDR_VERSION (0x1f << 0) /* Version of the Device */
|
||||
#define AT91_CIDR_EPROC (7 << 5) /* Embedded Processor */
|
||||
#define AT91_CIDR_NVPSIZ (0xf << 8) /* Nonvolatile Program Memory Size */
|
||||
|
@ -53,7 +63,4 @@
|
|||
#define AT91_CIDR_NVPTYP (7 << 28) /* Nonvolatile Program Memory Type */
|
||||
#define AT91_CIDR_EXT (1 << 31) /* Extension Flag */
|
||||
|
||||
#define AT91_DBGU_FNR (AT91_DBGU + 0x48) /* Force NTRST Register [SAM9 only] */
|
||||
#define AT91_DBGU_FNTRST (1 << 0) /* Force NTRST */
|
||||
|
||||
#endif
|
||||
|
|
55
include/asm-arm/arch-at91/at91x40.h
Normal file
55
include/asm-arm/arch-at91/at91x40.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* include/asm-arm/arch-at91/at91x40.h
|
||||
*
|
||||
* (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef AT91X40_H
|
||||
#define AT91X40_H
|
||||
|
||||
/*
|
||||
* IRQ list.
|
||||
*/
|
||||
#define AT91_ID_FIQ 0 /* FIQ */
|
||||
#define AT91_ID_SYS 1 /* System Peripheral */
|
||||
#define AT91X40_ID_USART0 2 /* USART port 0 */
|
||||
#define AT91X40_ID_USART1 3 /* USART port 1 */
|
||||
#define AT91X40_ID_TC0 4 /* Timer/Counter 0 */
|
||||
#define AT91X40_ID_TC1 5 /* Timer/Counter 1*/
|
||||
#define AT91X40_ID_TC2 6 /* Timer/Counter 2*/
|
||||
#define AT91X40_ID_WD 7 /* Watchdog? */
|
||||
#define AT91X40_ID_PIOA 8 /* Parallel IO Controller A */
|
||||
|
||||
#define AT91X40_ID_IRQ0 16 /* External IRQ 0 */
|
||||
#define AT91X40_ID_IRQ1 17 /* External IRQ 1 */
|
||||
#define AT91X40_ID_IRQ2 18 /* External IRQ 2 */
|
||||
|
||||
/*
|
||||
* System Peripherals (offset from AT91_BASE_SYS)
|
||||
*/
|
||||
#define AT91_BASE_SYS 0xffc00000
|
||||
|
||||
#define AT91_EBI (0xffe00000 - AT91_BASE_SYS) /* External Bus Interface */
|
||||
#define AT91_SF (0xfff00000 - AT91_BASE_SYS) /* Special Function */
|
||||
#define AT91_USART1 (0xfffcc000 - AT91_BASE_SYS) /* USART 1 */
|
||||
#define AT91_USART0 (0xfffd0000 - AT91_BASE_SYS) /* USART 0 */
|
||||
#define AT91_TC (0xfffe0000 - AT91_BASE_SYS) /* Timer Counter */
|
||||
#define AT91_PIOA (0xffff0000 - AT91_BASE_SYS) /* PIO Controller A */
|
||||
#define AT91_PS (0xffff4000 - AT91_BASE_SYS) /* Power Save */
|
||||
#define AT91_WD (0xffff8000 - AT91_BASE_SYS) /* Watchdog Timer */
|
||||
#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */
|
||||
|
||||
/*
|
||||
* The AT91x40 series doesn't have a debug unit like the other AT91 parts.
|
||||
* But it does have a chip identify register and extension ID, so define at
|
||||
* least these here.
|
||||
*/
|
||||
#define AT91_DBGU_CIDR (AT91_SF + 0) /* CIDR in PS segment */
|
||||
#define AT91_DBGU_EXID (AT91_SF + 4) /* EXID in PS segment */
|
||||
|
||||
#endif /* AT91X40_H */
|
|
@ -28,6 +28,11 @@
|
|||
|
||||
#define ARCH_ID_AT91SAM9RL64 0x019b03a0
|
||||
|
||||
#define ARCH_ID_AT91M40800 0x14080044
|
||||
#define ARCH_ID_AT91R40807 0x44080746
|
||||
#define ARCH_ID_AT91M40807 0x14080745
|
||||
#define ARCH_ID_AT91R40008 0x44000840
|
||||
|
||||
static inline unsigned long at91_cpu_identify(void)
|
||||
{
|
||||
return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
|
||||
|
|
|
@ -26,18 +26,29 @@
|
|||
#include <asm/arch/at91sam9263.h>
|
||||
#elif defined(CONFIG_ARCH_AT91SAM9RL)
|
||||
#include <asm/arch/at91sam9rl.h>
|
||||
#elif defined(CONFIG_ARCH_AT91X40)
|
||||
#include <asm/arch/at91x40.h>
|
||||
#else
|
||||
#error "Unsupported AT91 processor"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
/*
|
||||
* Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF
|
||||
* to 0xFEF78000 .. 0xFF000000. (544Kb)
|
||||
*/
|
||||
#define AT91_IO_PHYS_BASE 0xFFF78000
|
||||
#define AT91_IO_SIZE (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
|
||||
#define AT91_IO_VIRT_BASE (0xFF000000 - AT91_IO_SIZE)
|
||||
#else
|
||||
/*
|
||||
* Identity mapping for the non MMU case.
|
||||
*/
|
||||
#define AT91_IO_PHYS_BASE AT91_BASE_SYS
|
||||
#define AT91_IO_VIRT_BASE AT91_IO_PHYS_BASE
|
||||
#endif
|
||||
|
||||
#define AT91_IO_SIZE (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
|
||||
|
||||
/* Convert a physical IO address to virtual IO address */
|
||||
#define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
|
||||
|
@ -66,7 +77,11 @@
|
|||
#define AT91_CHIPSELECT_7 0x80000000
|
||||
|
||||
/* SDRAM */
|
||||
#ifdef CONFIG_DRAM_BASE
|
||||
#define AT91_SDRAM_BASE CONFIG_DRAM_BASE
|
||||
#else
|
||||
#define AT91_SDRAM_BASE AT91_CHIPSELECT_1
|
||||
#endif
|
||||
|
||||
/* Clocks */
|
||||
#define AT91_SLOW_CLOCK 32768 /* slow clock */
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
#define AT91SAM9_MASTER_CLOCK 100000000
|
||||
#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
|
||||
|
||||
#elif defined(CONFIG_ARCH_AT91X40)
|
||||
|
||||
#define AT91X40_MASTER_CLOCK 40000000
|
||||
#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,20 +33,24 @@
|
|||
*/
|
||||
static void putc(int c)
|
||||
{
|
||||
#ifdef AT91_DBGU
|
||||
void __iomem *sys = (void __iomem *) AT91_BASE_SYS; /* physical address */
|
||||
|
||||
while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXRDY))
|
||||
barrier();
|
||||
__raw_writel(c, sys + AT91_DBGU_THR);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void flush(void)
|
||||
{
|
||||
#ifdef AT91_DBGU
|
||||
void __iomem *sys = (void __iomem *) AT91_BASE_SYS; /* physical address */
|
||||
|
||||
/* wait for transmission to complete */
|
||||
while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXEMPTY))
|
||||
barrier();
|
||||
#endif
|
||||
}
|
||||
|
||||
#define arch_decomp_setup()
|
||||
|
|
22
include/asm-arm/arch-davinci/clock.h
Normal file
22
include/asm-arm/arch-davinci/clock.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* include/asm-arm/arch-davinci/clock.h
|
||||
*
|
||||
* Clock control driver for DaVinci - header file
|
||||
*
|
||||
* Authors: Vladimir Barinov <source@mvista.com>
|
||||
*
|
||||
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_DAVINCI_CLOCK_H
|
||||
#define __ASM_ARCH_DAVINCI_CLOCK_H
|
||||
|
||||
struct clk;
|
||||
|
||||
extern int clk_register(struct clk *clk);
|
||||
extern void clk_unregister(struct clk *clk);
|
||||
extern int davinci_clk_init(void);
|
||||
|
||||
#endif
|
156
include/asm-arm/arch-davinci/gpio.h
Normal file
156
include/asm-arm/arch-davinci/gpio.h
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* TI DaVinci GPIO Support
|
||||
*
|
||||
* Copyright (c) 2006 David Brownell
|
||||
* Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __DAVINCI_GPIO_H
|
||||
#define __DAVINCI_GPIO_H
|
||||
|
||||
/*
|
||||
* basic gpio routines
|
||||
*
|
||||
* board-specific init should be done by arch/.../.../board-XXX.c (maybe
|
||||
* initializing banks together) rather than boot loaders; kexec() won't
|
||||
* go through boot loaders.
|
||||
*
|
||||
* the gpio clock will be turned on when gpios are used, and you may also
|
||||
* need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are
|
||||
* used as gpios, not with other peripherals.
|
||||
*
|
||||
* GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation, and maybe
|
||||
* for later updates, code should write GPIO(N) or:
|
||||
* - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53)
|
||||
* - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70)
|
||||
*
|
||||
* For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
|
||||
* for now, that's != GPIO(N)
|
||||
*/
|
||||
#define GPIO(X) (X) /* 0 <= X <= 70 */
|
||||
#define GPIOV18(X) (X) /* 1.8V i/o; 0 <= X <= 53 */
|
||||
#define GPIOV33(X) ((X)+54) /* 3.3V i/o; 0 <= X <= 17 */
|
||||
|
||||
struct gpio_controller {
|
||||
u32 dir;
|
||||
u32 out_data;
|
||||
u32 set_data;
|
||||
u32 clr_data;
|
||||
u32 in_data;
|
||||
u32 set_rising;
|
||||
u32 clr_rising;
|
||||
u32 set_falling;
|
||||
u32 clr_falling;
|
||||
u32 intstat;
|
||||
};
|
||||
|
||||
/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
|
||||
* with constant parameters; or in outlined code they execute at runtime.
|
||||
*
|
||||
* You'd access the controller directly when reading or writing more than
|
||||
* one gpio value at a time, and to support wired logic where the value
|
||||
* being driven by the cpu need not match the value read back.
|
||||
*
|
||||
* These are NOT part of the cross-platform GPIO interface
|
||||
*/
|
||||
static inline struct gpio_controller *__iomem
|
||||
__gpio_to_controller(unsigned gpio)
|
||||
{
|
||||
void *__iomem ptr;
|
||||
|
||||
if (gpio < 32)
|
||||
ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
|
||||
else if (gpio < 64)
|
||||
ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
|
||||
else if (gpio < DAVINCI_N_GPIO)
|
||||
ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
|
||||
else
|
||||
ptr = NULL;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline u32 __gpio_mask(unsigned gpio)
|
||||
{
|
||||
return 1 << (gpio % 32);
|
||||
}
|
||||
|
||||
/* The get/set/clear functions will inline when called with constant
|
||||
* parameters, for low-overhead bitbanging. Illegal constant parameters
|
||||
* cause link-time errors.
|
||||
*
|
||||
* Otherwise, calls with variable parameters use outlined functions.
|
||||
*/
|
||||
extern int __error_inval_gpio(void);
|
||||
|
||||
extern void __gpio_set(unsigned gpio, int value);
|
||||
extern int __gpio_get(unsigned gpio);
|
||||
|
||||
static inline void gpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
if (__builtin_constant_p(value)) {
|
||||
struct gpio_controller *__iomem g;
|
||||
u32 mask;
|
||||
|
||||
if (gpio >= DAVINCI_N_GPIO)
|
||||
__error_inval_gpio();
|
||||
|
||||
g = __gpio_to_controller(gpio);
|
||||
mask = __gpio_mask(gpio);
|
||||
if (value)
|
||||
__raw_writel(mask, &g->set_data);
|
||||
else
|
||||
__raw_writel(mask, &g->clr_data);
|
||||
return;
|
||||
}
|
||||
|
||||
__gpio_set(gpio, value);
|
||||
}
|
||||
|
||||
/* Returns zero or nonzero; works for gpios configured as inputs OR
|
||||
* as outputs.
|
||||
*
|
||||
* NOTE: changes in reported values are synchronized to the GPIO clock.
|
||||
* This is most easily seen after calling gpio_set_value() and then immediatly
|
||||
* gpio_get_value(), where the gpio_get_value() would return the old value
|
||||
* until the GPIO clock ticks and the new value gets latched.
|
||||
*/
|
||||
|
||||
static inline int gpio_get_value(unsigned gpio)
|
||||
{
|
||||
struct gpio_controller *__iomem g;
|
||||
|
||||
if (!__builtin_constant_p(gpio))
|
||||
return __gpio_get(gpio);
|
||||
|
||||
if (gpio >= DAVINCI_N_GPIO)
|
||||
return __error_inval_gpio();
|
||||
|
||||
g = __gpio_to_controller(gpio);
|
||||
return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
|
||||
}
|
||||
|
||||
/* powerup default direction is IN */
|
||||
extern int gpio_direction_input(unsigned gpio);
|
||||
extern int gpio_direction_output(unsigned gpio, int value);
|
||||
|
||||
#include <asm-generic/gpio.h> /* cansleep wrappers */
|
||||
|
||||
extern int gpio_request(unsigned gpio, const char *tag);
|
||||
extern void gpio_free(unsigned gpio);
|
||||
|
||||
static inline int gpio_to_irq(unsigned gpio)
|
||||
{
|
||||
return DAVINCI_N_AINTC_IRQ + gpio;
|
||||
}
|
||||
|
||||
static inline int irq_to_gpio(unsigned irq)
|
||||
{
|
||||
return irq - DAVINCI_N_AINTC_IRQ;
|
||||
}
|
||||
|
||||
#endif /* __DAVINCI_GPIO_H */
|
|
@ -11,4 +11,42 @@
|
|||
#ifndef __ASM_ARCH_HARDWARE_H
|
||||
#define __ASM_ARCH_HARDWARE_H
|
||||
|
||||
/*
|
||||
* Base register addresses
|
||||
*/
|
||||
#define DAVINCI_DMA_3PCC_BASE (0x01C00000)
|
||||
#define DAVINCI_DMA_3PTC0_BASE (0x01C10000)
|
||||
#define DAVINCI_DMA_3PTC1_BASE (0x01C10400)
|
||||
#define DAVINCI_I2C_BASE (0x01C21000)
|
||||
#define DAVINCI_PWM0_BASE (0x01C22000)
|
||||
#define DAVINCI_PWM1_BASE (0x01C22400)
|
||||
#define DAVINCI_PWM2_BASE (0x01C22800)
|
||||
#define DAVINCI_SYSTEM_MODULE_BASE (0x01C40000)
|
||||
#define DAVINCI_PLL_CNTRL0_BASE (0x01C40800)
|
||||
#define DAVINCI_PLL_CNTRL1_BASE (0x01C40C00)
|
||||
#define DAVINCI_PWR_SLEEP_CNTRL_BASE (0x01C41000)
|
||||
#define DAVINCI_SYSTEM_DFT_BASE (0x01C42000)
|
||||
#define DAVINCI_IEEE1394_BASE (0x01C60000)
|
||||
#define DAVINCI_USB_OTG_BASE (0x01C64000)
|
||||
#define DAVINCI_CFC_ATA_BASE (0x01C66000)
|
||||
#define DAVINCI_SPI_BASE (0x01C66800)
|
||||
#define DAVINCI_GPIO_BASE (0x01C67000)
|
||||
#define DAVINCI_UHPI_BASE (0x01C67800)
|
||||
#define DAVINCI_VPSS_REGS_BASE (0x01C70000)
|
||||
#define DAVINCI_EMAC_CNTRL_REGS_BASE (0x01C80000)
|
||||
#define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE (0x01C81000)
|
||||
#define DAVINCI_EMAC_WRAPPER_RAM_BASE (0x01C82000)
|
||||
#define DAVINCI_MDIO_CNTRL_REGS_BASE (0x01C84000)
|
||||
#define DAVINCI_IMCOP_BASE (0x01CC0000)
|
||||
#define DAVINCI_ASYNC_EMIF_CNTRL_BASE (0x01E00000)
|
||||
#define DAVINCI_VLYNQ_BASE (0x01E01000)
|
||||
#define DAVINCI_MCBSP_BASE (0x01E02000)
|
||||
#define DAVINCI_MMC_SD_BASE (0x01E10000)
|
||||
#define DAVINCI_MS_BASE (0x01E20000)
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE (0x02000000)
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE (0x04000000)
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE (0x06000000)
|
||||
#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE (0x08000000)
|
||||
#define DAVINCI_VLYNQ_REMOTE_BASE (0x0C000000)
|
||||
|
||||
#endif /* __ASM_ARCH_HARDWARE_H */
|
||||
|
|
55
include/asm-arm/arch-davinci/mux.h
Normal file
55
include/asm-arm/arch-davinci/mux.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* DaVinci pin multiplexing defines
|
||||
*
|
||||
* Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
|
||||
*
|
||||
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_MUX_H
|
||||
#define __ASM_ARCH_MUX_H
|
||||
|
||||
#define DAVINCI_MUX_AEAW0 0
|
||||
#define DAVINCI_MUX_AEAW1 1
|
||||
#define DAVINCI_MUX_AEAW2 2
|
||||
#define DAVINCI_MUX_AEAW3 3
|
||||
#define DAVINCI_MUX_AEAW4 4
|
||||
#define DAVINCI_MUX_AECS4 10
|
||||
#define DAVINCI_MUX_AECS5 11
|
||||
#define DAVINCI_MUX_VLYNQWD0 12
|
||||
#define DAVINCI_MUX_VLYNQWD1 13
|
||||
#define DAVINCI_MUX_VLSCREN 14
|
||||
#define DAVINCI_MUX_VLYNQEN 15
|
||||
#define DAVINCI_MUX_HDIREN 16
|
||||
#define DAVINCI_MUX_ATAEN 17
|
||||
#define DAVINCI_MUX_RGB666 22
|
||||
#define DAVINCI_MUX_RGB888 23
|
||||
#define DAVINCI_MUX_LOEEN 24
|
||||
#define DAVINCI_MUX_LFLDEN 25
|
||||
#define DAVINCI_MUX_CWEN 26
|
||||
#define DAVINCI_MUX_CFLDEN 27
|
||||
#define DAVINCI_MUX_HPIEN 29
|
||||
#define DAVINCI_MUX_1394EN 30
|
||||
#define DAVINCI_MUX_EMACEN 31
|
||||
|
||||
#define DAVINCI_MUX_LEVEL2 32
|
||||
#define DAVINCI_MUX_UART0 (DAVINCI_MUX_LEVEL2 + 0)
|
||||
#define DAVINCI_MUX_UART1 (DAVINCI_MUX_LEVEL2 + 1)
|
||||
#define DAVINCI_MUX_UART2 (DAVINCI_MUX_LEVEL2 + 2)
|
||||
#define DAVINCI_MUX_U2FLO (DAVINCI_MUX_LEVEL2 + 3)
|
||||
#define DAVINCI_MUX_PWM0 (DAVINCI_MUX_LEVEL2 + 4)
|
||||
#define DAVINCI_MUX_PWM1 (DAVINCI_MUX_LEVEL2 + 5)
|
||||
#define DAVINCI_MUX_PWM2 (DAVINCI_MUX_LEVEL2 + 6)
|
||||
#define DAVINCI_MUX_I2C (DAVINCI_MUX_LEVEL2 + 7)
|
||||
#define DAVINCI_MUX_SPI (DAVINCI_MUX_LEVEL2 + 8)
|
||||
#define DAVINCI_MUX_MSTK (DAVINCI_MUX_LEVEL2 + 9)
|
||||
#define DAVINCI_MUX_ASP (DAVINCI_MUX_LEVEL2 + 10)
|
||||
#define DAVINCI_MUX_CLK0 (DAVINCI_MUX_LEVEL2 + 16)
|
||||
#define DAVINCI_MUX_CLK1 (DAVINCI_MUX_LEVEL2 + 17)
|
||||
#define DAVINCI_MUX_TIMIN (DAVINCI_MUX_LEVEL2 + 18)
|
||||
|
||||
extern void davinci_mux_peripheral(unsigned int mux, unsigned int enable);
|
||||
|
||||
#endif /* __ASM_ARCH_MUX_H */
|
102
include/asm-arm/arch-imx/gpio.h
Normal file
102
include/asm-arm/arch-imx/gpio.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
#ifndef _IMX_GPIO_H
|
||||
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
#define IMX_GPIO_ALLOC_MODE_NORMAL 0
|
||||
#define IMX_GPIO_ALLOC_MODE_NO_ALLOC 1
|
||||
#define IMX_GPIO_ALLOC_MODE_TRY_ALLOC 2
|
||||
#define IMX_GPIO_ALLOC_MODE_ALLOC_ONLY 4
|
||||
#define IMX_GPIO_ALLOC_MODE_RELEASE 8
|
||||
|
||||
extern int imx_gpio_request(unsigned gpio, const char *label);
|
||||
|
||||
extern void imx_gpio_free(unsigned gpio);
|
||||
|
||||
extern int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
|
||||
int alloc_mode, const char *label);
|
||||
|
||||
extern int imx_gpio_direction_input(unsigned gpio);
|
||||
|
||||
extern int imx_gpio_direction_output(unsigned gpio, int value);
|
||||
|
||||
extern void __imx_gpio_set_value(unsigned gpio, int value);
|
||||
|
||||
static inline int imx_gpio_get_value(unsigned gpio)
|
||||
{
|
||||
return SSR(gpio >> GPIO_PORT_SHIFT) & (1 << (gpio & GPIO_PIN_MASK));
|
||||
}
|
||||
|
||||
static inline void imx_gpio_set_value_inline(unsigned gpio, int value)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
if(value)
|
||||
DR(gpio >> GPIO_PORT_SHIFT) |= (1 << (gpio & GPIO_PIN_MASK));
|
||||
else
|
||||
DR(gpio >> GPIO_PORT_SHIFT) &= ~(1 << (gpio & GPIO_PIN_MASK));
|
||||
raw_local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static inline void imx_gpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
if(__builtin_constant_p(gpio))
|
||||
imx_gpio_set_value_inline(gpio, value);
|
||||
else
|
||||
__imx_gpio_set_value(gpio, value);
|
||||
}
|
||||
|
||||
extern int imx_gpio_to_irq(unsigned gpio);
|
||||
|
||||
extern int imx_irq_to_gpio(unsigned irq);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* Wrappers for "new style" GPIO calls. These calls i.MX specific versions
|
||||
* to allow future extension of GPIO logic.
|
||||
*/
|
||||
|
||||
static inline int gpio_request(unsigned gpio, const char *label)
|
||||
{
|
||||
return imx_gpio_request(gpio, label);
|
||||
}
|
||||
|
||||
static inline void gpio_free(unsigned gpio)
|
||||
{
|
||||
imx_gpio_free(gpio);
|
||||
}
|
||||
|
||||
static inline int gpio_direction_input(unsigned gpio)
|
||||
{
|
||||
return imx_gpio_direction_input(gpio);
|
||||
}
|
||||
|
||||
static inline int gpio_direction_output(unsigned gpio, int value)
|
||||
{
|
||||
return imx_gpio_direction_output(gpio, value);
|
||||
}
|
||||
|
||||
static inline int gpio_get_value(unsigned gpio)
|
||||
{
|
||||
return imx_gpio_get_value(gpio);
|
||||
}
|
||||
|
||||
static inline void gpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
imx_gpio_set_value(gpio, value);
|
||||
}
|
||||
|
||||
#include <asm-generic/gpio.h> /* cansleep wrappers */
|
||||
|
||||
static inline int gpio_to_irq(unsigned gpio)
|
||||
{
|
||||
return imx_gpio_to_irq(gpio);
|
||||
}
|
||||
|
||||
static inline int irq_to_gpio(unsigned irq)
|
||||
{
|
||||
return imx_irq_to_gpio(irq);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -77,6 +77,8 @@
|
|||
#define SWR(x) __REG2(IMX_GPIO_BASE + 0x3c, ((x) & 3) << 8)
|
||||
#define PUEN(x) __REG2(IMX_GPIO_BASE + 0x40, ((x) & 3) << 8)
|
||||
|
||||
#define GPIO_PORT_MAX 3
|
||||
|
||||
#define GPIO_PIN_MASK 0x1f
|
||||
#define GPIO_PORT_MASK (0x3 << 5)
|
||||
|
||||
|
|
|
@ -32,4 +32,8 @@
|
|||
#define IXDP425_PCI_INTC_PIN 9
|
||||
#define IXDP425_PCI_INTD_PIN 8
|
||||
|
||||
/* NAND Flash pins */
|
||||
#define IXDP425_NAND_NCE_PIN 12
|
||||
|
||||
#define IXDP425_NAND_CMD_BYTE 0x01
|
||||
#define IXDP425_NAND_ADDR_BYTE 0x02
|
||||
|
|
|
@ -38,9 +38,10 @@ static void flush(void)
|
|||
static __inline__ void __arch_decomp_setup(unsigned long arch_id)
|
||||
{
|
||||
/*
|
||||
* Coyote and gtwx5715 only have UART2 connected
|
||||
* Some boards are using UART2 as console
|
||||
*/
|
||||
if (machine_is_adi_coyote() || machine_is_gtwx5715())
|
||||
if (machine_is_adi_coyote() || machine_is_gtwx5715() ||
|
||||
machine_is_gateway7001() || machine_is_wg302v2())
|
||||
uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS;
|
||||
else
|
||||
uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS;
|
||||
|
|
79
include/asm-arm/arch-ks8695/gpio.h
Normal file
79
include/asm-arm/arch-ks8695/gpio.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* include/asm-arm/arch-ks8695/gpio.h
|
||||
*
|
||||
* Copyright (C) 2006 Andrew Victor
|
||||
*
|
||||
* 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 __ASM_ARCH_GPIO_H_
|
||||
#define __ASM_ARCH_GPIO_H_
|
||||
|
||||
#define KS8695_GPIO_0 0
|
||||
#define KS8695_GPIO_1 1
|
||||
#define KS8695_GPIO_2 2
|
||||
#define KS8695_GPIO_3 3
|
||||
#define KS8695_GPIO_4 4
|
||||
#define KS8695_GPIO_5 5
|
||||
#define KS8695_GPIO_6 6
|
||||
#define KS8695_GPIO_7 7
|
||||
#define KS8695_GPIO_8 8
|
||||
#define KS8695_GPIO_9 9
|
||||
#define KS8695_GPIO_10 10
|
||||
#define KS8695_GPIO_11 11
|
||||
#define KS8695_GPIO_12 12
|
||||
#define KS8695_GPIO_13 13
|
||||
#define KS8695_GPIO_14 14
|
||||
#define KS8695_GPIO_15 15
|
||||
|
||||
|
||||
/*
|
||||
* Configure GPIO pin as external interrupt source.
|
||||
*/
|
||||
int __init_or_module ks8695_gpio_interrupt(unsigned int pin, unsigned int type);
|
||||
|
||||
/*
|
||||
* Configure the GPIO line as an input.
|
||||
*/
|
||||
int __init_or_module gpio_direction_input(unsigned int pin);
|
||||
|
||||
/*
|
||||
* Configure the GPIO line as an output, with default state.
|
||||
*/
|
||||
int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state);
|
||||
|
||||
/*
|
||||
* Set the state of an output GPIO line.
|
||||
*/
|
||||
void gpio_set_value(unsigned int pin, unsigned int state);
|
||||
|
||||
/*
|
||||
* Read the state of a GPIO line.
|
||||
*/
|
||||
int gpio_get_value(unsigned int pin);
|
||||
|
||||
/*
|
||||
* Map GPIO line to IRQ number.
|
||||
*/
|
||||
int gpio_to_irq(unsigned int pin);
|
||||
|
||||
/*
|
||||
* Map IRQ number to GPIO line.
|
||||
*/
|
||||
int irq_to_gpio(unsigned int irq);
|
||||
|
||||
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
static inline int gpio_request(unsigned int pin, const char *label)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void gpio_free(unsigned int pin)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -30,30 +30,12 @@ typedef enum {
|
|||
DMA_PRIO_LOW = 2
|
||||
} pxa_dma_prio;
|
||||
|
||||
#if defined(CONFIG_PXA27x)
|
||||
|
||||
#define PXA_DMA_CHANNELS 32
|
||||
|
||||
#define pxa_for_each_dma_prio(ch, prio) \
|
||||
for ( \
|
||||
ch = prio * 4; \
|
||||
ch != (4 << prio) + 16; \
|
||||
ch = (ch + 1 == (4 << prio)) ? (prio * 4 + 16) : (ch + 1) \
|
||||
)
|
||||
|
||||
#elif defined(CONFIG_PXA25x)
|
||||
|
||||
#define PXA_DMA_CHANNELS 16
|
||||
|
||||
#define pxa_for_each_dma_prio(ch, prio) \
|
||||
for (ch = prio * 4; ch != (4 << prio); ch++)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DMA registration
|
||||
*/
|
||||
|
||||
int __init pxa_init_dma(int num_ch);
|
||||
|
||||
int pxa_request_dma (char *name,
|
||||
pxa_dma_prio prio,
|
||||
void (*irq_handler)(int, void *),
|
||||
|
|
|
@ -20,20 +20,38 @@
|
|||
.endm
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
|
||||
#ifdef CONFIG_PXA27x
|
||||
mrc p6, 0, \irqstat, c0, c0, 0 @ ICIP
|
||||
mrc p6, 0, \irqnr, c1, c0, 0 @ ICMR
|
||||
#else
|
||||
mrc p15, 0, \tmp, c0, c0, 0 @ CPUID
|
||||
mov \tmp, \tmp, lsr #13
|
||||
and \tmp, \tmp, #0x7 @ Core G
|
||||
cmp \tmp, #1
|
||||
bhi 1004f
|
||||
|
||||
mov \base, #io_p2v(0x40000000) @ IIR Ctl = 0x40d00000
|
||||
add \base, \base, #0x00d00000
|
||||
ldr \irqstat, [\base, #0] @ ICIP
|
||||
ldr \irqnr, [\base, #4] @ ICMR
|
||||
#endif
|
||||
b 1002f
|
||||
|
||||
1004:
|
||||
mrc p6, 0, \irqstat, c6, c0, 0 @ ICIP2
|
||||
mrc p6, 0, \irqnr, c7, c0, 0 @ ICMR2
|
||||
ands \irqstat, \irqstat, \irqnr
|
||||
beq 1003f
|
||||
rsb \irqstat, \irqnr, #0
|
||||
and \irqstat, \irqstat, \irqnr
|
||||
clz \irqnr, \irqstat
|
||||
rsb \irqnr, \irqnr, #31
|
||||
add \irqnr, \irqnr, #32
|
||||
b 1001f
|
||||
1003:
|
||||
mrc p6, 0, \irqstat, c0, c0, 0 @ ICIP
|
||||
mrc p6, 0, \irqnr, c1, c0, 0 @ ICMR
|
||||
1002:
|
||||
ands \irqnr, \irqstat, \irqnr
|
||||
beq 1001f
|
||||
rsb \irqstat, \irqnr, #0
|
||||
and \irqstat, \irqstat, \irqnr
|
||||
clz \irqnr, \irqstat
|
||||
rsb \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
|
||||
rsb \irqnr, \irqnr, #31
|
||||
1001:
|
||||
.endm
|
||||
|
|
|
@ -62,6 +62,42 @@
|
|||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define __cpu_is_pxa21x(id) \
|
||||
({ \
|
||||
unsigned int _id = (id) >> 4 & 0xf3f; \
|
||||
_id == 0x212; \
|
||||
})
|
||||
|
||||
#define __cpu_is_pxa25x(id) \
|
||||
({ \
|
||||
unsigned int _id = (id) >> 4 & 0xfff; \
|
||||
_id == 0x2d0 || _id == 0x290; \
|
||||
})
|
||||
|
||||
#define __cpu_is_pxa27x(id) \
|
||||
({ \
|
||||
unsigned int _id = (id) >> 4 & 0xfff; \
|
||||
_id == 0x411; \
|
||||
})
|
||||
|
||||
#define cpu_is_pxa21x() \
|
||||
({ \
|
||||
unsigned int id = read_cpuid(CPUID_ID); \
|
||||
__cpu_is_pxa21x(id); \
|
||||
})
|
||||
|
||||
#define cpu_is_pxa25x() \
|
||||
({ \
|
||||
unsigned int id = read_cpuid(CPUID_ID); \
|
||||
__cpu_is_pxa25x(id); \
|
||||
})
|
||||
|
||||
#define cpu_is_pxa27x() \
|
||||
({ \
|
||||
unsigned int id = read_cpuid(CPUID_ID); \
|
||||
__cpu_is_pxa27x(id); \
|
||||
})
|
||||
|
||||
/*
|
||||
* Handy routine to set GPIO alternate functions
|
||||
*/
|
||||
|
|
|
@ -11,14 +11,9 @@
|
|||
*/
|
||||
|
||||
|
||||
#define PXA_IRQ(x) (x)
|
||||
|
||||
#ifdef CONFIG_PXA27x
|
||||
#define PXA_IRQ_SKIP 0
|
||||
#else
|
||||
#define PXA_IRQ_SKIP 7
|
||||
#endif
|
||||
|
||||
#define PXA_IRQ(x) ((x) - PXA_IRQ_SKIP)
|
||||
|
||||
#define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */
|
||||
#define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */
|
||||
#define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI) */
|
||||
|
@ -26,6 +21,8 @@
|
|||
#define IRQ_KEYPAD PXA_IRQ(4) /* Key pad controller */
|
||||
#define IRQ_MEMSTK PXA_IRQ(5) /* Memory Stick interrupt */
|
||||
#define IRQ_PWRI2C PXA_IRQ(6) /* Power I2C interrupt */
|
||||
#endif
|
||||
|
||||
#define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error (PXA26x) */
|
||||
#define IRQ_OST_4_11 PXA_IRQ(7) /* OS timer 4-11 matches (PXA27x) */
|
||||
#define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */
|
||||
|
@ -58,18 +55,15 @@
|
|||
#ifdef CONFIG_PXA27x
|
||||
#define IRQ_TPM PXA_IRQ(32) /* TPM interrupt */
|
||||
#define IRQ_CAMERA PXA_IRQ(33) /* Camera Interface */
|
||||
|
||||
#define PXA_INTERNAL_IRQS 34
|
||||
#else
|
||||
#define PXA_INTERNAL_IRQS 32
|
||||
#endif
|
||||
|
||||
#define GPIO_2_x_TO_IRQ(x) \
|
||||
PXA_IRQ((x) - 2 + PXA_INTERNAL_IRQS)
|
||||
#define PXA_GPIO_IRQ_BASE (64)
|
||||
#define PXA_GPIO_IRQ_NUM (128)
|
||||
|
||||
#define GPIO_2_x_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x))
|
||||
#define IRQ_GPIO(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x))
|
||||
|
||||
#define IRQ_TO_GPIO_2_x(i) \
|
||||
((i) - IRQ_GPIO(2) + 2)
|
||||
#define IRQ_TO_GPIO_2_x(i) ((i) - PXA_GPIO_IRQ_BASE)
|
||||
#define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
|
||||
|
||||
#if defined(CONFIG_PXA25x)
|
||||
|
@ -84,7 +78,7 @@
|
|||
* these. If you need more, increase IRQ_BOARD_END, but keep it
|
||||
* within sensible limits.
|
||||
*/
|
||||
#define IRQ_BOARD_START (IRQ_GPIO(PXA_LAST_GPIO) + 1)
|
||||
#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM)
|
||||
#define IRQ_BOARD_END (IRQ_BOARD_START + 16)
|
||||
|
||||
#define IRQ_SA1111_START (IRQ_BOARD_END)
|
||||
|
|
|
@ -9,4 +9,3 @@
|
|||
|
||||
extern int pxa_pm_prepare(suspend_state_t state);
|
||||
extern int pxa_pm_enter(suspend_state_t state);
|
||||
extern int pxa_pm_finish(suspend_state_t state);
|
||||
|
|
|
@ -1765,29 +1765,9 @@
|
|||
#define SSACD_P(x) (*(((x) == 1) ? &SSACD_P1 : ((x) == 2) ? &SSACD_P2 : ((x) == 3) ? &SSACD_P3 : NULL))
|
||||
|
||||
/*
|
||||
* MultiMediaCard (MMC) controller
|
||||
* MultiMediaCard (MMC) controller - see drivers/mmc/host/pxamci.h
|
||||
*/
|
||||
|
||||
#define MMC_STRPCL __REG(0x41100000) /* Control to start and stop MMC clock */
|
||||
#define MMC_STAT __REG(0x41100004) /* MMC Status Register (read only) */
|
||||
#define MMC_CLKRT __REG(0x41100008) /* MMC clock rate */
|
||||
#define MMC_SPI __REG(0x4110000c) /* SPI mode control bits */
|
||||
#define MMC_CMDAT __REG(0x41100010) /* Command/response/data sequence control */
|
||||
#define MMC_RESTO __REG(0x41100014) /* Expected response time out */
|
||||
#define MMC_RDTO __REG(0x41100018) /* Expected data read time out */
|
||||
#define MMC_BLKLEN __REG(0x4110001c) /* Block length of data transaction */
|
||||
#define MMC_NOB __REG(0x41100020) /* Number of blocks, for block mode */
|
||||
#define MMC_PRTBUF __REG(0x41100024) /* Partial MMC_TXFIFO FIFO written */
|
||||
#define MMC_I_MASK __REG(0x41100028) /* Interrupt Mask */
|
||||
#define MMC_I_REG __REG(0x4110002c) /* Interrupt Register (read only) */
|
||||
#define MMC_CMD __REG(0x41100030) /* Index of current command */
|
||||
#define MMC_ARGH __REG(0x41100034) /* MSW part of the current command argument */
|
||||
#define MMC_ARGL __REG(0x41100038) /* LSW part of the current command argument */
|
||||
#define MMC_RES __REG(0x4110003c) /* Response FIFO (read only) */
|
||||
#define MMC_RXFIFO __REG(0x41100040) /* Receive FIFO (read only) */
|
||||
#define MMC_TXFIFO __REG(0x41100044) /* Transmit FIFO (write only) */
|
||||
|
||||
|
||||
/*
|
||||
* Core Clock
|
||||
*/
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/user.h>
|
||||
#include <asm/hwcap.h>
|
||||
|
||||
typedef unsigned long elf_greg_t;
|
||||
typedef unsigned long elf_freg_t[3];
|
||||
|
@ -39,30 +40,8 @@ typedef struct user_fp elf_fpregset_t;
|
|||
#endif
|
||||
#define ELF_ARCH EM_ARM
|
||||
|
||||
/*
|
||||
* HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
|
||||
*/
|
||||
#define HWCAP_SWP 1
|
||||
#define HWCAP_HALF 2
|
||||
#define HWCAP_THUMB 4
|
||||
#define HWCAP_26BIT 8 /* Play it safe */
|
||||
#define HWCAP_FAST_MULT 16
|
||||
#define HWCAP_FPA 32
|
||||
#define HWCAP_VFP 64
|
||||
#define HWCAP_EDSP 128
|
||||
#define HWCAP_JAVA 256
|
||||
#define HWCAP_IWMMXT 512
|
||||
#define HWCAP_CRUNCH 1024
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifndef __ASSEMBLY__
|
||||
/*
|
||||
* This yields a mask that user programs can use to figure out what
|
||||
* instruction set this cpu supports.
|
||||
*/
|
||||
#define ELF_HWCAP (elf_hwcap)
|
||||
extern unsigned int elf_hwcap;
|
||||
|
||||
/*
|
||||
* This yields a string that ld.so will use to load implementation
|
||||
* specific libraries for optimization. This is more specific in
|
||||
|
|
28
include/asm-arm/hwcap.h
Normal file
28
include/asm-arm/hwcap.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef __ASMARM_HWCAP_H
|
||||
#define __ASMARM_HWCAP_H
|
||||
|
||||
/*
|
||||
* HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
|
||||
*/
|
||||
#define HWCAP_SWP 1
|
||||
#define HWCAP_HALF 2
|
||||
#define HWCAP_THUMB 4
|
||||
#define HWCAP_26BIT 8 /* Play it safe */
|
||||
#define HWCAP_FAST_MULT 16
|
||||
#define HWCAP_FPA 32
|
||||
#define HWCAP_VFP 64
|
||||
#define HWCAP_EDSP 128
|
||||
#define HWCAP_JAVA 256
|
||||
#define HWCAP_IWMMXT 512
|
||||
#define HWCAP_CRUNCH 1024
|
||||
|
||||
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
||||
/*
|
||||
* This yields a mask that user programs can use to figure out what
|
||||
* instruction set this cpu supports.
|
||||
*/
|
||||
#define ELF_HWCAP (elf_hwcap)
|
||||
extern unsigned int elf_hwcap;
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -10,6 +10,8 @@
|
|||
#ifndef __ASM_ARM_PTRACE_H
|
||||
#define __ASM_ARM_PTRACE_H
|
||||
|
||||
#include <asm/hwcap.h>
|
||||
|
||||
#define PTRACE_GETREGS 12
|
||||
#define PTRACE_SETREGS 13
|
||||
#define PTRACE_GETFPREGS 14
|
||||
|
@ -45,6 +47,7 @@
|
|||
#define PSR_T_BIT 0x00000020
|
||||
#define PSR_F_BIT 0x00000040
|
||||
#define PSR_I_BIT 0x00000080
|
||||
#define PSR_A_BIT 0x00000100
|
||||
#define PSR_J_BIT 0x01000000
|
||||
#define PSR_Q_BIT 0x08000000
|
||||
#define PSR_V_BIT 0x10000000
|
||||
|
@ -103,6 +106,10 @@ struct pt_regs {
|
|||
#define thumb_mode(regs) (0)
|
||||
#endif
|
||||
|
||||
#define isa_mode(regs) \
|
||||
((((regs)->ARM_cpsr & PSR_J_BIT) >> 23) | \
|
||||
(((regs)->ARM_cpsr & PSR_T_BIT) >> 5))
|
||||
|
||||
#define processor_mode(regs) \
|
||||
((regs)->ARM_cpsr & MODE_MASK)
|
||||
|
||||
|
@ -117,14 +124,17 @@ struct pt_regs {
|
|||
*/
|
||||
static inline int valid_user_regs(struct pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs) &&
|
||||
(regs->ARM_cpsr & (PSR_F_BIT|PSR_I_BIT)) == 0)
|
||||
if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) {
|
||||
regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force CPSR to something logical...
|
||||
*/
|
||||
regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
|
||||
regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT;
|
||||
if (!(elf_hwcap & HWCAP_26BIT))
|
||||
regs->ARM_cpsr |= USR_MODE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue