From 7e36e2f5355ab87f8946041d044b34cda01e2077 Mon Sep 17 00:00:00 2001 From: Rod Whitby Date: Tue, 1 Apr 2008 10:53:23 +0100 Subject: [ARM] 4874/2: ixp4xx: Add support for the Freecom FSG-3 board The Freecom-FSG3 is a small network-attached-storage device with the following feature set: * Intel IXP422 * 4MB Flash (ixp4xx flash driver) * 64MB RAM * 4 USB 2.0 host ports (ehci and ohci drivers) * 1 WAN (eth1) and 3 LAN (eth0) ethernet ports * Supported by the open source ixp4xx ethernet driver * Via VT6421 disk controller (libata and sata-via drivers) * Internal hard disk (PATA supported, SATA not yet supported) * External SATA port (not yet supported) * ISL1208 RTC chip * Winbond 83782 temp sensor and fan controller * MiniPCI slot The ixp4xx_defconfig is also updated to support this device (the leds-fsg driver is to be submitted separately via the leds tree after this initial support is merged, as it depends on header gpio defines). Signed-off-by: Rod Whitby Signed-off-by: Russell King --- include/asm-arm/arch-ixp4xx/fsg.h | 50 ++++++++++++++++++++++++++++++++++ include/asm-arm/arch-ixp4xx/hardware.h | 1 + include/asm-arm/arch-ixp4xx/irqs.h | 7 +++++ 3 files changed, 58 insertions(+) create mode 100644 include/asm-arm/arch-ixp4xx/fsg.h (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-ixp4xx/fsg.h b/include/asm-arm/arch-ixp4xx/fsg.h new file mode 100644 index 00000000000..c0100cc7981 --- /dev/null +++ b/include/asm-arm/arch-ixp4xx/fsg.h @@ -0,0 +1,50 @@ +/* + * include/asm-arm/arch-ixp4xx/fsg.h + * + * Freecom FSG-3 platform specific definitions + * + * Author: Rod Whitby + * Author: Tomasz Chmielewski + * Maintainers: http://www.nslu2-linux.org + * + * Based on coyote.h by + * Copyright 2004 (c) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ASM_ARCH_HARDWARE_H__ +#error "Do not include this directly, instead #include " +#endif + +#define FSG_SDA_PIN 12 +#define FSG_SCL_PIN 13 + +/* + * FSG PCI IRQs + */ +#define FSG_PCI_MAX_DEV 3 +#define FSG_PCI_IRQ_LINES 3 + + +/* PCI controller GPIO to IRQ pin mappings */ +#define FSG_PCI_INTA_PIN 6 +#define FSG_PCI_INTB_PIN 7 +#define FSG_PCI_INTC_PIN 5 + +/* Buttons */ + +#define FSG_SB_GPIO 4 /* sync button */ +#define FSG_RB_GPIO 9 /* reset button */ +#define FSG_UB_GPIO 10 /* usb button */ + +/* LEDs */ + +#define FSG_LED_WLAN_BIT 0 +#define FSG_LED_WAN_BIT 1 +#define FSG_LED_SATA_BIT 2 +#define FSG_LED_USB_BIT 4 +#define FSG_LED_RING_BIT 5 +#define FSG_LED_SYNC_BIT 7 diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h index 73e8dc36f6a..fa723a62785 100644 --- a/include/asm-arm/arch-ixp4xx/hardware.h +++ b/include/asm-arm/arch-ixp4xx/hardware.h @@ -45,5 +45,6 @@ #include "nslu2.h" #include "nas100d.h" #include "dsmg600.h" +#include "fsg.h" #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h index 11801605047..674af4a8414 100644 --- a/include/asm-arm/arch-ixp4xx/irqs.h +++ b/include/asm-arm/arch-ixp4xx/irqs.h @@ -128,4 +128,11 @@ #define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7 #define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6 +/* + * Freecom FSG-3 Board IRQs + */ +#define IRQ_FSG_PCI_INTA IRQ_IXP4XX_GPIO6 +#define IRQ_FSG_PCI_INTB IRQ_IXP4XX_GPIO7 +#define IRQ_FSG_PCI_INTC IRQ_IXP4XX_GPIO5 + #endif -- cgit v1.2.3-70-g09d2 From e055d5bff318845f99c0fbf93245767fab8dce88 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Apr 2008 01:43:27 +0100 Subject: [ARM] 5015/1: arm: remove ARCH_CO285 Trying to compile a kerel for ARCH_CO285 fails with the following error: <-- snip --> ... CC arch/arm/mach-footbridge/dc21285.o /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c: In function 'dc21285_base_address': /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:54: error: 'PCICFG0_BASE' undeclared (first use in this function) /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:54: error: (Each undeclared identifier is reported only once /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:54: error: for each function it appears in.) /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:57: error: 'PCICFG1_BASE' undeclared (first use in this function) /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c: In function 'dc21285_scan_bus': /home/bunk/linux/kernel-2.6/git/linux-2.6/arch/arm/mach-footbridge/dc21285.c:286: error: implicit declaration of function 'pci_scan_bus' ... make[2]: *** [arch/arm/mach-footbridge/dc21285.o] Error 1 <-- snip --> This does not seem to be a recent breakage. The ARCH_CO285 support is old - kernel 2.2.0 contains first traces of it, an it seems to have been pretty complete in later 2.2 kernels. Since it seems to be completely dead code now this patch therefore removes it. Signed-off-by: Adrian Bunk Signed-off-by: Russell King --- arch/arm/Kconfig | 10 +-------- arch/arm/Makefile | 2 -- arch/arm/mach-footbridge/Makefile | 2 -- arch/arm/mach-footbridge/co285.c | 39 --------------------------------- arch/arm/mach-footbridge/common.c | 21 ------------------ arch/arm/mach-footbridge/ebsa285-leds.c | 2 +- arch/arm/mach-footbridge/time.c | 3 +-- include/asm-arm/arch-ebsa285/hardware.h | 26 ---------------------- include/asm-arm/arch-ebsa285/memory.h | 19 ---------------- include/asm-arm/arch-ebsa285/vmalloc.h | 4 ---- 10 files changed, 3 insertions(+), 125 deletions(-) delete mode 100644 arch/arm/mach-footbridge/co285.c (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4039a133006..ab78d5c421f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -232,14 +232,6 @@ config ARCH_CLPS711X help Support for Cirrus Logic 711x/721x based boards. -config ARCH_CO285 - bool "Co-EBSA285" - select FOOTBRIDGE - select FOOTBRIDGE_ADDIN - select HAVE_IDE - help - Support for Intel's EBSA285 companion chip. - config ARCH_EBSA110 bool "EBSA-110" select ISA @@ -784,7 +776,7 @@ source "mm/Kconfig" config LEDS bool "Timer and CPU usage LEDs" - depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \ + depends on ARCH_CDB89712 || ARCH_EBSA110 || \ ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \ ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \ ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1a4649667ec..79b8ca3400e 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -100,8 +100,6 @@ textofs-y := 0x00008000 incdir-$(CONFIG_ARCH_CLPS7500) := cl7500 machine-$(CONFIG_FOOTBRIDGE) := footbridge incdir-$(CONFIG_FOOTBRIDGE) := ebsa285 - machine-$(CONFIG_ARCH_CO285) := footbridge - incdir-$(CONFIG_ARCH_CO285) := ebsa285 machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_SA1100) := sa1100 ifeq ($(CONFIG_ARCH_SA1100),y) diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile index 0694ad6b647..32f8609e4f8 100644 --- a/arch/arm/mach-footbridge/Makefile +++ b/arch/arm/mach-footbridge/Makefile @@ -14,12 +14,10 @@ pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o -leds-$(CONFIG_ARCH_CO285) += ebsa285-leds.o leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o -obj-$(CONFIG_ARCH_CO285) += co285.o dc21285-timer.o obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c deleted file mode 100644 index 4545576ad8d..00000000000 --- a/arch/arm/mach-footbridge/co285.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * linux/arch/arm/mach-footbridge/co285.c - * - * CO285 machine fixup - */ -#include - -#include -#include - -#include - -#include "common.h" - -static void __init -fixup_coebsa285(struct machine_desc *desc, struct tag *tags, - char **cmdline, struct meminfo *mi) -{ - extern unsigned long boot_memory_end; - extern char boot_command_line[]; - - mi->nr_banks = 1; - mi->bank[0].start = PHYS_OFFSET; - mi->bank[0].size = boot_memory_end; - mi->bank[0].node = 0; - - *cmdline = boot_command_line; -} - -MACHINE_START(CO285, "co-EBSA285") - /* Maintainer: Mark van Doesburg */ - .phys_io = DC21285_ARMCSR_BASE, - .io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc, - .fixup = fixup_coebsa285, - .map_io = footbridge_map_io, - .init_irq = footbridge_init_irq, - .timer = &footbridge_timer, -MACHINE_END - diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index ef29fc34ce6..b08ab507c05 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c @@ -177,25 +177,6 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = { #endif }; -/* - * The CO-ebsa285 mapping. - */ -static struct map_desc co285_io_desc[] __initdata = { -#ifdef CONFIG_ARCH_CO285 - { - .virtual = PCIO_BASE, - .pfn = __phys_to_pfn(DC21285_PCI_IO), - .length = PCIO_SIZE, - .type = MT_DEVICE, - }, { - .virtual = PCIMEM_BASE, - .pfn = __phys_to_pfn(DC21285_PCI_MEM), - .length = PCIMEM_SIZE, - .type = MT_DEVICE, - }, -#endif -}; - void __init footbridge_map_io(void) { /* @@ -208,8 +189,6 @@ void __init footbridge_map_io(void) * Now, work out what we've got to map in addition on this * platform. */ - if (machine_is_co285()) - iotable_init(co285_io_desc, ARRAY_SIZE(co285_io_desc)); if (footbridge_cfn_mode()) iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc)); } diff --git a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c index a64e2222651..09c1fbc5187 100644 --- a/arch/arm/mach-footbridge/ebsa285-leds.c +++ b/arch/arm/mach-footbridge/ebsa285-leds.c @@ -128,7 +128,7 @@ static void ebsa285_leds_event(led_event_t evt) static int __init leds_init(void) { - if (machine_is_ebsa285() || machine_is_co285()) + if (machine_is_ebsa285()) leds_event = ebsa285_leds_event; leds_event(led_start); diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c index 5d02e95dede..d5cfcda385d 100644 --- a/arch/arm/mach-footbridge/time.c +++ b/arch/arm/mach-footbridge/time.c @@ -115,8 +115,7 @@ static int set_isa_cmos_time(void) void __init isa_rtc_init(void) { - if (machine_is_co285() || - machine_is_personal_server()) + if (machine_is_personal_server()) /* * Add-in 21285s shouldn't access the RTC */ diff --git a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h index daad8ee2d19..74610c2c63d 100644 --- a/include/asm-arm/arch-ebsa285/hardware.h +++ b/include/asm-arm/arch-ebsa285/hardware.h @@ -14,7 +14,6 @@ #include -#ifdef CONFIG_ARCH_FOOTBRIDGE /* Virtual Physical Size * 0xff800000 0x40000000 1MB X-Bus * 0xff000000 0x7c000000 1MB PCI I/O space @@ -50,31 +49,6 @@ #define PCIMEM_SIZE 0x01000000 #define PCIMEM_BASE 0xf0000000 -#elif defined(CONFIG_ARCH_CO285) -/* - * This is the COEBSA285 cut-down mapping - */ -#define PCIMEM_SIZE 0x80000000 -#define PCIMEM_BASE 0x80000000 - -#define WFLUSH_SIZE 0x01000000 -#define WFLUSH_BASE 0x7d000000 - -#define ARMCSR_SIZE 0x00100000 -#define ARMCSR_BASE 0x7cf00000 - -#define XBUS_SIZE 0x00020000 -#define XBUS_BASE 0x7cee0000 - -#define PCIO_SIZE 0x00010000 -#define PCIO_BASE 0x7ced0000 - -#else - -#error "Undefined footbridge architecture" - -#endif - #define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000)) #define XBUS_LED_AMBER (1 << 0) #define XBUS_LED_GREEN (1 << 1) diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h index cbd7ae64bcc..9019a3bf5ab 100644 --- a/include/asm-arm/arch-ebsa285/memory.h +++ b/include/asm-arm/arch-ebsa285/memory.h @@ -42,8 +42,6 @@ extern unsigned long __bus_to_virt(unsigned long); #endif -#if defined(CONFIG_ARCH_FOOTBRIDGE) - /* Task size and page offset at 3GB */ #define TASK_SIZE UL(0xbf000000) #define PAGE_OFFSET UL(0xc0000000) @@ -53,23 +51,6 @@ extern unsigned long __bus_to_virt(unsigned long); */ #define FLUSH_BASE 0xf9000000 -#elif defined(CONFIG_ARCH_CO285) - -/* Task size and page offset at 1.5GB */ -#define TASK_SIZE UL(0x5f000000) -#define PAGE_OFFSET UL(0x60000000) - -/* - * Cache flushing area. - */ -#define FLUSH_BASE 0x7e000000 - -#else - -#error "Undefined footbridge architecture" - -#endif - /* * Physical DRAM offset. */ diff --git a/include/asm-arm/arch-ebsa285/vmalloc.h b/include/asm-arm/arch-ebsa285/vmalloc.h index 02598200997..e487d7e8c8a 100644 --- a/include/asm-arm/arch-ebsa285/vmalloc.h +++ b/include/asm-arm/arch-ebsa285/vmalloc.h @@ -7,8 +7,4 @@ */ -#ifdef CONFIG_ARCH_FOOTBRIDGE #define VMALLOC_END (PAGE_OFFSET + 0x30000000) -#else -#define VMALLOC_END (PAGE_OFFSET + 0x20000000) -#endif -- cgit v1.2.3-70-g09d2 From 205bee6ad804d7034773b5978c74dde495df2301 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 13:57:26 +0100 Subject: [ARM] dyntick: Remove obsolete and unused ARM dyntick support dyntick is superseded by the clocksource/clockevent infrastructure, using the NO_HZ configuration option. No one implements dyntick on ARM anymore, so it's pointless keeping it around. Remove dyntick support. Signed-off-by: Russell King --- arch/arm/Kconfig | 21 ------ arch/arm/configs/at91cap9adk_defconfig | 1 - arch/arm/configs/at91rm9200dk_defconfig | 1 - arch/arm/configs/at91rm9200ek_defconfig | 1 - arch/arm/configs/at91sam9260ek_defconfig | 1 - arch/arm/configs/at91sam9261ek_defconfig | 1 - arch/arm/configs/at91sam9263ek_defconfig | 1 - arch/arm/configs/at91sam9rlek_defconfig | 1 - arch/arm/configs/ateb9200_defconfig | 1 - arch/arm/configs/cm_x270_defconfig | 1 - arch/arm/configs/collie_defconfig | 1 - arch/arm/configs/corgi_defconfig | 1 - arch/arm/configs/ecbat91_defconfig | 1 - arch/arm/configs/em_x270_defconfig | 1 - arch/arm/configs/ep93xx_defconfig | 1 - arch/arm/configs/eseries_pxa_defconfig | 1 - arch/arm/configs/iop13xx_defconfig | 1 - arch/arm/configs/iop32x_defconfig | 1 - arch/arm/configs/iop33x_defconfig | 1 - arch/arm/configs/ixp2000_defconfig | 1 - arch/arm/configs/ixp23xx_defconfig | 1 - arch/arm/configs/kafa_defconfig | 1 - arch/arm/configs/kb9202_defconfig | 1 - arch/arm/configs/ks8695_defconfig | 1 - arch/arm/configs/lpd270_defconfig | 1 - arch/arm/configs/lpd7a404_defconfig | 1 - arch/arm/configs/netx_defconfig | 1 - arch/arm/configs/onearm_defconfig | 1 - arch/arm/configs/picotux200_defconfig | 1 - arch/arm/configs/pnx4008_defconfig | 1 - arch/arm/configs/realview-smp_defconfig | 1 - arch/arm/configs/realview_defconfig | 1 - arch/arm/configs/rpc_defconfig | 1 - arch/arm/configs/s3c2410_defconfig | 1 - arch/arm/configs/sam9_l9260_defconfig | 1 - arch/arm/configs/spitz_defconfig | 1 - arch/arm/configs/tct_hammer_defconfig | 1 - arch/arm/configs/trizeps4_defconfig | 1 - arch/arm/configs/versatile_defconfig | 1 - arch/arm/kernel/process.c | 4 +- arch/arm/kernel/time.c | 120 ------------------------------- arch/arm/mach-omap1/pm.c | 7 -- arch/arm/mach-omap2/pm.c | 7 -- include/asm-arm/dyntick.h | 6 -- include/asm-arm/hw_irq.h | 11 --- include/asm-arm/mach/time.h | 22 ------ 46 files changed, 1 insertion(+), 235 deletions(-) delete mode 100644 include/asm-arm/dyntick.h (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..167824e24ed 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -703,27 +703,6 @@ config PREEMPT Say Y here if you are building a kernel for a desktop, embedded or real-time system. Say N if you are unsure. -config NO_IDLE_HZ - bool "Dynamic tick timer" - depends on !GENERIC_CLOCKEVENTS - help - Select this option if you want to disable continuous timer ticks - and have them programmed to occur as required. This option saves - power as the system can remain in idle state for longer. - - By default dynamic tick is disabled during the boot, and can be - manually enabled with: - - echo 1 > /sys/devices/system/timer/timer0/dyn_tick - - Alternatively, if you want dynamic tick automatically enabled - during boot, pass "dyntick=enable" via the kernel command string. - - Please note that dynamic tick may affect the accuracy of - timekeeping on some platforms depending on the implementation. - Currently at least OMAP, PXA2xx and SA11x0 platforms are known - to have accurate timekeeping with dynamic tick. - config HZ int default 128 if ARCH_L7200 diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig index e32e7364812..b8e73e95598 100644 --- a/arch/arm/configs/at91cap9adk_defconfig +++ b/arch/arm/configs/at91cap9adk_defconfig @@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index 2dbbbc3d4ac..868fb7b9530 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig @@ -169,7 +169,6 @@ CONFIG_AT91_CF=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index 6e994f7820c..de43fc67561 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig @@ -160,7 +160,6 @@ CONFIG_ISA_DMA_API=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig index f659c938473..2011adfa675 100644 --- a/arch/arm/configs/at91sam9260ek_defconfig +++ b/arch/arm/configs/at91sam9260ek_defconfig @@ -220,7 +220,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig index 3802e85f748..4049768962d 100644 --- a/arch/arm/configs/at91sam9261ek_defconfig +++ b/arch/arm/configs/at91sam9261ek_defconfig @@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig index 32a0d74e0c8..fa1c5aecb5a 100644 --- a/arch/arm/configs/at91sam9263ek_defconfig +++ b/arch/arm/configs/at91sam9263ek_defconfig @@ -213,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig index 98e6746d02b..d8ec5f9ca6e 100644 --- a/arch/arm/configs/at91sam9rlek_defconfig +++ b/arch/arm/configs/at91sam9rlek_defconfig @@ -211,7 +211,6 @@ CONFIG_CPU_CP15_MMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig index d846a492e5c..85c80f723d8 100644 --- a/arch/arm/configs/ateb9200_defconfig +++ b/arch/arm/configs/ateb9200_defconfig @@ -171,7 +171,6 @@ CONFIG_AT91_CF=m # Kernel Features # CONFIG_PREEMPT=y -CONFIG_NO_IDLE_HZ=y CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/cm_x270_defconfig b/arch/arm/configs/cm_x270_defconfig index 5cab08397ae..33b201c3b30 100644 --- a/arch/arm/configs/cm_x270_defconfig +++ b/arch/arm/configs/cm_x270_defconfig @@ -194,7 +194,6 @@ CONFIG_PCI_HOST_ITE8152=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig index 4264e273202..f7622e65816 100644 --- a/arch/arm/configs/collie_defconfig +++ b/arch/arm/configs/collie_defconfig @@ -166,7 +166,6 @@ CONFIG_PCMCIA_SA1100=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set CONFIG_ARCH_DISCONTIGMEM_ENABLE=y diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index e8980a9bb89..9b8748a8d9d 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -165,7 +165,6 @@ CONFIG_PCMCIA_PXA2XX=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y diff --git a/arch/arm/configs/ecbat91_defconfig b/arch/arm/configs/ecbat91_defconfig index 90ed214e367..cfeb817ad21 100644 --- a/arch/arm/configs/ecbat91_defconfig +++ b/arch/arm/configs/ecbat91_defconfig @@ -230,7 +230,6 @@ CONFIG_AT91_CF=y # # CONFIG_TICK_ONESHOT is not set CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig index 6bea0901bdf..d3114c23603 100644 --- a/arch/arm/configs/em_x270_defconfig +++ b/arch/arm/configs/em_x270_defconfig @@ -197,7 +197,6 @@ CONFIG_XSCALE_PMU=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 24a701ab33e..21aa013793c 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig @@ -184,7 +184,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig index ed487b90dbe..493ecee24f9 100644 --- a/arch/arm/configs/eseries_pxa_defconfig +++ b/arch/arm/configs/eseries_pxa_defconfig @@ -251,7 +251,6 @@ CONFIG_PCMCIA_PXA2XX=m # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig index 988b4d13e76..482e5706105 100644 --- a/arch/arm/configs/iop13xx_defconfig +++ b/arch/arm/configs/iop13xx_defconfig @@ -197,7 +197,6 @@ CONFIG_PCI_LEGACY=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig index 83f40d4041a..8612f58e105 100644 --- a/arch/arm/configs/iop32x_defconfig +++ b/arch/arm/configs/iop32x_defconfig @@ -201,7 +201,6 @@ CONFIG_PCI_LEGACY=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig index 917afb5ccfa..8b0098d19d0 100644 --- a/arch/arm/configs/iop33x_defconfig +++ b/arch/arm/configs/iop33x_defconfig @@ -197,7 +197,6 @@ CONFIG_PCI_LEGACY=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig index f8f9793b526..84680db6c61 100644 --- a/arch/arm/configs/ixp2000_defconfig +++ b/arch/arm/configs/ixp2000_defconfig @@ -184,7 +184,6 @@ CONFIG_PCI=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig index 27cf022dd80..4a2f7b2372d 100644 --- a/arch/arm/configs/ixp23xx_defconfig +++ b/arch/arm/configs/ixp23xx_defconfig @@ -180,7 +180,6 @@ CONFIG_PCI=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig index ae51a40db6f..6dd95a2c8d5 100644 --- a/arch/arm/configs/kafa_defconfig +++ b/arch/arm/configs/kafa_defconfig @@ -162,7 +162,6 @@ CONFIG_CPU_TLB_V4WBI=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig index c16537d9d67..8e74c66f239 100644 --- a/arch/arm/configs/kb9202_defconfig +++ b/arch/arm/configs/kb9202_defconfig @@ -126,7 +126,6 @@ CONFIG_ISA_DMA_API=y # # Kernel Features # -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y diff --git a/arch/arm/configs/ks8695_defconfig b/arch/arm/configs/ks8695_defconfig index 8ab21a0719e..6077f2cb88e 100644 --- a/arch/arm/configs/ks8695_defconfig +++ b/arch/arm/configs/ks8695_defconfig @@ -174,7 +174,6 @@ CONFIG_PCCARD_NONSTATIC=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig index a3bf5833b87..1a38d8e3fe6 100644 --- a/arch/arm/configs/lpd270_defconfig +++ b/arch/arm/configs/lpd270_defconfig @@ -173,7 +173,6 @@ CONFIG_XSCALE_PMU=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig index 46a0f7fe1fa..7a2e932da1c 100644 --- a/arch/arm/configs/lpd7a404_defconfig +++ b/arch/arm/configs/lpd7a404_defconfig @@ -148,7 +148,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set # CONFIG_AEABI is not set CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y diff --git a/arch/arm/configs/netx_defconfig b/arch/arm/configs/netx_defconfig index 57f32f39d0f..0884f2370c3 100644 --- a/arch/arm/configs/netx_defconfig +++ b/arch/arm/configs/netx_defconfig @@ -154,7 +154,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig index 650a248613e..418ca2febbe 100644 --- a/arch/arm/configs/onearm_defconfig +++ b/arch/arm/configs/onearm_defconfig @@ -202,7 +202,6 @@ CONFIG_AT91_CF=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig index 95a22f51280..14826f0dabd 100644 --- a/arch/arm/configs/picotux200_defconfig +++ b/arch/arm/configs/picotux200_defconfig @@ -201,7 +201,6 @@ CONFIG_ARM_THUMB=y # Kernel Features # # CONFIG_PREEMPT is not set -CONFIG_NO_IDLE_HZ=y CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig index b5e11aa2e29..811b8f60d19 100644 --- a/arch/arm/configs/pnx4008_defconfig +++ b/arch/arm/configs/pnx4008_defconfig @@ -151,7 +151,6 @@ CONFIG_ARM_THUMB=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig index fc39ba1a89f..0c09b23167e 100644 --- a/arch/arm/configs/realview-smp_defconfig +++ b/arch/arm/configs/realview-smp_defconfig @@ -177,7 +177,6 @@ CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y CONFIG_LOCAL_TIMERS=y # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index accbf529ce5..907e54344da 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -126,7 +126,6 @@ CONFIG_ISA_DMA_API=y # # Kernel Features # -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig index 5ddecb9ddf0..f62d1817d2c 100644 --- a/arch/arm/configs/rpc_defconfig +++ b/arch/arm/configs/rpc_defconfig @@ -190,7 +190,6 @@ CONFIG_ISA_DMA_API=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index f8a1645b3d4..6d03763773b 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -246,7 +246,6 @@ CONFIG_ISA=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=200 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/sam9_l9260_defconfig b/arch/arm/configs/sam9_l9260_defconfig index 484dc9739df..8688362bcf7 100644 --- a/arch/arm/configs/sam9_l9260_defconfig +++ b/arch/arm/configs/sam9_l9260_defconfig @@ -211,7 +211,6 @@ CONFIG_ARM_THUMB=y # # CONFIG_TICK_ONESHOT is not set CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index aa7a0117950..7d59fb1f1ce 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -164,7 +164,6 @@ CONFIG_PCMCIA_PXA2XX=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y diff --git a/arch/arm/configs/tct_hammer_defconfig b/arch/arm/configs/tct_hammer_defconfig index 576b8339f0d..07dfb98df4f 100644 --- a/arch/arm/configs/tct_hammer_defconfig +++ b/arch/arm/configs/tct_hammer_defconfig @@ -247,7 +247,6 @@ CONFIG_ARM_THUMB=y # # CONFIG_TICK_ONESHOT is not set # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=200 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index 6db6392806f..8b7a431a8bf 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig @@ -195,7 +195,6 @@ CONFIG_PCMCIA_PXA2XX=y # Kernel Features # CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index 48dca69adda..8355f88f729 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -151,7 +151,6 @@ CONFIG_ARM_AMBA=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 46bf2ede612..199b3680118 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -133,10 +133,8 @@ static void default_idle(void) cpu_relax(); else { local_irq_disable(); - if (!need_resched()) { - timer_dyn_reprogram(); + if (!need_resched()) arch_idle(); - } local_irq_enable(); } } diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index b5867eca1d0..cc5145b28e7 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -365,108 +365,6 @@ static struct sysdev_class timer_sysclass = { .resume = timer_resume, }; -#ifdef CONFIG_NO_IDLE_HZ -static int timer_dyn_tick_enable(void) -{ - struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; - unsigned long flags; - int ret = -ENODEV; - - if (dyn_tick) { - spin_lock_irqsave(&dyn_tick->lock, flags); - ret = 0; - if (!(dyn_tick->state & DYN_TICK_ENABLED)) { - ret = dyn_tick->enable(); - - if (ret == 0) - dyn_tick->state |= DYN_TICK_ENABLED; - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); - } - - return ret; -} - -static int timer_dyn_tick_disable(void) -{ - struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; - unsigned long flags; - int ret = -ENODEV; - - if (dyn_tick) { - spin_lock_irqsave(&dyn_tick->lock, flags); - ret = 0; - if (dyn_tick->state & DYN_TICK_ENABLED) { - ret = dyn_tick->disable(); - - if (ret == 0) - dyn_tick->state &= ~DYN_TICK_ENABLED; - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); - } - - return ret; -} - -/* - * Reprogram the system timer for at least the calculated time interval. - * This function should be called from the idle thread with IRQs disabled, - * immediately before sleeping. - */ -void timer_dyn_reprogram(void) -{ - struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; - unsigned long next, seq, flags; - - if (!dyn_tick) - return; - - spin_lock_irqsave(&dyn_tick->lock, flags); - if (dyn_tick->state & DYN_TICK_ENABLED) { - next = next_timer_interrupt(); - do { - seq = read_seqbegin(&xtime_lock); - dyn_tick->reprogram(next - jiffies); - } while (read_seqretry(&xtime_lock, seq)); - } - spin_unlock_irqrestore(&dyn_tick->lock, flags); -} - -static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) -{ - return sprintf(buf, "%i\n", - (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); -} - -static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, - size_t count) -{ - unsigned int enable = simple_strtoul(buf, NULL, 2); - - if (enable) - timer_dyn_tick_enable(); - else - timer_dyn_tick_disable(); - - return count; -} -static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); - -/* - * dyntick=enable|disable - */ -static char dyntick_str[4] __initdata = ""; - -static int __init dyntick_setup(char *str) -{ - if (str) - strlcpy(dyntick_str, str, sizeof(dyntick_str)); - return 1; -} - -__setup("dyntick=", dyntick_setup); -#endif - static int __init timer_init_sysfs(void) { int ret = sysdev_class_register(&timer_sysclass); @@ -475,19 +373,6 @@ static int __init timer_init_sysfs(void) ret = sysdev_register(&system_timer->dev); } -#ifdef CONFIG_NO_IDLE_HZ - if (ret == 0 && system_timer->dyn_tick) { - ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick); - - /* - * Turn on dynamic tick after calibrate delay - * for correct bogomips - */ - if (ret == 0 && dyntick_str[0] == 'e') - ret = timer_dyn_tick_enable(); - } -#endif - return ret; } @@ -500,10 +385,5 @@ void __init time_init(void) system_timer->offset = dummy_gettimeoffset; #endif system_timer->init(); - -#ifdef CONFIG_NO_IDLE_HZ - if (system_timer->dyn_tick) - spin_lock_init(&system_timer->dyn_tick->lock); -#endif } diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index e6c64e10b7e..742f79e73bd 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -116,13 +116,6 @@ void omap_pm_idle(void) return; } - /* - * Since an interrupt may set up a timer, we don't want to - * reprogram the hardware timer with interrupts enabled. - * Re-enable interrupts only after returning from idle. - */ - timer_dyn_reprogram(); - #ifdef CONFIG_OMAP_MPU_TIMER #warning Enable 32kHz OS timer in order to allow sleep states in idle use_idlect1 = use_idlect1 & ~(1 << 9); diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index aad781dcf1b..d6c9de82ca0 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -57,13 +57,6 @@ void omap2_pm_idle(void) return; } - /* - * Since an interrupt may set up a timer, we don't want to - * reprogram the hardware timer with interrupts enabled. - * Re-enable interrupts only after returning from idle. - */ - timer_dyn_reprogram(); - omap2_sram_idle(); local_fiq_enable(); local_irq_enable(); diff --git a/include/asm-arm/dyntick.h b/include/asm-arm/dyntick.h deleted file mode 100644 index 19fab2d2b76..00000000000 --- a/include/asm-arm/dyntick.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASMARM_DYNTICK_H -#define _ASMARM_DYNTICK_H - -#include - -#endif /* _ASMARM_DYNTICK_H */ diff --git a/include/asm-arm/hw_irq.h b/include/asm-arm/hw_irq.h index 98d594a973d..f1a08a50060 100644 --- a/include/asm-arm/hw_irq.h +++ b/include/asm-arm/hw_irq.h @@ -6,15 +6,4 @@ #include -#if defined(CONFIG_NO_IDLE_HZ) -# include -# define handle_dynamic_tick(action) \ - if (!(action->flags & IRQF_TIMER) && system_timer->dyn_tick) { \ - write_seqlock(&xtime_lock); \ - if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) \ - system_timer->dyn_tick->handler(irq, NULL); \ - write_sequnlock(&xtime_lock); \ - } -#endif - #endif diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h index 5dc357013b7..2fd36ea0130 100644 --- a/include/asm-arm/mach/time.h +++ b/include/asm-arm/mach/time.h @@ -41,30 +41,8 @@ struct sys_timer { #ifndef CONFIG_GENERIC_TIME unsigned long (*offset)(void); #endif - -#ifdef CONFIG_NO_IDLE_HZ - struct dyn_tick_timer *dyn_tick; -#endif -}; - -#ifdef CONFIG_NO_IDLE_HZ - -#define DYN_TICK_ENABLED (1 << 1) - -struct dyn_tick_timer { - spinlock_t lock; - unsigned int state; /* Current state */ - int (*enable)(void); /* Enables dynamic tick */ - int (*disable)(void); /* Disables dynamic tick */ - void (*reprogram)(unsigned long); /* Reprograms the timer */ - int (*handler)(int, void *); }; -void timer_dyn_reprogram(void); -#else -#define timer_dyn_reprogram() do { } while (0) -#endif - extern struct sys_timer *system_timer; extern void timer_tick(void); -- cgit v1.2.3-70-g09d2 From 284d115ec9b70d7c38752d10ad393a198db07a4b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 17:32:16 +0100 Subject: [ARM] pxa: separate PXA25x and PXA27x UDC register definitions The PXA25x and PXA27x USB device controller register definitions are different. Currently, they live side by side in pxa-regs.h, but only one set is available depending on the setting of PXA25x or PXA27x. This means that if we build to support both PXA25x and PXA27x, the PXA27x definitions are unavailable, even to PXA27x specific code. Remove these definitions from pxa-regs.h, and place them in separate files. Include these files where appropriate. Note: according to the dependencies in drivers/usb/gadget/Kconfig, we do not support the UDC on PXA27x nor PXA3xx CPUs, so remove the platform devices from pxa27x.c and pxa3xx.c. Signed-off-by: Russell King --- arch/arm/mach-pxa/em-x270.c | 1 + arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/pxa3xx.c | 2 +- drivers/usb/gadget/pxa2xx_udc.c | 10 +- include/asm-arm/arch-pxa/pxa-regs.h | 412 ---------------------------------- include/asm-arm/arch-pxa/pxa25x-udc.h | 163 ++++++++++++++ include/asm-arm/arch-pxa/pxa27x-udc.h | 256 +++++++++++++++++++++ 7 files changed, 430 insertions(+), 416 deletions(-) create mode 100644 include/asm-arm/arch-pxa/pxa25x-udc.h create mode 100644 include/asm-arm/arch-pxa/pxa27x-udc.h (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index edc4f07a230..1269ac99150 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e945836e12..cdaf573e0f1 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -353,7 +353,7 @@ void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) } static struct platform_device *devices[] __initdata = { - &pxa_device_udc, +/* &pxa_device_udc, The UDC driver is PXA25x only */ &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 644550bfa33..7fbe78649da 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -520,7 +520,7 @@ void __init pxa3xx_init_irq(void) */ static struct platform_device *devices[] __initdata = { - &pxa_device_udc, +/* &pxa_device_udc, The UDC driver is PXA25x only */ &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 08f699b1fc5..63db96adc0b 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -46,19 +46,25 @@ #include #include #include +#include #include #include #include -#include #include #include #include -#include #include #include +/* + * This driver is PXA25x only. Grab the right register definitions. + */ +#ifdef CONFIG_ARCH_PXA +#include +#endif + #include diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 4b2ea1e95c5..68d74287730 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -599,418 +599,6 @@ #define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */ -/* - * USB Device Controller - * PXA25x and PXA27x USB device controller registers are different. - */ -#if defined(CONFIG_PXA25x) - -#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ -#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */ -#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */ - -#define UDCCR __REG(0x40600000) /* UDC Control Register */ -#define UDCCR_UDE (1 << 0) /* UDC enable */ -#define UDCCR_UDA (1 << 1) /* UDC active */ -#define UDCCR_RSM (1 << 2) /* Device resume */ -#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */ -#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */ -#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */ -#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */ -#define UDCCR_REM (1 << 7) /* Reset interrupt mask */ - -#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */ -#define UDCCS0_OPR (1 << 0) /* OUT packet ready */ -#define UDCCS0_IPR (1 << 1) /* IN packet ready */ -#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */ -#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */ -#define UDCCS0_SST (1 << 4) /* Sent stall */ -#define UDCCS0_FST (1 << 5) /* Force stall */ -#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */ -#define UDCCS0_SA (1 << 7) /* Setup active */ - -/* Bulk IN - Endpoint 1,6,11 */ -#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */ -#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */ -#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */ - -#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */ -#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */ -#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */ -#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */ -#define UDCCS_BI_SST (1 << 4) /* Sent stall */ -#define UDCCS_BI_FST (1 << 5) /* Force stall */ -#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */ - -/* Bulk OUT - Endpoint 2,7,12 */ -#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */ -#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */ -#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */ - -#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */ -#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */ -#define UDCCS_BO_DME (1 << 3) /* DMA enable */ -#define UDCCS_BO_SST (1 << 4) /* Sent stall */ -#define UDCCS_BO_FST (1 << 5) /* Force stall */ -#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */ -#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */ - -/* Isochronous IN - Endpoint 3,8,13 */ -#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */ -#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */ -#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */ - -#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */ -#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */ -#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */ -#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */ -#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */ - -/* Isochronous OUT - Endpoint 4,9,14 */ -#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */ -#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */ -#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */ - -#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */ -#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */ -#define UDCCS_IO_ROF (1 << 2) /* Receive overflow */ -#define UDCCS_IO_DME (1 << 3) /* DMA enable */ -#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */ -#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */ - -/* Interrupt IN - Endpoint 5,10,15 */ -#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */ -#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */ -#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */ - -#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */ -#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */ -#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */ -#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */ -#define UDCCS_INT_SST (1 << 4) /* Sent stall */ -#define UDCCS_INT_FST (1 << 5) /* Force stall */ -#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */ - -#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */ -#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */ -#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */ -#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */ -#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */ -#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */ -#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */ -#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */ -#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */ -#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */ -#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */ -#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */ -#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */ -#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */ -#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */ -#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */ -#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */ -#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */ -#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data Register */ -#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data Register */ -#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data Register */ -#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */ -#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */ -#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */ - -#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */ - -#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */ -#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */ -#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */ -#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */ -#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */ -#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */ -#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */ -#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */ - -#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */ - -#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */ -#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */ -#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */ -#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */ -#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */ -#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */ -#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */ -#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */ - -#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */ - -#define USIR0_IR0 (1 << 0) /* Interrupt request ep 0 */ -#define USIR0_IR1 (1 << 1) /* Interrupt request ep 1 */ -#define USIR0_IR2 (1 << 2) /* Interrupt request ep 2 */ -#define USIR0_IR3 (1 << 3) /* Interrupt request ep 3 */ -#define USIR0_IR4 (1 << 4) /* Interrupt request ep 4 */ -#define USIR0_IR5 (1 << 5) /* Interrupt request ep 5 */ -#define USIR0_IR6 (1 << 6) /* Interrupt request ep 6 */ -#define USIR0_IR7 (1 << 7) /* Interrupt request ep 7 */ - -#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */ - -#define USIR1_IR8 (1 << 0) /* Interrupt request ep 8 */ -#define USIR1_IR9 (1 << 1) /* Interrupt request ep 9 */ -#define USIR1_IR10 (1 << 2) /* Interrupt request ep 10 */ -#define USIR1_IR11 (1 << 3) /* Interrupt request ep 11 */ -#define USIR1_IR12 (1 << 4) /* Interrupt request ep 12 */ -#define USIR1_IR13 (1 << 5) /* Interrupt request ep 13 */ -#define USIR1_IR14 (1 << 6) /* Interrupt request ep 14 */ -#define USIR1_IR15 (1 << 7) /* Interrupt request ep 15 */ - -#elif defined(CONFIG_PXA27x) - -#define UDCCR __REG(0x40600000) /* UDC Control Register */ -#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ -#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation - Protocol Port Support */ -#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol - Support */ -#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol - Enable */ -#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ -#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ -#define UDCCR_ACN_S 11 -#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ -#define UDCCR_AIN_S 8 -#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface - Setting Number */ -#define UDCCR_AAISN_S 5 -#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active - Configuration */ -#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration - Error */ -#define UDCCR_UDR (1 << 2) /* UDC Resume */ -#define UDCCR_UDA (1 << 1) /* UDC Active */ -#define UDCCR_UDE (1 << 0) /* UDC Enable */ - -#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control Register0 */ -#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control Register1 */ -#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ -#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ - -#define UDC_INT_FIFOERROR (0x2) -#define UDC_INT_PACKETCMP (0x1) - -#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ -#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ -#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ -#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ -#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ - -#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */ -#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */ -#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */ -#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */ -#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */ -#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */ -#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */ - -#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */ -#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */ -#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ -#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt - Rising Edge Interrupt Enable */ -#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt - Falling Edge Interrupt Enable */ -#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising - Edge Interrupt Enable */ -#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling - Edge Interrupt Enable */ -#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge - Interrupt Enable */ - -#define UP2OCR __REG(0x40600020) /* USB Port 2 Output Control register */ - -#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ -#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ -#define UP2OCR_DPPDE (1 << 2) /* Host Port 2 Transceiver D+ Pull Down Enable */ -#define UP2OCR_DMPDE (1 << 3) /* Host Port 2 Transceiver D- Pull Down Enable */ -#define UP2OCR_DPPUE (1 << 4) /* Host Port 2 Transceiver D+ Pull Up Enable */ -#define UP2OCR_DMPUE (1 << 5) /* Host Port 2 Transceiver D- Pull Up Enable */ -#define UP2OCR_DPPUBE (1 << 6) /* Host Port 2 Transceiver D+ Pull Up Bypass Enable */ -#define UP2OCR_DMPUBE (1 << 7) /* Host Port 2 Transceiver D- Pull Up Bypass Enable */ -#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */ -#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */ -#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ -#define UP2OCR_HXS (1 << 16) /* Host Port 2 Transceiver Output Select */ -#define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */ -#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ - -#define UDCCSN(x) __REG2(0x40600100, (x) << 2) -#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ -#define UDCCSR0_SA (1 << 7) /* Setup Active */ -#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ -#define UDCCSR0_FST (1 << 5) /* Force Stall */ -#define UDCCSR0_SST (1 << 4) /* Sent Stall */ -#define UDCCSR0_DME (1 << 3) /* DMA Enable */ -#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ -#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ -#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ - -#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register - Endpoint A */ -#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register - Endpoint B */ -#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */ -#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register - Endpoint D */ -#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register - Endpoint E */ -#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register - Endpoint F */ -#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */ -#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register - Endpoint H */ -#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register - Endpoint I */ -#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register - Endpoint J */ -#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */ -#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register - Endpoint L */ -#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register - Endpoint M */ -#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register - Endpoint N */ -#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */ -#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */ -#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register - Endpoint R */ -#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register - Endpoint S */ -#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */ -#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register - Endpoint U */ -#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register - Endpoint V */ -#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register - Endpoint W */ -#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */ - -#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ -#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ -#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ -#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ -#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ -#define UDCCSR_FST (1 << 5) /* Force STALL */ -#define UDCCSR_SST (1 << 4) /* Sent STALL */ -#define UDCCSR_DME (1 << 3) /* DMA Enable */ -#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ -#define UDCCSR_PC (1 << 1) /* Packet Complete */ -#define UDCCSR_FS (1 << 0) /* FIFO needs service */ - -#define UDCBCN(x) __REG2(0x40600200, (x)<<2) -#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */ -#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */ -#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */ -#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */ -#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */ -#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */ -#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */ -#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */ -#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */ -#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */ -#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */ -#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */ -#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */ -#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */ -#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */ -#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */ -#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */ -#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */ -#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */ -#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */ -#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */ -#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */ -#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */ -#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */ - -#define UDCDN(x) __REG2(0x40600300, (x)<<2) -#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2)) -#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x)))) -#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */ -#define UDCDRA __REG(0x40600304) /* Data Register - EPA */ -#define UDCDRB __REG(0x40600308) /* Data Register - EPB */ -#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */ -#define UDCDRD __REG(0x40600310) /* Data Register - EPD */ -#define UDCDRE __REG(0x40600314) /* Data Register - EPE */ -#define UDCDRF __REG(0x40600318) /* Data Register - EPF */ -#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */ -#define UDCDRH __REG(0x40600320) /* Data Register - EPH */ -#define UDCDRI __REG(0x40600324) /* Data Register - EPI */ -#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */ -#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */ -#define UDCDRL __REG(0x40600330) /* Data Register - EPL */ -#define UDCDRM __REG(0x40600334) /* Data Register - EPM */ -#define UDCDRN __REG(0x40600338) /* Data Register - EPN */ -#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */ -#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */ -#define UDCDRR __REG(0x40600344) /* Data Register - EPR */ -#define UDCDRS __REG(0x40600348) /* Data Register - EPS */ -#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */ -#define UDCDRU __REG(0x40600350) /* Data Register - EPU */ -#define UDCDRV __REG(0x40600354) /* Data Register - EPV */ -#define UDCDRW __REG(0x40600358) /* Data Register - EPW */ -#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */ - -#define UDCCN(x) __REG2(0x40600400, (x)<<2) -#define UDCCRA __REG(0x40600404) /* Configuration register EPA */ -#define UDCCRB __REG(0x40600408) /* Configuration register EPB */ -#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */ -#define UDCCRD __REG(0x40600410) /* Configuration register EPD */ -#define UDCCRE __REG(0x40600414) /* Configuration register EPE */ -#define UDCCRF __REG(0x40600418) /* Configuration register EPF */ -#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */ -#define UDCCRH __REG(0x40600420) /* Configuration register EPH */ -#define UDCCRI __REG(0x40600424) /* Configuration register EPI */ -#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */ -#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */ -#define UDCCRL __REG(0x40600430) /* Configuration register EPL */ -#define UDCCRM __REG(0x40600434) /* Configuration register EPM */ -#define UDCCRN __REG(0x40600438) /* Configuration register EPN */ -#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */ -#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */ -#define UDCCRR __REG(0x40600444) /* Configuration register EPR */ -#define UDCCRS __REG(0x40600448) /* Configuration register EPS */ -#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */ -#define UDCCRU __REG(0x40600450) /* Configuration register EPU */ -#define UDCCRV __REG(0x40600454) /* Configuration register EPV */ -#define UDCCRW __REG(0x40600458) /* Configuration register EPW */ -#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */ - -#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ -#define UDCCONR_CN_S (25) -#define UDCCONR_IN (0x07 << 22) /* Interface Number */ -#define UDCCONR_IN_S (22) -#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ -#define UDCCONR_AISN_S (19) -#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ -#define UDCCONR_EN_S (15) -#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ -#define UDCCONR_ET_S (13) -#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ -#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ -#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ -#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ -#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ -#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ -#define UDCCONR_MPS_S (2) -#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ -#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ - - -#define UDC_INT_FIFOERROR (0x2) -#define UDC_INT_PACKETCMP (0x1) - -#define UDC_FNR_MASK (0x7ff) - -#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST) -#define UDC_BCR_MASK (0x3ff) -#endif - /* * Fast Infrared Communication Port */ diff --git a/include/asm-arm/arch-pxa/pxa25x-udc.h b/include/asm-arm/arch-pxa/pxa25x-udc.h new file mode 100644 index 00000000000..840305916b6 --- /dev/null +++ b/include/asm-arm/arch-pxa/pxa25x-udc.h @@ -0,0 +1,163 @@ +#ifndef _ASM_ARCH_PXA25X_UDC_H +#define _ASM_ARCH_PXA25X_UDC_H + +#ifdef _ASM_ARCH_PXA27X_UDC_H +#error You can't include both PXA25x and PXA27x UDC support +#endif + +#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ +#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */ +#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */ + +#define UDCCR __REG(0x40600000) /* UDC Control Register */ +#define UDCCR_UDE (1 << 0) /* UDC enable */ +#define UDCCR_UDA (1 << 1) /* UDC active */ +#define UDCCR_RSM (1 << 2) /* Device resume */ +#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */ +#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */ +#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */ +#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */ +#define UDCCR_REM (1 << 7) /* Reset interrupt mask */ + +#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */ +#define UDCCS0_OPR (1 << 0) /* OUT packet ready */ +#define UDCCS0_IPR (1 << 1) /* IN packet ready */ +#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */ +#define UDCCS0_SST (1 << 4) /* Sent stall */ +#define UDCCS0_FST (1 << 5) /* Force stall */ +#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */ +#define UDCCS0_SA (1 << 7) /* Setup active */ + +/* Bulk IN - Endpoint 1,6,11 */ +#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */ +#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */ +#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */ + +#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_BI_SST (1 << 4) /* Sent stall */ +#define UDCCS_BI_FST (1 << 5) /* Force stall */ +#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */ + +/* Bulk OUT - Endpoint 2,7,12 */ +#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */ +#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */ +#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */ + +#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */ +#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */ +#define UDCCS_BO_DME (1 << 3) /* DMA enable */ +#define UDCCS_BO_SST (1 << 4) /* Sent stall */ +#define UDCCS_BO_FST (1 << 5) /* Force stall */ +#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */ +#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */ + +/* Isochronous IN - Endpoint 3,8,13 */ +#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */ +#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */ +#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */ + +#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */ + +/* Isochronous OUT - Endpoint 4,9,14 */ +#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */ +#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */ +#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */ + +#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */ +#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */ +#define UDCCS_IO_ROF (1 << 2) /* Receive overflow */ +#define UDCCS_IO_DME (1 << 3) /* DMA enable */ +#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */ +#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */ + +/* Interrupt IN - Endpoint 5,10,15 */ +#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */ +#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */ +#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */ + +#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */ +#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */ +#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */ +#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */ +#define UDCCS_INT_SST (1 << 4) /* Sent stall */ +#define UDCCS_INT_FST (1 << 5) /* Force stall */ +#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */ + +#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */ +#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */ +#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */ +#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */ +#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */ +#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */ +#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */ +#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */ +#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */ +#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */ +#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */ +#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */ +#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */ +#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */ +#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */ +#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */ +#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */ +#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */ +#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data Register */ +#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data Register */ +#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data Register */ +#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */ +#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */ +#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */ + +#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */ + +#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */ +#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */ +#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */ +#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */ +#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */ +#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */ +#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */ +#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */ + +#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */ + +#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */ +#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */ +#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */ +#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */ +#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */ +#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */ +#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */ +#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */ + +#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */ + +#define USIR0_IR0 (1 << 0) /* Interrupt request ep 0 */ +#define USIR0_IR1 (1 << 1) /* Interrupt request ep 1 */ +#define USIR0_IR2 (1 << 2) /* Interrupt request ep 2 */ +#define USIR0_IR3 (1 << 3) /* Interrupt request ep 3 */ +#define USIR0_IR4 (1 << 4) /* Interrupt request ep 4 */ +#define USIR0_IR5 (1 << 5) /* Interrupt request ep 5 */ +#define USIR0_IR6 (1 << 6) /* Interrupt request ep 6 */ +#define USIR0_IR7 (1 << 7) /* Interrupt request ep 7 */ + +#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */ + +#define USIR1_IR8 (1 << 0) /* Interrupt request ep 8 */ +#define USIR1_IR9 (1 << 1) /* Interrupt request ep 9 */ +#define USIR1_IR10 (1 << 2) /* Interrupt request ep 10 */ +#define USIR1_IR11 (1 << 3) /* Interrupt request ep 11 */ +#define USIR1_IR12 (1 << 4) /* Interrupt request ep 12 */ +#define USIR1_IR13 (1 << 5) /* Interrupt request ep 13 */ +#define USIR1_IR14 (1 << 6) /* Interrupt request ep 14 */ +#define USIR1_IR15 (1 << 7) /* Interrupt request ep 15 */ + +#endif diff --git a/include/asm-arm/arch-pxa/pxa27x-udc.h b/include/asm-arm/arch-pxa/pxa27x-udc.h new file mode 100644 index 00000000000..9cf0b1f8811 --- /dev/null +++ b/include/asm-arm/arch-pxa/pxa27x-udc.h @@ -0,0 +1,256 @@ +#ifndef _ASM_ARCH_PXA27X_UDC_H +#define _ASM_ARCH_PXA27X_UDC_H + +#ifdef _ASM_ARCH_PXA25X_UDC_H +#error You can't include both PXA25x and PXA27x UDC support +#endif + +#define UDCCR __REG(0x40600000) /* UDC Control Register */ +#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ +#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation + Protocol Port Support */ +#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol + Support */ +#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol + Enable */ +#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ +#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ +#define UDCCR_ACN_S 11 +#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ +#define UDCCR_AIN_S 8 +#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface + Setting Number */ +#define UDCCR_AAISN_S 5 +#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active + Configuration */ +#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration + Error */ +#define UDCCR_UDR (1 << 2) /* UDC Resume */ +#define UDCCR_UDA (1 << 1) /* UDC Active */ +#define UDCCR_UDE (1 << 0) /* UDC Enable */ + +#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control Register0 */ +#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control Register1 */ +#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ +#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ + +#define UDC_INT_FIFOERROR (0x2) +#define UDC_INT_PACKETCMP (0x1) + +#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) +#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ +#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ +#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ +#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ +#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ + +#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */ +#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */ +#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) +#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */ +#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */ +#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */ +#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */ +#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */ + +#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */ +#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */ +#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ +#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt + Rising Edge Interrupt Enable */ +#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt + Falling Edge Interrupt Enable */ +#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge + Interrupt Enable */ +#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising + Edge Interrupt Enable */ +#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling + Edge Interrupt Enable */ +#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge + Interrupt Enable */ +#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge + Interrupt Enable */ + +#define UP2OCR __REG(0x40600020) /* USB Port 2 Output Control register */ + +#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ +#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ +#define UP2OCR_DPPDE (1 << 2) /* Host Port 2 Transceiver D+ Pull Down Enable */ +#define UP2OCR_DMPDE (1 << 3) /* Host Port 2 Transceiver D- Pull Down Enable */ +#define UP2OCR_DPPUE (1 << 4) /* Host Port 2 Transceiver D+ Pull Up Enable */ +#define UP2OCR_DMPUE (1 << 5) /* Host Port 2 Transceiver D- Pull Up Enable */ +#define UP2OCR_DPPUBE (1 << 6) /* Host Port 2 Transceiver D+ Pull Up Bypass Enable */ +#define UP2OCR_DMPUBE (1 << 7) /* Host Port 2 Transceiver D- Pull Up Bypass Enable */ +#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */ +#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */ +#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ +#define UP2OCR_HXS (1 << 16) /* Host Port 2 Transceiver Output Select */ +#define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */ +#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ + +#define UDCCSN(x) __REG2(0x40600100, (x) << 2) +#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ +#define UDCCSR0_SA (1 << 7) /* Setup Active */ +#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ +#define UDCCSR0_FST (1 << 5) /* Force Stall */ +#define UDCCSR0_SST (1 << 4) /* Sent Stall */ +#define UDCCSR0_DME (1 << 3) /* DMA Enable */ +#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ +#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ +#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ + +#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register - Endpoint A */ +#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register - Endpoint B */ +#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */ +#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register - Endpoint D */ +#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register - Endpoint E */ +#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register - Endpoint F */ +#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */ +#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register - Endpoint H */ +#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register - Endpoint I */ +#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register - Endpoint J */ +#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */ +#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register - Endpoint L */ +#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register - Endpoint M */ +#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register - Endpoint N */ +#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */ +#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */ +#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register - Endpoint R */ +#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register - Endpoint S */ +#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */ +#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register - Endpoint U */ +#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register - Endpoint V */ +#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register - Endpoint W */ +#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */ + +#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ +#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ +#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ +#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ +#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ +#define UDCCSR_FST (1 << 5) /* Force STALL */ +#define UDCCSR_SST (1 << 4) /* Sent STALL */ +#define UDCCSR_DME (1 << 3) /* DMA Enable */ +#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ +#define UDCCSR_PC (1 << 1) /* Packet Complete */ +#define UDCCSR_FS (1 << 0) /* FIFO needs service */ + +#define UDCBCN(x) __REG2(0x40600200, (x)<<2) +#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */ +#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */ +#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */ +#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */ +#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */ +#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */ +#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */ +#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */ +#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */ +#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */ +#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */ +#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */ +#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */ +#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */ +#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */ +#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */ +#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */ +#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */ +#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */ +#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */ +#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */ +#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */ +#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */ +#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */ + +#define UDCDN(x) __REG2(0x40600300, (x)<<2) +#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2)) +#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x)))) +#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */ +#define UDCDRA __REG(0x40600304) /* Data Register - EPA */ +#define UDCDRB __REG(0x40600308) /* Data Register - EPB */ +#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */ +#define UDCDRD __REG(0x40600310) /* Data Register - EPD */ +#define UDCDRE __REG(0x40600314) /* Data Register - EPE */ +#define UDCDRF __REG(0x40600318) /* Data Register - EPF */ +#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */ +#define UDCDRH __REG(0x40600320) /* Data Register - EPH */ +#define UDCDRI __REG(0x40600324) /* Data Register - EPI */ +#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */ +#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */ +#define UDCDRL __REG(0x40600330) /* Data Register - EPL */ +#define UDCDRM __REG(0x40600334) /* Data Register - EPM */ +#define UDCDRN __REG(0x40600338) /* Data Register - EPN */ +#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */ +#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */ +#define UDCDRR __REG(0x40600344) /* Data Register - EPR */ +#define UDCDRS __REG(0x40600348) /* Data Register - EPS */ +#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */ +#define UDCDRU __REG(0x40600350) /* Data Register - EPU */ +#define UDCDRV __REG(0x40600354) /* Data Register - EPV */ +#define UDCDRW __REG(0x40600358) /* Data Register - EPW */ +#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */ + +#define UDCCN(x) __REG2(0x40600400, (x)<<2) +#define UDCCRA __REG(0x40600404) /* Configuration register EPA */ +#define UDCCRB __REG(0x40600408) /* Configuration register EPB */ +#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */ +#define UDCCRD __REG(0x40600410) /* Configuration register EPD */ +#define UDCCRE __REG(0x40600414) /* Configuration register EPE */ +#define UDCCRF __REG(0x40600418) /* Configuration register EPF */ +#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */ +#define UDCCRH __REG(0x40600420) /* Configuration register EPH */ +#define UDCCRI __REG(0x40600424) /* Configuration register EPI */ +#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */ +#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */ +#define UDCCRL __REG(0x40600430) /* Configuration register EPL */ +#define UDCCRM __REG(0x40600434) /* Configuration register EPM */ +#define UDCCRN __REG(0x40600438) /* Configuration register EPN */ +#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */ +#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */ +#define UDCCRR __REG(0x40600444) /* Configuration register EPR */ +#define UDCCRS __REG(0x40600448) /* Configuration register EPS */ +#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */ +#define UDCCRU __REG(0x40600450) /* Configuration register EPU */ +#define UDCCRV __REG(0x40600454) /* Configuration register EPV */ +#define UDCCRW __REG(0x40600458) /* Configuration register EPW */ +#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */ + +#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ +#define UDCCONR_CN_S (25) +#define UDCCONR_IN (0x07 << 22) /* Interface Number */ +#define UDCCONR_IN_S (22) +#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ +#define UDCCONR_AISN_S (19) +#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ +#define UDCCONR_EN_S (15) +#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ +#define UDCCONR_ET_S (13) +#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ +#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ +#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ +#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ +#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ +#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ +#define UDCCONR_MPS_S (2) +#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ +#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ + + +#define UDC_INT_FIFOERROR (0x2) +#define UDC_INT_PACKETCMP (0x1) + +#define UDC_FNR_MASK (0x7ff) + +#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST) +#define UDC_BCR_MASK (0x3ff) + +#endif -- cgit v1.2.3-70-g09d2 From bedd78ca786c1d18c2a2785c7e40593dc9c9870f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 12:31:29 +0100 Subject: [RTC] remove old ARM rtc library code Now that all drivers using it are gone, remove the old ARM RTC library. Acked-by: Alessandro Zummo Signed-off-by: Russell King --- arch/arm/common/Makefile | 1 - arch/arm/common/rtctime.c | 434 ---------------------------------------------- include/asm-arm/rtc.h | 43 ----- 3 files changed, 478 deletions(-) delete mode 100644 arch/arm/common/rtctime.c delete mode 100644 include/asm-arm/rtc.h (limited to 'include/asm-arm') diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 3d0b9fa42f8..325e4b6a6af 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -2,7 +2,6 @@ # Makefile for the linux kernel. # -obj-y += rtctime.o obj-$(CONFIG_ARM_GIC) += gic.o obj-$(CONFIG_ARM_VIC) += vic.o obj-$(CONFIG_ICST525) += icst525.o diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c deleted file mode 100644 index aa8f7739c82..00000000000 --- a/arch/arm/common/rtctime.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * linux/arch/arm/common/rtctime.c - * - * Copyright (C) 2003 Deep Blue Solutions Ltd. - * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre. - * Based on rtc.c by Paul Gortmaker - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); -static struct fasync_struct *rtc_async_queue; - -/* - * rtc_lock protects rtc_irq_data - */ -static DEFINE_SPINLOCK(rtc_lock); -static unsigned long rtc_irq_data; - -/* - * rtc_sem protects rtc_inuse and rtc_ops - */ -static DEFINE_MUTEX(rtc_mutex); -static unsigned long rtc_inuse; -static struct rtc_ops *rtc_ops; - -#define rtc_epoch 1900UL - -/* - * Calculate the next alarm time given the requested alarm time mask - * and the current time. - */ -void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) -{ - unsigned long next_time; - unsigned long now_time; - - next->tm_year = now->tm_year; - next->tm_mon = now->tm_mon; - next->tm_mday = now->tm_mday; - next->tm_hour = alrm->tm_hour; - next->tm_min = alrm->tm_min; - next->tm_sec = alrm->tm_sec; - - rtc_tm_to_time(now, &now_time); - rtc_tm_to_time(next, &next_time); - - if (next_time < now_time) { - /* Advance one day */ - next_time += 60 * 60 * 24; - rtc_time_to_tm(next_time, next); - } -} -EXPORT_SYMBOL(rtc_next_alarm_time); - -static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) -{ - memset(tm, 0, sizeof(struct rtc_time)); - return ops->read_time(tm); -} - -static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) -{ - int ret; - - ret = rtc_valid_tm(tm); - if (ret == 0) - ret = ops->set_time(tm); - - return ret; -} - -static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -{ - int ret = -EINVAL; - if (ops->read_alarm) { - memset(alrm, 0, sizeof(struct rtc_wkalrm)); - ret = ops->read_alarm(alrm); - } - return ret; -} - -static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) -{ - int ret = -EINVAL; - if (ops->set_alarm) - ret = ops->set_alarm(alrm); - return ret; -} - -void rtc_update(unsigned long num, unsigned long events) -{ - spin_lock(&rtc_lock); - rtc_irq_data = (rtc_irq_data + (num << 8)) | events; - spin_unlock(&rtc_lock); - - wake_up_interruptible(&rtc_wait); - kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); -} -EXPORT_SYMBOL(rtc_update); - - -static ssize_t -rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) -{ - DECLARE_WAITQUEUE(wait, current); - unsigned long data; - ssize_t ret; - - if (count < sizeof(unsigned long)) - return -EINVAL; - - add_wait_queue(&rtc_wait, &wait); - do { - __set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irq(&rtc_lock); - data = rtc_irq_data; - rtc_irq_data = 0; - spin_unlock_irq(&rtc_lock); - - if (data != 0) { - ret = 0; - break; - } - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - schedule(); - } while (1); - set_current_state(TASK_RUNNING); - remove_wait_queue(&rtc_wait, &wait); - - if (ret == 0) { - ret = put_user(data, (unsigned long __user *)buf); - if (ret == 0) - ret = sizeof(unsigned long); - } - return ret; -} - -static unsigned int rtc_poll(struct file *file, poll_table *wait) -{ - unsigned long data; - - poll_wait(file, &rtc_wait, wait); - - spin_lock_irq(&rtc_lock); - data = rtc_irq_data; - spin_unlock_irq(&rtc_lock); - - return data != 0 ? POLLIN | POLLRDNORM : 0; -} - -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct rtc_ops *ops = file->private_data; - struct rtc_time tm; - struct rtc_wkalrm alrm; - void __user *uarg = (void __user *)arg; - int ret = -EINVAL; - - switch (cmd) { - case RTC_ALM_READ: - ret = rtc_arm_read_alarm(ops, &alrm); - if (ret) - break; - ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); - if (ret) - ret = -EFAULT; - break; - - case RTC_ALM_SET: - ret = copy_from_user(&alrm.time, uarg, sizeof(tm)); - if (ret) { - ret = -EFAULT; - break; - } - alrm.enabled = 0; - alrm.pending = 0; - alrm.time.tm_mday = -1; - alrm.time.tm_mon = -1; - alrm.time.tm_year = -1; - alrm.time.tm_wday = -1; - alrm.time.tm_yday = -1; - alrm.time.tm_isdst = -1; - ret = rtc_arm_set_alarm(ops, &alrm); - break; - - case RTC_RD_TIME: - ret = rtc_arm_read_time(ops, &tm); - if (ret) - break; - ret = copy_to_user(uarg, &tm, sizeof(tm)); - if (ret) - ret = -EFAULT; - break; - - case RTC_SET_TIME: - if (!capable(CAP_SYS_TIME)) { - ret = -EACCES; - break; - } - ret = copy_from_user(&tm, uarg, sizeof(tm)); - if (ret) { - ret = -EFAULT; - break; - } - ret = rtc_arm_set_time(ops, &tm); - break; - - case RTC_EPOCH_SET: -#ifndef rtc_epoch - /* - * There were no RTC clocks before 1900. - */ - if (arg < 1900) { - ret = -EINVAL; - break; - } - if (!capable(CAP_SYS_TIME)) { - ret = -EACCES; - break; - } - rtc_epoch = arg; - ret = 0; -#endif - break; - - case RTC_EPOCH_READ: - ret = put_user(rtc_epoch, (unsigned long __user *)uarg); - break; - - case RTC_WKALM_SET: - ret = copy_from_user(&alrm, uarg, sizeof(alrm)); - if (ret) { - ret = -EFAULT; - break; - } - ret = rtc_arm_set_alarm(ops, &alrm); - break; - - case RTC_WKALM_RD: - ret = rtc_arm_read_alarm(ops, &alrm); - if (ret) - break; - ret = copy_to_user(uarg, &alrm, sizeof(alrm)); - if (ret) - ret = -EFAULT; - break; - - default: - if (ops->ioctl) - ret = ops->ioctl(cmd, arg); - break; - } - return ret; -} - -static int rtc_open(struct inode *inode, struct file *file) -{ - int ret; - - mutex_lock(&rtc_mutex); - - if (rtc_inuse) { - ret = -EBUSY; - } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) { - ret = -ENODEV; - } else { - file->private_data = rtc_ops; - - ret = rtc_ops->open ? rtc_ops->open() : 0; - if (ret == 0) { - spin_lock_irq(&rtc_lock); - rtc_irq_data = 0; - spin_unlock_irq(&rtc_lock); - - rtc_inuse = 1; - } - } - mutex_unlock(&rtc_mutex); - - return ret; -} - -static int rtc_release(struct inode *inode, struct file *file) -{ - struct rtc_ops *ops = file->private_data; - - if (ops->release) - ops->release(); - - spin_lock_irq(&rtc_lock); - rtc_irq_data = 0; - spin_unlock_irq(&rtc_lock); - - module_put(rtc_ops->owner); - rtc_inuse = 0; - - return 0; -} - -static int rtc_fasync(int fd, struct file *file, int on) -{ - return fasync_helper(fd, file, on, &rtc_async_queue); -} - -static const struct file_operations rtc_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = rtc_read, - .poll = rtc_poll, - .ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, - .fasync = rtc_fasync, -}; - -static struct miscdevice rtc_miscdev = { - .minor = RTC_MINOR, - .name = "rtc", - .fops = &rtc_fops, -}; - - -static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - struct rtc_ops *ops = data; - struct rtc_wkalrm alrm; - struct rtc_time tm; - char *p = page; - - if (rtc_arm_read_time(ops, &tm) == 0) { - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n" - "rtc_epoch\t: %04lu\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - rtc_epoch); - } - - if (rtc_arm_read_alarm(ops, &alrm) == 0) { - p += sprintf(p, "alrm_time\t: "); - if ((unsigned int)alrm.time.tm_hour <= 24) - p += sprintf(p, "%02d:", alrm.time.tm_hour); - else - p += sprintf(p, "**:"); - if ((unsigned int)alrm.time.tm_min <= 59) - p += sprintf(p, "%02d:", alrm.time.tm_min); - else - p += sprintf(p, "**:"); - if ((unsigned int)alrm.time.tm_sec <= 59) - p += sprintf(p, "%02d\n", alrm.time.tm_sec); - else - p += sprintf(p, "**\n"); - - p += sprintf(p, "alrm_date\t: "); - if ((unsigned int)alrm.time.tm_year <= 200) - p += sprintf(p, "%04d-", alrm.time.tm_year + 1900); - else - p += sprintf(p, "****-"); - if ((unsigned int)alrm.time.tm_mon <= 11) - p += sprintf(p, "%02d-", alrm.time.tm_mon + 1); - else - p += sprintf(p, "**-"); - if ((unsigned int)alrm.time.tm_mday <= 31) - p += sprintf(p, "%02d\n", alrm.time.tm_mday); - else - p += sprintf(p, "**\n"); - p += sprintf(p, "alrm_wakeup\t: %s\n", - alrm.enabled ? "yes" : "no"); - p += sprintf(p, "alrm_pending\t: %s\n", - alrm.pending ? "yes" : "no"); - } - - if (ops->proc) - p += ops->proc(p); - - return p - page; -} - -int register_rtc(struct rtc_ops *ops) -{ - int ret = -EBUSY; - - mutex_lock(&rtc_mutex); - if (rtc_ops == NULL) { - rtc_ops = ops; - - ret = misc_register(&rtc_miscdev); - if (ret == 0) - create_proc_read_entry("driver/rtc", 0, NULL, - rtc_read_proc, ops); - } - mutex_unlock(&rtc_mutex); - - return ret; -} -EXPORT_SYMBOL(register_rtc); - -void unregister_rtc(struct rtc_ops *rtc) -{ - mutex_lock(&rtc_mutex); - if (rtc == rtc_ops) { - remove_proc_entry("driver/rtc", NULL); - misc_deregister(&rtc_miscdev); - rtc_ops = NULL; - } - mutex_unlock(&rtc_mutex); -} -EXPORT_SYMBOL(unregister_rtc); diff --git a/include/asm-arm/rtc.h b/include/asm-arm/rtc.h deleted file mode 100644 index 1a5c9232a91..00000000000 --- a/include/asm-arm/rtc.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * linux/include/asm-arm/rtc.h - * - * Copyright (C) 2003 Deep Blue Solutions Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef ASMARM_RTC_H -#define ASMARM_RTC_H - -struct module; - -struct rtc_ops { - struct module *owner; - int (*open)(void); - void (*release)(void); - int (*ioctl)(unsigned int, unsigned long); - - int (*read_time)(struct rtc_time *); - int (*set_time)(struct rtc_time *); - int (*read_alarm)(struct rtc_wkalrm *); - int (*set_alarm)(struct rtc_wkalrm *); - int (*proc)(char *buf); -}; - -void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *); -void rtc_update(unsigned long, unsigned long); -int register_rtc(struct rtc_ops *); -void unregister_rtc(struct rtc_ops *); - -static inline int rtc_periodic_alarm(struct rtc_time *tm) -{ - return (tm->tm_year == -1) || - ((unsigned)tm->tm_mon >= 12) || - ((unsigned)(tm->tm_mday - 1) >= 31) || - ((unsigned)tm->tm_hour > 23) || - ((unsigned)tm->tm_min > 59) || - ((unsigned)tm->tm_sec > 59); -} - -#endif -- cgit v1.2.3-70-g09d2 From 8ff7f2a46bd8831e1f1f2a694ec13921720180b7 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 21 Feb 2008 16:30:10 +0100 Subject: There is no need to have BOOT_PARAMS_SIZE known outside of atags.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit atags.c was the only user of KEXEC_BOOT_PARAMS_SIZE and kexec.h was only included to get that definition. Signed-off-by: Uwe Kleine-König Acked-by: Uli Luckas --- arch/arm/kernel/atags.c | 7 +++---- include/asm-arm/kexec.h | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c index 64c420805e6..56fef9a0550 100644 --- a/arch/arm/kernel/atags.c +++ b/arch/arm/kernel/atags.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -42,14 +41,14 @@ create_proc_entries(void) return 0; } - -static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE]; +#define BOOT_PARAMS_SIZE 1536 +static char __initdata atags_copy_buf[BOOT_PARAMS_SIZE]; static char __initdata *atags_copy; void __init save_atags(const struct tag *tags) { atags_copy = atags_copy_buf; - memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE); + memcpy(atags_copy, tags, sizeof(atags_copy_buf)); } diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h index 47fe34d692d..c8986bb99ed 100644 --- a/include/asm-arm/kexec.h +++ b/include/asm-arm/kexec.h @@ -14,8 +14,6 @@ #define KEXEC_ARCH KEXEC_ARCH_ARM -#define KEXEC_BOOT_PARAMS_SIZE 1536 - #define KEXEC_ARM_ATAGS_OFFSET 0x1000 #define KEXEC_ARM_ZIMAGE_OFFSET 0x8000 -- cgit v1.2.3-70-g09d2 From a4831fbe096a6f4f691fd71b041ce27add54088e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 21 May 2008 10:17:07 +0200 Subject: ns9xxx: fix assembler version of __REG2 to be consistent with the C version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not very critical because __REG2 isn't used in assembler code currently. Additionally some white space noise is fixed. Signed-off-by: Uwe Kleine-König --- include/asm-arm/arch-ns9xxx/hardware.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-ns9xxx/hardware.h b/include/asm-arm/arch-ns9xxx/hardware.h index 0b7b34603f1..0dca11ce21f 100644 --- a/include/asm-arm/arch-ns9xxx/hardware.h +++ b/include/asm-arm/arch-ns9xxx/hardware.h @@ -66,13 +66,13 @@ __REGGET(var, reg ## _ ## field) / __REGSHIFT(reg ## _ ## field) # define REGGETIM_IDX(var, reg, field, idx) \ - __REGGET(var, reg ## _ ## field((idx))) / \ + __REGGET(var, reg ## _ ## field((idx))) / \ __REGSHIFT(reg ## _ ## field((idx))) #else # define __REG(x) io_p2v(x) -# define __REG2(x, y) io_p2v((x) + (y)) +# define __REG2(x, y) io_p2v((x) + 4 * (y)) #endif -- cgit v1.2.3-70-g09d2 From e0773410247f1e5fc6f7c52a4c5f3c6c9873d527 Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sat, 31 May 2008 14:24:02 +0530 Subject: ftrace: export kretprobe_trampoline for function tracer Follow suit from kprobe implementations on other archs and make kretprobe_trampoline non-static. Ftrace implmentation (more specifically, kernel/trace/trace.c) requires access to it (see-> http://kerneltrap.org/mailarchive/linux-kernel/2008/5/27/1955234). Signed-off-by: Abhishek Sagar Signed-off-by: Ingo Molnar --- arch/arm/kernel/kprobes.c | 2 +- include/asm-arm/kprobes.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 5593dd20721..5ee39e10c8d 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -274,7 +274,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, * for kretprobe handlers which should normally be interested in r0 only * anyway. */ -static void __attribute__((naked)) __kprobes kretprobe_trampoline(void) +void __naked __kprobes kretprobe_trampoline(void) { __asm__ __volatile__ ( "stmdb sp!, {r0 - r11} \n\t" diff --git a/include/asm-arm/kprobes.h b/include/asm-arm/kprobes.h index c042194d3ab..b1a37876942 100644 --- a/include/asm-arm/kprobes.h +++ b/include/asm-arm/kprobes.h @@ -59,6 +59,7 @@ struct kprobe_ctlblk { }; void arch_remove_kprobe(struct kprobe *); +void kretprobe_trampoline(void); int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr); int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); -- cgit v1.2.3-70-g09d2 From 1a7e612fa5ea0311232bd5418a40ec7280557789 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 31 May 2008 16:18:11 +0100 Subject: [ARM] 5074/1: fix warning: missing terminating ' character Signed-off-by: Dmitry Baryshkov Acked-by: Richard Purdie Signed-off-by: Russell King --- include/asm-arm/arch-pxa/pxa27x-udc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/pxa27x-udc.h b/include/asm-arm/arch-pxa/pxa27x-udc.h index 9cf0b1f8811..2d4e9cd3a5e 100644 --- a/include/asm-arm/arch-pxa/pxa27x-udc.h +++ b/include/asm-arm/arch-pxa/pxa27x-udc.h @@ -2,7 +2,7 @@ #define _ASM_ARCH_PXA27X_UDC_H #ifdef _ASM_ARCH_PXA25X_UDC_H -#error You can't include both PXA25x and PXA27x UDC support +#error You cannot include both PXA25x and PXA27x UDC support #endif #define UDCCR __REG(0x40600000) /* UDC Control Register */ -- cgit v1.2.3-70-g09d2 From ca0a789ab9c83d8fdf28f5c2700b316cd5dec2f0 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Sat, 24 May 2008 17:47:04 +0100 Subject: [ARM] 5057/1: [AT91] Calao Systems - board files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for three AT91-based boards available from Calao Systems: USB_A9260, USB_A9263 and QIL_A9260. Signed-off-by: Grégory Hermant Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/Kconfig | 21 +++ arch/arm/mach-at91/Makefile | 3 + arch/arm/mach-at91/board-qil-a9260.c | 255 +++++++++++++++++++++++++++++++++++ arch/arm/mach-at91/board-usb-a9260.c | 215 +++++++++++++++++++++++++++++ arch/arm/mach-at91/board-usb-a9263.c | 230 +++++++++++++++++++++++++++++++ include/asm-arm/arch-at91/timex.h | 17 ++- 6 files changed, 740 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-at91/board-qil-a9260.c create mode 100644 arch/arm/mach-at91/board-usb-a9260.c create mode 100644 arch/arm/mach-at91/board-usb-a9263.c (limited to 'include/asm-arm') diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 3d549a9afe1..cae5c67dc31 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -170,6 +170,20 @@ config MACH_SAM9_L9260 Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260. +config MACH_USB_A9260 + bool "CALAO USB-A9260" + depends on ARCH_AT91SAM9260 + help + Select this if you are using a Calao Systems USB-A9260. + + +config MACH_QIL_A9260 + bool "CALAO QIL-A9260 board" + depends on ARCH_AT91SAM9260 + help + Select this if you are using a Calao Systems QIL-A9260 Board. + + endif # ---------------------------------------------------------- @@ -200,6 +214,13 @@ config MACH_AT91SAM9263EK Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit. +config MACH_USB_A9263 + bool "CALAO USB-A9263" + depends on ARCH_AT91SAM9263 + help + Select this if you are using a Calao Systems USB-A9263. + + endif # ---------------------------------------------------------- diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 995be14b2c4..932d17109e8 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -36,12 +36,15 @@ obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o obj-$(CONFIG_MACH_CAM60) += board-cam60.o obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o +obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o +obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o # AT91SAM9261 board-specific support obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o # AT91SAM9263 board-specific support obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o +obj-$(CONFIG_MACH_USB_A9263) += board-usb-a9263.o # AT91SAM9RL board-specific support obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c new file mode 100644 index 00000000000..99b4ec3818d --- /dev/null +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -0,0 +1,255 @@ +/* + * linux/arch/arm/mach-at91/board-qil-a9260.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * Copyright (C) 2007 Calao-systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + + +static void __init ek_map_io(void) +{ + /* Initialize processor: 12.000 MHz crystal */ + at91sam9260_initialize(12000000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ + at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS1 (ie, USART0) */ + at91_set_serial_console(1); + +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if defined(CONFIG_RTC_DRV_M41T94) + { /* M41T94 RTC */ + .modalias = "m41t94", + .chip_select = 0, + .max_speed_hz = 1 * 1000 * 1000, + .bus_num = 0, + } +#endif +}; + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA31, + .is_rmii = 1, +}; + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Uboot & Kernel", + .offset = 0x00000000, + .size = 16 * 1024 * 1024, + }, + { + .name = "Root FS", + .offset = 0x01000000, + .size = 120 * 1024 * 1024, + }, + { + .name = "FS", + .offset = 0x08800000, + .size = 120 * 1024 * 1024, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 0, + .wire4 = 1, +// .det_pin = ... not connected +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { /* USER PUSH BUTTON */ + .code = KEY_ENTER, + .gpio = AT91_PIN_PB10, + .active_low = 1, + .desc = "user_pb", + .wakeup = 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_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */ + at91_set_deglitch(AT91_PIN_PB10, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* user_led (green) */ + .name = "user_led", + .gpio = AT91_PIN_PB21, + .active_low = 0, + .default_trigger = "heartbeat", + } +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mmc(0, &ek_mmc_data); + /* Push Buttons */ + ek_add_device_buttons(); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* shutdown controller, wakeup button (5 msec low) */ + at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW + | AT91_SHDW_RTTWKEN); +} + +MACHINE_START(QIL_A9260, "CALAO QIL_A9260") + /* Maintainer: calao-systems */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c new file mode 100644 index 00000000000..837aedf8ffe --- /dev/null +++ b/arch/arm/mach-at91/board-usb-a9260.c @@ -0,0 +1,215 @@ +/* + * linux/arch/arm/mach-at91/board-usb-a9260.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * Copyright (C) 2007 Calao-systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + + +static void __init ek_map_io(void) +{ + /* Initialize processor: 12.000 MHz crystal */ + at91sam9260_initialize(12000000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA31, + .is_rmii = 1, +}; + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Uboot & Kernel", + .offset = 0x00000000, + .size = 16 * 1024 * 1024, + }, + { + .name = "Root FS", + .offset = 0x01000000, + .size = 120 * 1024 * 1024, + }, + { + .name = "FS", + .offset = 0x08800000, + .size = 120 * 1024 * 1024, + } +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + +/* + * GPIO Buttons + */ + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { /* USER PUSH BUTTON */ + .code = KEY_ENTER, + .gpio = AT91_PIN_PB10, + .active_low = 1, + .desc = "user_pb", + .wakeup = 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_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */ + at91_set_deglitch(AT91_PIN_PB10, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* user_led (green) */ + .name = "user_led", + .gpio = AT91_PIN_PB21, + .active_low = 0, + .default_trigger = "heartbeat", + } +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* Push Buttons */ + ek_add_device_buttons(); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* shutdown controller, wakeup button (5 msec low) */ + at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW + | AT91_SHDW_RTTWKEN); +} + +MACHINE_START(USB_A9260, "CALAO USB_A9260") + /* Maintainer: calao-systems */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c new file mode 100644 index 00000000000..95800d32bd4 --- /dev/null +++ b/arch/arm/mach-at91/board-usb-a9263.c @@ -0,0 +1,230 @@ +/* + * linux/arch/arm/mach-at91/board-usb-a9263.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2007 Atmel Corporation. + * Copyright (C) 2007 Calao-systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + + +static void __init ek_map_io(void) +{ + /* Initialize processor: 12.00 MHz crystal */ + at91sam9263_initialize(12000000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9263_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PB11, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + } +#endif +}; + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PE31, + .is_rmii = 1, +}; + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Linux Kernel", + .offset = 0x00000000, + .size = 16 * 1024 * 1024, + }, + { + .name = "Root FS", + .offset = 0x01000000, + .size = 120 * 1024 * 1024, + }, + { + .name = "FS", + .offset = 0x08800000, + .size = 120 * 1024 * 1024, + } +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PA22, + .enable_pin = AT91_PIN_PD15, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + +/* + * GPIO Buttons + */ +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +static struct gpio_keys_button ek_buttons[] = { + { /* USER PUSH BUTTON */ + .code = KEY_ENTER, + .gpio = AT91_PIN_PB10, + .active_low = 1, + .desc = "user_pb", + .wakeup = 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_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */ + at91_set_deglitch(AT91_PIN_PB10, 1); + + platform_device_register(&ek_button_device); +} +#else +static void __init ek_add_device_buttons(void) {} +#endif + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* user_led (green) */ + .name = "user_led", + .gpio = AT91_PIN_PB21, + .active_low = 1, + .default_trigger = "heartbeat", + } +}; + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* Push Buttons */ + ek_add_device_buttons(); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + /* shutdown controller, wakeup button (5 msec low) */ + at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW + | AT91_SHDW_RTTWKEN); +} + +MACHINE_START(USB_A9263, "CALAO USB_A9263") + /* Maintainer: calao-systems */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/include/asm-arm/arch-at91/timex.h b/include/asm-arm/arch-at91/timex.h index f1933b0fa43..6e084eb839d 100644 --- a/include/asm-arm/arch-at91/timex.h +++ b/include/asm-arm/arch-at91/timex.h @@ -27,14 +27,29 @@ #define CLOCK_TICK_RATE (AT91_SLOW_CLOCK) -#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9261) +#elif defined(CONFIG_ARCH_AT91SAM9260) + +#if defined(CONFIG_MACH_USB_A9260) || defined(CONFIG_MACH_QIL_A9260) +#define AT91SAM9_MASTER_CLOCK 90000000 +#else +#define AT91SAM9_MASTER_CLOCK 99300000 +#endif + +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + +#elif defined(CONFIG_ARCH_AT91SAM9261) #define AT91SAM9_MASTER_CLOCK 99300000 #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) #elif defined(CONFIG_ARCH_AT91SAM9263) +#if defined(CONFIG_MACH_USB_A9263) +#define AT91SAM9_MASTER_CLOCK 90000000 +#else #define AT91SAM9_MASTER_CLOCK 99959500 +#endif + #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) #elif defined(CONFIG_ARCH_AT91SAM9RL) -- cgit v1.2.3-70-g09d2 From 53d7168026a440c4cba25468a3d926ddd7ab030a Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Sat, 5 Apr 2008 21:14:03 +0100 Subject: [ARM] 4933/1: AT91CAP9 UDPHS driver: generic AT91 parts. This is patch 1 of 2 adding support for the USB High Speed Device Port on the AT91CAP9 system on chip. The AT91CAP9 uses the same UDPHS IP as the AVR32 and the AT91SAM9RL. This patch makes the generic AT91 adaptations, mainly dealing with the addition of the UDPHS UTMI clock. Signed-off-by: Stelian Pop Acked-by: Haavard Skinnemoen Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/clock.c | 42 +++++++++++++++++++++++++++++++++++- include/asm-arm/arch-at91/at91_pmc.h | 7 +++++- include/asm-arm/arch-at91/board.h | 4 ++++ 3 files changed, 51 insertions(+), 2 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index a33dfe45072..b87772cd3d3 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -112,12 +112,34 @@ static void pmc_sys_mode(struct clk *clk, int is_on) at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); } +static void pmc_uckr_mode(struct clk *clk, int is_on) +{ + unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); + + if (is_on) { + is_on = AT91_PMC_LOCKU; + at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); + } else + at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask)); + + do { + cpu_relax(); + } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on); +} + /* USB function clocks (PLLB must be 48 MHz) */ static struct clk udpck = { .name = "udpck", .parent = &pllb, .mode = pmc_sys_mode, }; +static struct clk utmi_clk = { + .name = "utmi_clk", + .parent = &main_clk, + .pmc_mask = AT91_PMC_UPLLEN, /* in CKGR_UCKR */ + .mode = pmc_uckr_mode, + .type = CLK_TYPE_PLL, +}; static struct clk uhpck = { .name = "uhpck", .parent = &pllb, @@ -361,7 +383,7 @@ static void __init init_programmable_clock(struct clk *clk) static int at91_clk_show(struct seq_file *s, void *unused) { - u32 scsr, pcsr, sr; + u32 scsr, pcsr, uckr = 0, sr; struct clk *clk; seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); @@ -370,6 +392,8 @@ static int at91_clk_show(struct seq_file *s, void *unused) seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); + if (cpu_is_at91cap9()) + seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); @@ -382,6 +406,8 @@ static int at91_clk_show(struct seq_file *s, void *unused) state = (scsr & clk->pmc_mask) ? "on" : "off"; else if (clk->mode == pmc_periph_mode) state = (pcsr & clk->pmc_mask) ? "on" : "off"; + else if (clk->mode == pmc_uckr_mode) + state = (uckr & clk->pmc_mask) ? "on" : "off"; else if (clk->pmc_mask) state = (sr & clk->pmc_mask) ? "on" : "off"; else if (clk == &clk32k || clk == &main_clk) @@ -581,6 +607,17 @@ int __init at91_clock_init(unsigned long main_clock) udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); + /* + * USB HS clock init + */ + if (cpu_is_at91cap9()) { + /* + * multiplier is hard-wired to 40 + * (obtain the USB High Speed 480 MHz when input is 12 MHz) + */ + utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; + } + /* * MCK and CPU derive from one of those primary clocks. * For now, assume this parentage won't change. @@ -598,6 +635,9 @@ int __init at91_clock_init(unsigned long main_clock) for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) list_add_tail(&standard_pmc_clocks[i]->node, &clocks); + if (cpu_is_at91cap9()) + list_add_tail(&utmi_clk.node, &clocks); + /* MCK and CPU clock are "always on" */ clk_enable(&mck); diff --git a/include/asm-arm/arch-at91/at91_pmc.h b/include/asm-arm/arch-at91/at91_pmc.h index c2b13c28015..2001e81f226 100644 --- a/include/asm-arm/arch-at91/at91_pmc.h +++ b/include/asm-arm/arch-at91/at91_pmc.h @@ -39,10 +39,14 @@ #define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */ #define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [SAM9RL, CAP9] */ +#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */ +#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */ +#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */ +#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI PLL Start-up Time */ #define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ #define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ -#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [AT91SAM926x only] */ +#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x, CAP9] */ #define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ #define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */ @@ -97,6 +101,7 @@ #define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */ #define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */ #define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */ +#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [AT91CAP9 only] */ #define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */ #define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ #define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h index dc189f01c5b..1f247028686 100644 --- a/include/asm-arm/arch-at91/board.h +++ b/include/asm-arm/arch-at91/board.h @@ -36,6 +36,7 @@ #include #include #include +#include /* USB Device */ struct at91_udc_data { @@ -45,6 +46,9 @@ struct at91_udc_data { }; extern void __init at91_add_device_udc(struct at91_udc_data *data); + /* USB High Speed Device */ +extern void __init at91_add_device_usba(struct usba_platform_data *data); + /* Compact Flash */ struct at91_cf_data { u8 irq_pin; /* I/O IRQ */ -- cgit v1.2.3-70-g09d2 From 7c8cf66529ebf95f1a5f34d1b69504d442b42630 Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Sat, 5 Apr 2008 21:15:25 +0100 Subject: [ARM] 4934/1: AT91CAP9 UDPHS driver: board and cpu integration. This is patch 2 of 2 adding support for the USB High Speed Device Port on the AT91CAP9 system on chip. The AT91CAP9 uses the same UDPHS IP as the AVR32 and the AT91SAM9RL. This patch declares the UDPHS ressources in the at91cap9 (cpu and adk board) files, wires up the atmel_usba_udc driver to them, and activates the driver in the defconfig. Signed-off-by: Stelian Pop Acked-by: Haavard Skinnemoen Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/configs/at91cap9adk_defconfig | 27 +++++++- arch/arm/mach-at91/at91cap9_devices.c | 99 +++++++++++++++++++++++++++++ arch/arm/mach-at91/board-cap9adk.c | 9 +++ include/asm-arm/arch-at91/at91cap9.h | 2 +- include/asm-arm/arch-at91/at91cap9_matrix.h | 5 ++ 5 files changed, 140 insertions(+), 2 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig index e32e7364812..39ca662c079 100644 --- a/arch/arm/configs/at91cap9adk_defconfig +++ b/arch/arm/configs/at91cap9adk_defconfig @@ -907,7 +907,32 @@ CONFIG_USB_MON=y # # USB Gadget Support # -# CONFIG_USB_GADGET is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AMD5536UDC is not set +CONFIG_USB_GADGET_ATMEL_USBA=y +CONFIG_USB_ATMEL_USBA=y +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # CONFIG_MMC_UNSAFE_RESUME is not set diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index be526746e01..747b9dedab8 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -83,6 +83,105 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} #endif +/* -------------------------------------------------------------------- + * USB HS Device (Gadget) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE) + +static struct resource usba_udc_resources[] = { + [0] = { + .start = AT91CAP9_UDPHS_FIFO, + .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91CAP9_BASE_UDPHS, + .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AT91CAP9_ID_UDPHS, + .end = AT91CAP9_ID_UDPHS, + .flags = IORESOURCE_IRQ, + }, +}; + +#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ + [idx] = { \ + .name = nam, \ + .index = idx, \ + .fifo_size = maxpkt, \ + .nr_banks = maxbk, \ + .can_dma = dma, \ + .can_isoc = isoc, \ + } + +static struct usba_ep_data usba_udc_ep[] = { + EP("ep0", 0, 64, 1, 0, 0), + EP("ep1", 1, 1024, 3, 1, 1), + EP("ep2", 2, 1024, 3, 1, 1), + EP("ep3", 3, 1024, 2, 1, 1), + EP("ep4", 4, 1024, 2, 1, 1), + EP("ep5", 5, 1024, 2, 1, 0), + EP("ep6", 6, 1024, 2, 1, 0), + EP("ep7", 7, 1024, 2, 0, 0), +}; + +#undef EP + +/* + * pdata doesn't have room for any endpoints, so we need to + * append room for the ones we need right after it. + */ +static struct { + struct usba_platform_data pdata; + struct usba_ep_data ep[8]; +} usba_udc_data; + +static struct platform_device at91_usba_udc_device = { + .name = "atmel_usba_udc", + .id = -1, + .dev = { + .platform_data = &usba_udc_data.pdata, + }, + .resource = usba_udc_resources, + .num_resources = ARRAY_SIZE(usba_udc_resources), +}; + +void __init at91_add_device_usba(struct usba_platform_data *data) +{ + at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS | + AT91_MATRIX_UDPHS_BYPASS_LOCK); + + /* + * Invalid pins are 0 on AT91, but the usba driver is shared + * with AVR32, which use negative values instead. Once/if + * gpio_is_valid() is ported to AT91, revisit this code. + */ + usba_udc_data.pdata.vbus_pin = -EINVAL; + usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); + memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));; + + if (data && data->vbus_pin > 0) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + usba_udc_data.pdata.vbus_pin = data->vbus_pin; + } + + /* Pullup pin is handled internally by USB device peripheral */ + + /* Clocks */ + at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk"); + at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk"); + + platform_device_register(&at91_usba_udc_device); +} +#else +void __init at91_add_device_usba(struct usba_platform_data *data) {} +#endif + + /* -------------------------------------------------------------------- * Ethernet * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index e5512d1ff21..8a2a958639d 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -78,6 +78,12 @@ static struct at91_usbh_data __initdata cap9adk_usbh_data = { .ports = 2, }; +/* + * USB HS Device port + */ +static struct usba_platform_data __initdata cap9adk_usba_udc_data = { + .vbus_pin = AT91_PIN_PB31, +}; /* * ADS7846 Touchscreen @@ -326,6 +332,9 @@ static void __init cap9adk_board_init(void) /* USB Host */ set_irq_type(AT91CAP9_ID_UHP, IRQT_HIGH); at91_add_device_usbh(&cap9adk_usbh_data); + /* USB HS */ + set_irq_type(AT91CAP9_ID_UDPHS, IRQT_HIGH); + at91_add_device_usba(&cap9adk_usba_udc_data); /* SPI */ at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices)); /* Touchscreen */ diff --git a/include/asm-arm/arch-at91/at91cap9.h b/include/asm-arm/arch-at91/at91cap9.h index bac83adb505..6f14d9053ac 100644 --- a/include/asm-arm/arch-at91/at91cap9.h +++ b/include/asm-arm/arch-at91/at91cap9.h @@ -118,7 +118,7 @@ #define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */ #define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */ -#define AT91CAP9_UDPHS_BASE 0x00600000 /* USB High Speed Device Port */ +#define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */ #define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */ #define CONFIG_DRAM_BASE AT91_CHIPSELECT_6 diff --git a/include/asm-arm/arch-at91/at91cap9_matrix.h b/include/asm-arm/arch-at91/at91cap9_matrix.h index a641686b6c3..ddbd4873c84 100644 --- a/include/asm-arm/arch-at91/at91cap9_matrix.h +++ b/include/asm-arm/arch-at91/at91cap9_matrix.h @@ -106,6 +106,11 @@ #define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */ #define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */ +#define AT91_MATRIX_UDPHS (AT91_MATRIX + 0x118) /* USBHS Special Function Register [AT91CAP9 only] */ +#define AT91_MATRIX_SELECT_UDPHS (0 << 31) /* select High Speed UDP */ +#define AT91_MATRIX_SELECT_UDP (1 << 31) /* select standard UDP */ +#define AT91_MATRIX_UDPHS_BYPASS_LOCK (1 << 30) /* bypass lock bit */ + #define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ #define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ #define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) -- cgit v1.2.3-70-g09d2 From ba45ca435060614e595a107ac323a36b52619d7d Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Tue, 8 Apr 2008 13:59:18 +0100 Subject: [ARM] 4940/1: AT91: UDPHS driver: SAM9RL board and cpu integration. Adds support for the USB High Speed Device Port on the AT91SAM9RL system on chip. The AT91SAM9RL uses the same UDPHS IP as the AVR32 and the AT91CAP9 (atmel_usba_udc driver). Signed-off-by: Nicolas Ferre Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/at91sam9rl_devices.c | 95 +++++++++++++++++++++++++++++++++ arch/arm/mach-at91/board-sam9rlek.c | 10 ++++ arch/arm/mach-at91/clock.c | 9 ++-- drivers/usb/gadget/Kconfig | 4 +- include/asm-arm/arch-at91/at91sam9rl.h | 2 +- 5 files changed, 113 insertions(+), 7 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 450db304936..8507dd02fe9 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -25,6 +25,101 @@ #include "generic.h" +/* -------------------------------------------------------------------- + * USB HS Device (Gadget) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE) + +static struct resource usba_udc_resources[] = { + [0] = { + .start = AT91SAM9RL_UDPHS_FIFO, + .end = AT91SAM9RL_UDPHS_FIFO + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_BASE_UDPHS, + .end = AT91SAM9RL_BASE_UDPHS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AT91SAM9RL_ID_UDPHS, + .end = AT91SAM9RL_ID_UDPHS, + .flags = IORESOURCE_IRQ, + }, +}; + +#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ + [idx] = { \ + .name = nam, \ + .index = idx, \ + .fifo_size = maxpkt, \ + .nr_banks = maxbk, \ + .can_dma = dma, \ + .can_isoc = isoc, \ + } + +static struct usba_ep_data usba_udc_ep[] __initdata = { + EP("ep0", 0, 64, 1, 0, 0), + EP("ep1", 1, 1024, 2, 1, 1), + EP("ep2", 2, 1024, 2, 1, 1), + EP("ep3", 3, 1024, 3, 1, 0), + EP("ep4", 4, 1024, 3, 1, 0), + EP("ep5", 5, 1024, 3, 1, 1), + EP("ep6", 6, 1024, 3, 1, 1), +}; + +#undef EP + +/* + * pdata doesn't have room for any endpoints, so we need to + * append room for the ones we need right after it. + */ +static struct { + struct usba_platform_data pdata; + struct usba_ep_data ep[7]; +} usba_udc_data; + +static struct platform_device at91_usba_udc_device = { + .name = "atmel_usba_udc", + .id = -1, + .dev = { + .platform_data = &usba_udc_data.pdata, + }, + .resource = usba_udc_resources, + .num_resources = ARRAY_SIZE(usba_udc_resources), +}; + +void __init at91_add_device_usba(struct usba_platform_data *data) +{ + /* + * Invalid pins are 0 on AT91, but the usba driver is shared + * with AVR32, which use negative values instead. Once/if + * gpio_is_valid() is ported to AT91, revisit this code. + */ + usba_udc_data.pdata.vbus_pin = -EINVAL; + usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); + memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));; + + if (data && data->vbus_pin > 0) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + usba_udc_data.pdata.vbus_pin = data->vbus_pin; + } + + /* Pullup pin is handled internally by USB device peripheral */ + + /* Clocks */ + at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk"); + at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk"); + + platform_device_register(&at91_usba_udc_device); +} +#else +void __init at91_add_device_usba(struct usba_platform_data *data) {} +#endif + + /* -------------------------------------------------------------------- * MMC / SD * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index ffc0597aee8..b6a70fc735c 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -55,6 +55,14 @@ static void __init ek_init_irq(void) } +/* + * USB HS Device port + */ +static struct usba_platform_data __initdata ek_usba_udc_data = { + .vbus_pin = AT91_PIN_PA8, +}; + + /* * MCI (SD/MMC) */ @@ -175,6 +183,8 @@ static void __init ek_board_init(void) { /* Serial */ at91_add_device_serial(); + /* USB HS */ + at91_add_device_usba(&ek_usba_udc_data); /* I2C */ at91_add_device_i2c(NULL, 0); /* NAND */ diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index b87772cd3d3..e8ce8f0f3ed 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -391,8 +391,9 @@ static int at91_clk_show(struct seq_file *s, void *unused) seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); - seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); - if (cpu_is_at91cap9()) + if (!cpu_is_at91sam9rl()) + seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); + if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); @@ -610,7 +611,7 @@ int __init at91_clock_init(unsigned long main_clock) /* * USB HS clock init */ - if (cpu_is_at91cap9()) { + if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) { /* * multiplier is hard-wired to 40 * (obtain the USB High Speed 480 MHz when input is 12 MHz) @@ -635,7 +636,7 @@ int __init at91_clock_init(unsigned long main_clock) for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) list_add_tail(&standard_pmc_clocks[i]->node, &clocks); - if (cpu_is_at91cap9()) + if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) list_add_tail(&utmi_clk.node, &clocks); /* MCK and CPU clock are "always on" */ diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 6e784d2db42..3565d435282 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -118,10 +118,10 @@ config USB_AMD5536UDC config USB_GADGET_ATMEL_USBA boolean "Atmel USBA" select USB_GADGET_DUALSPEED - depends on AVR32 || ARCH_AT91CAP9 + depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL help USBA is the integrated high-speed USB Device controller on - the AT32AP700x and AT91CAP9 processors from Atmel. + the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. config USB_ATMEL_USBA tristate diff --git a/include/asm-arm/arch-at91/at91sam9rl.h b/include/asm-arm/arch-at91/at91sam9rl.h index 16d2832f6c0..622e56f81d4 100644 --- a/include/asm-arm/arch-at91/at91sam9rl.h +++ b/include/asm-arm/arch-at91/at91sam9rl.h @@ -110,6 +110,6 @@ #define AT91SAM9RL_ROM_SIZE (2 * SZ_16K) /* Internal ROM size (32Kb) */ #define AT91SAM9RL_LCDC_BASE 0x00500000 /* LCD Controller */ -#define AT91SAM9RL_UDPHS_BASE 0x00600000 /* USB Device HS controller */ +#define AT91SAM9RL_UDPHS_FIFO 0x00600000 /* USB Device HS controller */ #endif -- cgit v1.2.3-70-g09d2 From 0b0a9df6038752674e54e333cd247c877d29aab8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 May 2008 14:59:36 +0100 Subject: [ARM] pxa: separate out power manager and clock registers The power manager and core clock registers aren't present in PXA3 CPUs. Move them out of pxa-regs.h into pxa2xx-regs.h, and include pxa2xx-regs.h where necessary. Signed-off-by: Russell King --- arch/arm/common/sharpsl_pm.c | 1 + arch/arm/mach-pxa/clock.c | 2 +- arch/arm/mach-pxa/corgi.c | 1 + arch/arm/mach-pxa/corgi_pm.c | 1 + arch/arm/mach-pxa/generic.c | 1 + arch/arm/mach-pxa/magician.c | 1 + arch/arm/mach-pxa/mfp-pxa2xx.c | 1 + arch/arm/mach-pxa/poodle.c | 1 + arch/arm/mach-pxa/pxa25x.c | 1 + arch/arm/mach-pxa/standby.S | 1 + arch/arm/mach-pxa/trizeps4.c | 2 + include/asm-arm/arch-pxa/pxa-regs.h | 158 +------------------------------- include/asm-arm/arch-pxa/pxa2xx-regs.h | 162 +++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/system.h | 1 + 14 files changed, 177 insertions(+), 157 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 5736c987c80..8822b684d47 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index e97dc59813c..180c8bb5304 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index b757dd75665..b37671b7188 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index ae91c4b1135..53c4499ebdb 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "sharpsl.h" diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 44617938f3f..c2f102339f5 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -26,6 +26,7 @@ #include #include +#include /* for __pxa_set_cken */ #include "generic.h" diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index badba064dc0..b94cae48314 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index 22097a1707c..d1cdb4ecb0b 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -20,6 +20,7 @@ #include #include +#include #include #include "generic.h" diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 0b30f25cff3..f81c10cafd4 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e5b417d14bb..3b848dc3ca1 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S index a37ef1c4b9e..40bb70eff3f 100644 --- a/arch/arm/mach-pxa/standby.S +++ b/arch/arm/mach-pxa/standby.S @@ -14,6 +14,7 @@ #include #include +#include .text diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 931885d86b9..bc7c465ef32 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -487,6 +488,7 @@ static void __init trizeps4_map_io(void) ConXS_BCR = trizeps_conxs_bcr; #endif +#warning FIXME - accessing PM registers directly is deprecated PWER = 0x00000002; PFER = 0x00000000; PRER = 0x00000002; diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 68d74287730..dce9308626b 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -825,120 +825,9 @@ #endif /* - * Power Manager + * Power Manager - see pxa2xx-regs.h */ -#define PMCR __REG(0x40F00000) /* Power Manager Control Register */ -#define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */ -#define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */ -#define PWER __REG(0x40F0000C) /* Power Manager Wake-up Enable Register */ -#define PRER __REG(0x40F00010) /* Power Manager GPIO Rising-Edge Detect Enable Register */ -#define PFER __REG(0x40F00014) /* Power Manager GPIO Falling-Edge Detect Enable Register */ -#define PEDR __REG(0x40F00018) /* Power Manager GPIO Edge Detect Status Register */ -#define PCFR __REG(0x40F0001C) /* Power Manager General Configuration Register */ -#define PGSR0 __REG(0x40F00020) /* Power Manager GPIO Sleep State Register for GP[31-0] */ -#define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */ -#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */ -#define PGSR3 __REG(0x40F0002C) /* Power Manager GPIO Sleep State Register for GP[118-96] */ -#define RCSR __REG(0x40F00030) /* Reset Controller Status Register */ - -#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */ -#define PSTR __REG(0x40F00038) /*Power Manager Standby Config Register */ -#define PSNR __REG(0x40F0003C) /*Power Manager Sense Config Register */ -#define PVCR __REG(0x40F00040) /*Power Manager VoltageControl Register */ -#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */ -#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */ -#define PCMD(x) __REG2(0x40F00080, (x)<<2) -#define PCMD0 __REG(0x40F00080 + 0 * 4) -#define PCMD1 __REG(0x40F00080 + 1 * 4) -#define PCMD2 __REG(0x40F00080 + 2 * 4) -#define PCMD3 __REG(0x40F00080 + 3 * 4) -#define PCMD4 __REG(0x40F00080 + 4 * 4) -#define PCMD5 __REG(0x40F00080 + 5 * 4) -#define PCMD6 __REG(0x40F00080 + 6 * 4) -#define PCMD7 __REG(0x40F00080 + 7 * 4) -#define PCMD8 __REG(0x40F00080 + 8 * 4) -#define PCMD9 __REG(0x40F00080 + 9 * 4) -#define PCMD10 __REG(0x40F00080 + 10 * 4) -#define PCMD11 __REG(0x40F00080 + 11 * 4) -#define PCMD12 __REG(0x40F00080 + 12 * 4) -#define PCMD13 __REG(0x40F00080 + 13 * 4) -#define PCMD14 __REG(0x40F00080 + 14 * 4) -#define PCMD15 __REG(0x40F00080 + 15 * 4) -#define PCMD16 __REG(0x40F00080 + 16 * 4) -#define PCMD17 __REG(0x40F00080 + 17 * 4) -#define PCMD18 __REG(0x40F00080 + 18 * 4) -#define PCMD19 __REG(0x40F00080 + 19 * 4) -#define PCMD20 __REG(0x40F00080 + 20 * 4) -#define PCMD21 __REG(0x40F00080 + 21 * 4) -#define PCMD22 __REG(0x40F00080 + 22 * 4) -#define PCMD23 __REG(0x40F00080 + 23 * 4) -#define PCMD24 __REG(0x40F00080 + 24 * 4) -#define PCMD25 __REG(0x40F00080 + 25 * 4) -#define PCMD26 __REG(0x40F00080 + 26 * 4) -#define PCMD27 __REG(0x40F00080 + 27 * 4) -#define PCMD28 __REG(0x40F00080 + 28 * 4) -#define PCMD29 __REG(0x40F00080 + 29 * 4) -#define PCMD30 __REG(0x40F00080 + 30 * 4) -#define PCMD31 __REG(0x40F00080 + 31 * 4) - -#define PCMD_MBC (1<<12) -#define PCMD_DCE (1<<11) -#define PCMD_LC (1<<10) -/* FIXME: PCMD_SQC need be checked. */ -#define PCMD_SQC (3<<8) /* currently only bit 8 is changeable, - bit 9 should be 0 all day. */ -#define PVCR_VCSA (0x1<<14) -#define PVCR_CommandDelay (0xf80) -#define PCFR_PI2C_EN (0x1 << 6) - -#define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */ -#define PSSR_RDH (1 << 5) /* Read Disable Hold */ -#define PSSR_PH (1 << 4) /* Peripheral Control Hold */ -#define PSSR_STS (1 << 3) /* Standby Mode Status */ -#define PSSR_VFS (1 << 2) /* VDD Fault Status */ -#define PSSR_BFS (1 << 1) /* Battery Fault Status */ -#define PSSR_SSS (1 << 0) /* Software Sleep Status */ - -#define PSLR_SL_ROD (1 << 20) /* Sleep-Mode/Depp-Sleep Mode nRESET_OUT Disable */ - -#define PCFR_RO (1 << 15) /* RDH Override */ -#define PCFR_PO (1 << 14) /* PH Override */ -#define PCFR_GPROD (1 << 12) /* GPIO nRESET_OUT Disable */ -#define PCFR_L1_EN (1 << 11) /* Sleep Mode L1 converter Enable */ -#define PCFR_FVC (1 << 10) /* Frequency/Voltage Change */ -#define PCFR_DC_EN (1 << 7) /* Sleep/deep-sleep DC-DC Converter Enable */ -#define PCFR_PI2CEN (1 << 6) /* Enable PI2C controller */ -#define PCFR_GPR_EN (1 << 4) /* nRESET_GPIO Pin Enable */ -#define PCFR_DS (1 << 3) /* Deep Sleep Mode */ -#define PCFR_FS (1 << 2) /* Float Static Chip Selects */ -#define PCFR_FP (1 << 1) /* Float PCMCIA controls */ -#define PCFR_OPDE (1 << 0) /* 3.6864 MHz oscillator power-down enable */ - -#define RCSR_GPR (1 << 3) /* GPIO Reset */ -#define RCSR_SMR (1 << 2) /* Sleep Mode */ -#define RCSR_WDR (1 << 1) /* Watchdog Reset */ -#define RCSR_HWR (1 << 0) /* Hardware Reset */ - -#define PWER_GPIO(Nb) (1 << Nb) /* GPIO [0..15] wake-up enable */ -#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */ -#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */ -#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */ -#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */ -#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */ -#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */ -#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */ -#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */ -#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */ -#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */ -#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */ -#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */ -#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */ -#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */ -#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */ -#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */ -#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */ - /* * SSP Serial Port Registers - see include/asm-arm/arch-pxa/regs-ssp.h */ @@ -948,52 +837,9 @@ */ /* - * Core Clock + * Core Clock - see include/asm-arm/arch-pxa/pxa2xx-regs.h */ -#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ -#define CKEN __REG(0x41300004) /* Clock Enable Register */ -#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ -#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ - -#define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ -#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ -#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */ - -#define CKEN_AC97CONF (31) /* AC97 Controller Configuration */ -#define CKEN_CAMERA (24) /* Camera Interface Clock Enable */ -#define CKEN_SSP1 (23) /* SSP1 Unit Clock Enable */ -#define CKEN_MEMC (22) /* Memory Controller Clock Enable */ -#define CKEN_MEMSTK (21) /* Memory Stick Host Controller */ -#define CKEN_IM (20) /* Internal Memory Clock Enable */ -#define CKEN_KEYPAD (19) /* Keypad Interface Clock Enable */ -#define CKEN_USIM (18) /* USIM Unit Clock Enable */ -#define CKEN_MSL (17) /* MSL Unit Clock Enable */ -#define CKEN_LCD (16) /* LCD Unit Clock Enable */ -#define CKEN_PWRI2C (15) /* PWR I2C Unit Clock Enable */ -#define CKEN_I2C (14) /* I2C Unit Clock Enable */ -#define CKEN_FICP (13) /* FICP Unit Clock Enable */ -#define CKEN_MMC (12) /* MMC Unit Clock Enable */ -#define CKEN_USB (11) /* USB Unit Clock Enable */ -#define CKEN_ASSP (10) /* ASSP (SSP3) Clock Enable */ -#define CKEN_USBHOST (10) /* USB Host Unit Clock Enable */ -#define CKEN_OSTIMER (9) /* OS Timer Unit Clock Enable */ -#define CKEN_NSSP (9) /* NSSP (SSP2) Clock Enable */ -#define CKEN_I2S (8) /* I2S Unit Clock Enable */ -#define CKEN_BTUART (7) /* BTUART Unit Clock Enable */ -#define CKEN_FFUART (6) /* FFUART Unit Clock Enable */ -#define CKEN_STUART (5) /* STUART Unit Clock Enable */ -#define CKEN_HWUART (4) /* HWUART Unit Clock Enable */ -#define CKEN_SSP3 (4) /* SSP3 Unit Clock Enable */ -#define CKEN_SSP (3) /* SSP Unit Clock Enable */ -#define CKEN_SSP2 (3) /* SSP2 Unit Clock Enable */ -#define CKEN_AC97 (2) /* AC97 Unit Clock Enable */ -#define CKEN_PWM1 (1) /* PWM1 Clock Enable */ -#define CKEN_PWM0 (0) /* PWM0 Clock Enable */ - -#define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */ -#define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */ - #ifdef CONFIG_PXA27x /* Camera Interface */ diff --git a/include/asm-arm/arch-pxa/pxa2xx-regs.h b/include/asm-arm/arch-pxa/pxa2xx-regs.h index 9553b54fa5b..73e0a329cf7 100644 --- a/include/asm-arm/arch-pxa/pxa2xx-regs.h +++ b/include/asm-arm/arch-pxa/pxa2xx-regs.h @@ -81,4 +81,166 @@ #endif + +/* + * Power Manager + */ + +#define PMCR __REG(0x40F00000) /* Power Manager Control Register */ +#define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */ +#define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */ +#define PWER __REG(0x40F0000C) /* Power Manager Wake-up Enable Register */ +#define PRER __REG(0x40F00010) /* Power Manager GPIO Rising-Edge Detect Enable Register */ +#define PFER __REG(0x40F00014) /* Power Manager GPIO Falling-Edge Detect Enable Register */ +#define PEDR __REG(0x40F00018) /* Power Manager GPIO Edge Detect Status Register */ +#define PCFR __REG(0x40F0001C) /* Power Manager General Configuration Register */ +#define PGSR0 __REG(0x40F00020) /* Power Manager GPIO Sleep State Register for GP[31-0] */ +#define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */ +#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */ +#define PGSR3 __REG(0x40F0002C) /* Power Manager GPIO Sleep State Register for GP[118-96] */ +#define RCSR __REG(0x40F00030) /* Reset Controller Status Register */ + +#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */ +#define PSTR __REG(0x40F00038) /* Power Manager Standby Config Register */ +#define PSNR __REG(0x40F0003C) /* Power Manager Sense Config Register */ +#define PVCR __REG(0x40F00040) /* Power Manager VoltageControl Register */ +#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */ +#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */ +#define PCMD(x) __REG2(0x40F00080, (x)<<2) +#define PCMD0 __REG(0x40F00080 + 0 * 4) +#define PCMD1 __REG(0x40F00080 + 1 * 4) +#define PCMD2 __REG(0x40F00080 + 2 * 4) +#define PCMD3 __REG(0x40F00080 + 3 * 4) +#define PCMD4 __REG(0x40F00080 + 4 * 4) +#define PCMD5 __REG(0x40F00080 + 5 * 4) +#define PCMD6 __REG(0x40F00080 + 6 * 4) +#define PCMD7 __REG(0x40F00080 + 7 * 4) +#define PCMD8 __REG(0x40F00080 + 8 * 4) +#define PCMD9 __REG(0x40F00080 + 9 * 4) +#define PCMD10 __REG(0x40F00080 + 10 * 4) +#define PCMD11 __REG(0x40F00080 + 11 * 4) +#define PCMD12 __REG(0x40F00080 + 12 * 4) +#define PCMD13 __REG(0x40F00080 + 13 * 4) +#define PCMD14 __REG(0x40F00080 + 14 * 4) +#define PCMD15 __REG(0x40F00080 + 15 * 4) +#define PCMD16 __REG(0x40F00080 + 16 * 4) +#define PCMD17 __REG(0x40F00080 + 17 * 4) +#define PCMD18 __REG(0x40F00080 + 18 * 4) +#define PCMD19 __REG(0x40F00080 + 19 * 4) +#define PCMD20 __REG(0x40F00080 + 20 * 4) +#define PCMD21 __REG(0x40F00080 + 21 * 4) +#define PCMD22 __REG(0x40F00080 + 22 * 4) +#define PCMD23 __REG(0x40F00080 + 23 * 4) +#define PCMD24 __REG(0x40F00080 + 24 * 4) +#define PCMD25 __REG(0x40F00080 + 25 * 4) +#define PCMD26 __REG(0x40F00080 + 26 * 4) +#define PCMD27 __REG(0x40F00080 + 27 * 4) +#define PCMD28 __REG(0x40F00080 + 28 * 4) +#define PCMD29 __REG(0x40F00080 + 29 * 4) +#define PCMD30 __REG(0x40F00080 + 30 * 4) +#define PCMD31 __REG(0x40F00080 + 31 * 4) + +#define PCMD_MBC (1<<12) +#define PCMD_DCE (1<<11) +#define PCMD_LC (1<<10) +/* FIXME: PCMD_SQC need be checked. */ +#define PCMD_SQC (3<<8) /* currently only bit 8 is changeable, + bit 9 should be 0 all day. */ +#define PVCR_VCSA (0x1<<14) +#define PVCR_CommandDelay (0xf80) +#define PCFR_PI2C_EN (0x1 << 6) + +#define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */ +#define PSSR_RDH (1 << 5) /* Read Disable Hold */ +#define PSSR_PH (1 << 4) /* Peripheral Control Hold */ +#define PSSR_STS (1 << 3) /* Standby Mode Status */ +#define PSSR_VFS (1 << 2) /* VDD Fault Status */ +#define PSSR_BFS (1 << 1) /* Battery Fault Status */ +#define PSSR_SSS (1 << 0) /* Software Sleep Status */ + +#define PSLR_SL_ROD (1 << 20) /* Sleep-Mode/Depp-Sleep Mode nRESET_OUT Disable */ + +#define PCFR_RO (1 << 15) /* RDH Override */ +#define PCFR_PO (1 << 14) /* PH Override */ +#define PCFR_GPROD (1 << 12) /* GPIO nRESET_OUT Disable */ +#define PCFR_L1_EN (1 << 11) /* Sleep Mode L1 converter Enable */ +#define PCFR_FVC (1 << 10) /* Frequency/Voltage Change */ +#define PCFR_DC_EN (1 << 7) /* Sleep/deep-sleep DC-DC Converter Enable */ +#define PCFR_PI2CEN (1 << 6) /* Enable PI2C controller */ +#define PCFR_GPR_EN (1 << 4) /* nRESET_GPIO Pin Enable */ +#define PCFR_DS (1 << 3) /* Deep Sleep Mode */ +#define PCFR_FS (1 << 2) /* Float Static Chip Selects */ +#define PCFR_FP (1 << 1) /* Float PCMCIA controls */ +#define PCFR_OPDE (1 << 0) /* 3.6864 MHz oscillator power-down enable */ + +#define RCSR_GPR (1 << 3) /* GPIO Reset */ +#define RCSR_SMR (1 << 2) /* Sleep Mode */ +#define RCSR_WDR (1 << 1) /* Watchdog Reset */ +#define RCSR_HWR (1 << 0) /* Hardware Reset */ + +#define PWER_GPIO(Nb) (1 << Nb) /* GPIO [0..15] wake-up enable */ +#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */ +#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */ +#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */ +#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */ +#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */ +#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */ +#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */ +#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */ +#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */ +#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */ +#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */ +#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */ +#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */ +#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */ +#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */ +#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */ +#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */ + +/* + * PXA2xx specific Core clock definitions + */ +#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ +#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ +#define CKEN __REG(0x41300004) /* Clock Enable Register */ +#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ + +#define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ +#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ +#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */ + +#define CKEN_AC97CONF (31) /* AC97 Controller Configuration */ +#define CKEN_CAMERA (24) /* Camera Interface Clock Enable */ +#define CKEN_SSP1 (23) /* SSP1 Unit Clock Enable */ +#define CKEN_MEMC (22) /* Memory Controller Clock Enable */ +#define CKEN_MEMSTK (21) /* Memory Stick Host Controller */ +#define CKEN_IM (20) /* Internal Memory Clock Enable */ +#define CKEN_KEYPAD (19) /* Keypad Interface Clock Enable */ +#define CKEN_USIM (18) /* USIM Unit Clock Enable */ +#define CKEN_MSL (17) /* MSL Unit Clock Enable */ +#define CKEN_LCD (16) /* LCD Unit Clock Enable */ +#define CKEN_PWRI2C (15) /* PWR I2C Unit Clock Enable */ +#define CKEN_I2C (14) /* I2C Unit Clock Enable */ +#define CKEN_FICP (13) /* FICP Unit Clock Enable */ +#define CKEN_MMC (12) /* MMC Unit Clock Enable */ +#define CKEN_USB (11) /* USB Unit Clock Enable */ +#define CKEN_ASSP (10) /* ASSP (SSP3) Clock Enable */ +#define CKEN_USBHOST (10) /* USB Host Unit Clock Enable */ +#define CKEN_OSTIMER (9) /* OS Timer Unit Clock Enable */ +#define CKEN_NSSP (9) /* NSSP (SSP2) Clock Enable */ +#define CKEN_I2S (8) /* I2S Unit Clock Enable */ +#define CKEN_BTUART (7) /* BTUART Unit Clock Enable */ +#define CKEN_FFUART (6) /* FFUART Unit Clock Enable */ +#define CKEN_STUART (5) /* STUART Unit Clock Enable */ +#define CKEN_HWUART (4) /* HWUART Unit Clock Enable */ +#define CKEN_SSP3 (4) /* SSP3 Unit Clock Enable */ +#define CKEN_SSP (3) /* SSP Unit Clock Enable */ +#define CKEN_SSP2 (3) /* SSP2 Unit Clock Enable */ +#define CKEN_AC97 (2) /* AC97 Unit Clock Enable */ +#define CKEN_PWM1 (1) /* PWM1 Clock Enable */ +#define CKEN_PWM0 (0) /* PWM0 Clock Enable */ + +#define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */ +#define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */ + #endif diff --git a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h index 9aa6c2e939e..ba7e132de1b 100644 --- a/include/asm-arm/arch-pxa/system.h +++ b/include/asm-arm/arch-pxa/system.h @@ -12,6 +12,7 @@ #include #include "hardware.h" +#include "pxa2xx-regs.h" #include "pxa-regs.h" static inline void arch_idle(void) -- cgit v1.2.3-70-g09d2 From d4f4c0aa8e36f69e46360b3d3569dc15d6099894 Mon Sep 17 00:00:00 2001 From: HÃ¥vard Skinnemoen Date: Fri, 6 Jun 2008 18:04:52 +0200 Subject: [MTD] [NAND] rename at91_nand -> atmel_nand: file names and Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AT91 NAND driver needs just a few tiny modifications to work on AVR32 as well. Rename it atmel_nand to reflect this. Also move the ECC register definitions into drivers/mtd/nand since they are only useful to the atmel_nand driver, and get rid of the useless filename at the top of each file. Signed-off-by: HÃ¥vard Skinnemoen Signed-off-by: David Woodhouse --- drivers/mtd/nand/Kconfig | 17 +- drivers/mtd/nand/Makefile | 2 +- drivers/mtd/nand/at91_nand.c | 592 ----------------------------------- drivers/mtd/nand/atmel_nand.c | 590 ++++++++++++++++++++++++++++++++++ drivers/mtd/nand/atmel_nand_ecc.h | 36 +++ include/asm-arm/arch-at91/at91_ecc.h | 38 --- 6 files changed, 636 insertions(+), 639 deletions(-) delete mode 100644 drivers/mtd/nand/at91_nand.c create mode 100644 drivers/mtd/nand/atmel_nand.c create mode 100644 drivers/mtd/nand/atmel_nand_ecc.h delete mode 100644 include/asm-arm/arch-at91/at91_ecc.h (limited to 'include/asm-arm') diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 7dea6c3a660..cdd2952c153 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -271,7 +271,7 @@ config MTD_NAND_CS553X If you say "m", the module will be called "cs553x_nand.ko". -config MTD_NAND_AT91 +config MTD_NAND_ATMEL bool "Support for NAND Flash / SmartMedia on AT91" depends on ARCH_AT91 help @@ -279,14 +279,15 @@ config MTD_NAND_AT91 on Atmel AT91 processors. choice prompt "ECC management for NAND Flash / SmartMedia on AT91" - depends on MTD_NAND_AT91 + depends on MTD_NAND_ATMEL -config MTD_NAND_AT91_ECC_HW +config MTD_NAND_ATMEL_ECC_HW bool "Hardware ECC" depends on ARCH_AT91SAM9263 || ARCH_AT91SAM9260 help - Uses hardware ECC provided by the at91sam9260/at91sam9263 chip - instead of software ECC. + Use hardware ECC instead of software ECC when the chip + supports it. + The hardware ECC controller is capable of single bit error correction and 2-bit random detection per page. @@ -296,16 +297,16 @@ config MTD_NAND_AT91_ECC_HW If unsure, say Y -config MTD_NAND_AT91_ECC_SOFT +config MTD_NAND_ATMEL_ECC_SOFT bool "Software ECC" help - Uses software ECC. + Use software ECC. NB : hardware and software ECC schemes are incompatible. If you switch from one to another, you'll have to erase your mtd partition. -config MTD_NAND_AT91_ECC_NONE +config MTD_NAND_ATMEL_ECC_NONE bool "No ECC (testing only, DANGEROUS)" depends on DEBUG_KERNEL help diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index d95a10c5186..d772581de57 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_MTD_NAND_TS7250) += ts7250.o obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o -obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o +obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c deleted file mode 100644 index 2dcaeeae206..00000000000 --- a/drivers/mtd/nand/at91_nand.c +++ /dev/null @@ -1,592 +0,0 @@ -/* - * drivers/mtd/nand/at91_nand.c - * - * Copyright (C) 2003 Rick Bronson - * - * Derived from drivers/mtd/nand/autcpu12.c - * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) - * - * Derived from drivers/mtd/spia.c - * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) - * - * - * Add Hardware ECC support for AT91SAM9260 / AT91SAM9263 - * Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright (C) 2007 - * - * Derived from Das U-Boot source code - * (u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c) - * (C) Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas - * - * - * 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 -#include -#include -#include -#include -#include - -#include -#include - -#include - -#ifdef CONFIG_MTD_NAND_AT91_ECC_HW -#define hard_ecc 1 -#else -#define hard_ecc 0 -#endif - -#ifdef CONFIG_MTD_NAND_AT91_ECC_NONE -#define no_ecc 1 -#else -#define no_ecc 0 -#endif - -/* Register access macros */ -#define ecc_readl(add, reg) \ - __raw_readl(add + AT91_ECC_##reg) -#define ecc_writel(add, reg, value) \ - __raw_writel((value), add + AT91_ECC_##reg) - -#include /* AT91SAM9260/3 ECC registers */ - -/* oob layout for large page size - * bad block info is on bytes 0 and 1 - * the bytes have to be consecutives to avoid - * several NAND_CMD_RNDOUT during read - */ -static struct nand_ecclayout at91_oobinfo_large = { - .eccbytes = 4, - .eccpos = {60, 61, 62, 63}, - .oobfree = { - {2, 58} - }, -}; - -/* oob layout for small page size - * bad block info is on bytes 4 and 5 - * the bytes have to be consecutives to avoid - * several NAND_CMD_RNDOUT during read - */ -static struct nand_ecclayout at91_oobinfo_small = { - .eccbytes = 4, - .eccpos = {0, 1, 2, 3}, - .oobfree = { - {6, 10} - }, -}; - -struct at91_nand_host { - struct nand_chip nand_chip; - struct mtd_info mtd; - void __iomem *io_base; - struct at91_nand_data *board; - struct device *dev; - void __iomem *ecc; -}; - -/* - * Enable NAND. - */ -static void at91_nand_enable(struct at91_nand_host *host) -{ - if (host->board->enable_pin) - gpio_set_value(host->board->enable_pin, 0); -} - -/* - * Disable NAND. - */ -static void at91_nand_disable(struct at91_nand_host *host) -{ - if (host->board->enable_pin) - gpio_set_value(host->board->enable_pin, 1); -} - -/* - * Hardware specific access to control-lines - */ -static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ - struct nand_chip *nand_chip = mtd->priv; - struct at91_nand_host *host = nand_chip->priv; - - if (ctrl & NAND_CTRL_CHANGE) { - if (ctrl & NAND_NCE) - at91_nand_enable(host); - else - at91_nand_disable(host); - } - if (cmd == NAND_CMD_NONE) - return; - - if (ctrl & NAND_CLE) - writeb(cmd, host->io_base + (1 << host->board->cle)); - else - writeb(cmd, host->io_base + (1 << host->board->ale)); -} - -/* - * Read the Device Ready pin. - */ -static int at91_nand_device_ready(struct mtd_info *mtd) -{ - struct nand_chip *nand_chip = mtd->priv; - struct at91_nand_host *host = nand_chip->priv; - - return gpio_get_value(host->board->rdy_pin); -} - -/* - * write oob for small pages - */ -static int at91_nand_write_oob_512(struct mtd_info *mtd, - struct nand_chip *chip, int page) -{ - int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; - int eccsize = chip->ecc.size, length = mtd->oobsize; - int len, pos, status = 0; - const uint8_t *bufpoi = chip->oob_poi; - - pos = eccsize + chunk; - - chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); - len = min_t(int, length, chunk); - chip->write_buf(mtd, bufpoi, len); - bufpoi += len; - length -= len; - if (length > 0) - chip->write_buf(mtd, bufpoi, length); - - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); - status = chip->waitfunc(mtd, chip); - - return status & NAND_STATUS_FAIL ? -EIO : 0; - -} - -/* - * read oob for small pages - */ -static int at91_nand_read_oob_512(struct mtd_info *mtd, - struct nand_chip *chip, int page, int sndcmd) -{ - if (sndcmd) { - chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); - sndcmd = 0; - } - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - return sndcmd; -} - -/* - * Calculate HW ECC - * - * function called after a write - * - * mtd: MTD block structure - * dat: raw data (unused) - * ecc_code: buffer for ECC - */ -static int at91_nand_calculate(struct mtd_info *mtd, - const u_char *dat, unsigned char *ecc_code) -{ - struct nand_chip *nand_chip = mtd->priv; - struct at91_nand_host *host = nand_chip->priv; - uint32_t *eccpos = nand_chip->ecc.layout->eccpos; - unsigned int ecc_value; - - /* get the first 2 ECC bytes */ - ecc_value = ecc_readl(host->ecc, PR); - - ecc_code[eccpos[0]] = ecc_value & 0xFF; - ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; - - /* get the last 2 ECC bytes */ - ecc_value = ecc_readl(host->ecc, NPR) & AT91_ECC_NPARITY; - - ecc_code[eccpos[2]] = ecc_value & 0xFF; - ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; - - return 0; -} - -/* - * HW ECC read page function - * - * mtd: mtd info structure - * chip: nand chip info structure - * buf: buffer to store read data - */ -static int at91_nand_read_page(struct mtd_info *mtd, - struct nand_chip *chip, uint8_t *buf) -{ - int eccsize = chip->ecc.size; - int eccbytes = chip->ecc.bytes; - uint32_t *eccpos = chip->ecc.layout->eccpos; - uint8_t *p = buf; - uint8_t *oob = chip->oob_poi; - uint8_t *ecc_pos; - int stat; - - /* read the page */ - chip->read_buf(mtd, p, eccsize); - - /* move to ECC position if needed */ - if (eccpos[0] != 0) { - /* This only works on large pages - * because the ECC controller waits for - * NAND_CMD_RNDOUTSTART after the - * NAND_CMD_RNDOUT. - * anyway, for small pages, the eccpos[0] == 0 - */ - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, - mtd->writesize + eccpos[0], -1); - } - - /* the ECC controller needs to read the ECC just after the data */ - ecc_pos = oob + eccpos[0]; - chip->read_buf(mtd, ecc_pos, eccbytes); - - /* check if there's an error */ - stat = chip->ecc.correct(mtd, p, oob, NULL); - - if (stat < 0) - mtd->ecc_stats.failed++; - else - mtd->ecc_stats.corrected += stat; - - /* get back to oob start (end of page) */ - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); - - /* read the oob */ - chip->read_buf(mtd, oob, mtd->oobsize); - - return 0; -} - -/* - * HW ECC Correction - * - * function called after a read - * - * mtd: MTD block structure - * dat: raw data read from the chip - * read_ecc: ECC from the chip (unused) - * isnull: unused - * - * Detect and correct a 1 bit error for a page - */ -static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, - u_char *read_ecc, u_char *isnull) -{ - struct nand_chip *nand_chip = mtd->priv; - struct at91_nand_host *host = nand_chip->priv; - unsigned int ecc_status; - unsigned int ecc_word, ecc_bit; - - /* get the status from the Status Register */ - ecc_status = ecc_readl(host->ecc, SR); - - /* if there's no error */ - if (likely(!(ecc_status & AT91_ECC_RECERR))) - return 0; - - /* get error bit offset (4 bits) */ - ecc_bit = ecc_readl(host->ecc, PR) & AT91_ECC_BITADDR; - /* get word address (12 bits) */ - ecc_word = ecc_readl(host->ecc, PR) & AT91_ECC_WORDADDR; - ecc_word >>= 4; - - /* if there are multiple errors */ - if (ecc_status & AT91_ECC_MULERR) { - /* check if it is a freshly erased block - * (filled with 0xff) */ - if ((ecc_bit == AT91_ECC_BITADDR) - && (ecc_word == (AT91_ECC_WORDADDR >> 4))) { - /* the block has just been erased, return OK */ - return 0; - } - /* it doesn't seems to be a freshly - * erased block. - * We can't correct so many errors */ - dev_dbg(host->dev, "at91_nand : multiple errors detected." - " Unable to correct.\n"); - return -EIO; - } - - /* if there's a single bit error : we can correct it */ - if (ecc_status & AT91_ECC_ECCERR) { - /* there's nothing much to do here. - * the bit error is on the ECC itself. - */ - dev_dbg(host->dev, "at91_nand : one bit error on ECC code." - " Nothing to correct\n"); - return 0; - } - - dev_dbg(host->dev, "at91_nand : one bit error on data." - " (word offset in the page :" - " 0x%x bit offset : 0x%x)\n", - ecc_word, ecc_bit); - /* correct the error */ - if (nand_chip->options & NAND_BUSWIDTH_16) { - /* 16 bits words */ - ((unsigned short *) dat)[ecc_word] ^= (1 << ecc_bit); - } else { - /* 8 bits words */ - dat[ecc_word] ^= (1 << ecc_bit); - } - dev_dbg(host->dev, "at91_nand : error corrected\n"); - return 1; -} - -/* - * Enable HW ECC : unsused - */ -static void at91_nand_hwctl(struct mtd_info *mtd, int mode) { ; } - -#ifdef CONFIG_MTD_PARTITIONS -static const char *part_probes[] = { "cmdlinepart", NULL }; -#endif - -/* - * Probe for the NAND device. - */ -static int __init at91_nand_probe(struct platform_device *pdev) -{ - struct at91_nand_host *host; - struct mtd_info *mtd; - struct nand_chip *nand_chip; - struct resource *regs; - struct resource *mem; - int res; - -#ifdef CONFIG_MTD_PARTITIONS - struct mtd_partition *partitions = NULL; - int num_partitions = 0; -#endif - - /* Allocate memory for the device structure (and zero it) */ - host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL); - if (!host) { - printk(KERN_ERR "at91_nand: failed to allocate device structure.\n"); - return -ENOMEM; - } - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - printk(KERN_ERR "at91_nand: can't get I/O resource mem\n"); - return -ENXIO; - } - - host->io_base = ioremap(mem->start, mem->end - mem->start + 1); - if (host->io_base == NULL) { - printk(KERN_ERR "at91_nand: ioremap failed\n"); - kfree(host); - return -EIO; - } - - mtd = &host->mtd; - nand_chip = &host->nand_chip; - host->board = pdev->dev.platform_data; - host->dev = &pdev->dev; - - nand_chip->priv = host; /* link the private data structures */ - mtd->priv = nand_chip; - mtd->owner = THIS_MODULE; - - /* Set address of NAND IO lines */ - nand_chip->IO_ADDR_R = host->io_base; - nand_chip->IO_ADDR_W = host->io_base; - nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; - - if (host->board->rdy_pin) - nand_chip->dev_ready = at91_nand_device_ready; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!regs && hard_ecc) { - printk(KERN_ERR "at91_nand: can't get I/O resource " - "regs\nFalling back on software ECC\n"); - } - - nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ - if (no_ecc) - nand_chip->ecc.mode = NAND_ECC_NONE; - if (hard_ecc && regs) { - host->ecc = ioremap(regs->start, regs->end - regs->start + 1); - if (host->ecc == NULL) { - printk(KERN_ERR "at91_nand: ioremap failed\n"); - res = -EIO; - goto err_ecc_ioremap; - } - nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; - nand_chip->ecc.calculate = at91_nand_calculate; - nand_chip->ecc.correct = at91_nand_correct; - nand_chip->ecc.hwctl = at91_nand_hwctl; - nand_chip->ecc.read_page = at91_nand_read_page; - nand_chip->ecc.bytes = 4; - nand_chip->ecc.prepad = 0; - nand_chip->ecc.postpad = 0; - } - - nand_chip->chip_delay = 20; /* 20us command delay time */ - - if (host->board->bus_width_16) /* 16-bit bus width */ - nand_chip->options |= NAND_BUSWIDTH_16; - - platform_set_drvdata(pdev, host); - at91_nand_enable(host); - - if (host->board->det_pin) { - if (gpio_get_value(host->board->det_pin)) { - printk ("No SmartMedia card inserted.\n"); - res = ENXIO; - goto out; - } - } - - /* first scan to find the device and get the page size */ - if (nand_scan_ident(mtd, 1)) { - res = -ENXIO; - goto out; - } - - if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { - /* ECC is calculated for the whole page (1 step) */ - nand_chip->ecc.size = mtd->writesize; - - /* set ECC page size and oob layout */ - switch (mtd->writesize) { - case 512: - nand_chip->ecc.layout = &at91_oobinfo_small; - nand_chip->ecc.read_oob = at91_nand_read_oob_512; - nand_chip->ecc.write_oob = at91_nand_write_oob_512; - ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_528); - break; - case 1024: - nand_chip->ecc.layout = &at91_oobinfo_large; - ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_1056); - break; - case 2048: - nand_chip->ecc.layout = &at91_oobinfo_large; - ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_2112); - break; - case 4096: - nand_chip->ecc.layout = &at91_oobinfo_large; - ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_4224); - break; - default: - /* page size not handled by HW ECC */ - /* switching back to soft ECC */ - nand_chip->ecc.mode = NAND_ECC_SOFT; - nand_chip->ecc.calculate = NULL; - nand_chip->ecc.correct = NULL; - nand_chip->ecc.hwctl = NULL; - nand_chip->ecc.read_page = NULL; - nand_chip->ecc.postpad = 0; - nand_chip->ecc.prepad = 0; - nand_chip->ecc.bytes = 0; - break; - } - } - - /* second phase scan */ - if (nand_scan_tail(mtd)) { - res = -ENXIO; - goto out; - } - -#ifdef CONFIG_MTD_PARTITIONS -#ifdef CONFIG_MTD_CMDLINE_PARTS - mtd->name = "at91_nand"; - num_partitions = parse_mtd_partitions(mtd, part_probes, - &partitions, 0); -#endif - if (num_partitions <= 0 && host->board->partition_info) - partitions = host->board->partition_info(mtd->size, - &num_partitions); - - if ((!partitions) || (num_partitions == 0)) { - printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); - res = ENXIO; - goto release; - } - - res = add_mtd_partitions(mtd, partitions, num_partitions); -#else - res = add_mtd_device(mtd); -#endif - - if (!res) - return res; - -#ifdef CONFIG_MTD_PARTITIONS -release: -#endif - nand_release(mtd); - -out: - iounmap(host->ecc); - -err_ecc_ioremap: - at91_nand_disable(host); - platform_set_drvdata(pdev, NULL); - iounmap(host->io_base); - kfree(host); - return res; -} - -/* - * Remove a NAND device. - */ -static int __devexit at91_nand_remove(struct platform_device *pdev) -{ - struct at91_nand_host *host = platform_get_drvdata(pdev); - struct mtd_info *mtd = &host->mtd; - - nand_release(mtd); - - at91_nand_disable(host); - - iounmap(host->io_base); - iounmap(host->ecc); - kfree(host); - - return 0; -} - -static struct platform_driver at91_nand_driver = { - .probe = at91_nand_probe, - .remove = at91_nand_remove, - .driver = { - .name = "at91_nand", - .owner = THIS_MODULE, - }, -}; - -static int __init at91_nand_init(void) -{ - return platform_driver_register(&at91_nand_driver); -} - - -static void __exit at91_nand_exit(void) -{ - platform_driver_unregister(&at91_nand_driver); -} - - -module_init(at91_nand_init); -module_exit(at91_nand_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Rick Bronson"); -MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200 / AT91SAM9"); -MODULE_ALIAS("platform:at91_nand"); diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c new file mode 100644 index 00000000000..51b703155db --- /dev/null +++ b/drivers/mtd/nand/atmel_nand.c @@ -0,0 +1,590 @@ +/* + * Copyright (C) 2003 Rick Bronson + * + * Derived from drivers/mtd/nand/autcpu12.c + * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) + * + * Derived from drivers/mtd/spia.c + * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) + * + * + * Add Hardware ECC support for AT91SAM9260 / AT91SAM9263 + * Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright (C) 2007 + * + * Derived from Das U-Boot source code + * (u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c) + * (C) Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas + * + * + * 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 +#include +#include +#include +#include +#include + +#include +#include + +#include + +#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW +#define hard_ecc 1 +#else +#define hard_ecc 0 +#endif + +#ifdef CONFIG_MTD_NAND_ATMEL_ECC_NONE +#define no_ecc 1 +#else +#define no_ecc 0 +#endif + +/* Register access macros */ +#define ecc_readl(add, reg) \ + __raw_readl(add + AT91_ECC_##reg) +#define ecc_writel(add, reg, value) \ + __raw_writel((value), add + AT91_ECC_##reg) + +#include "atmel_nand_ecc.h" /* Hardware ECC registers */ + +/* oob layout for large page size + * bad block info is on bytes 0 and 1 + * the bytes have to be consecutives to avoid + * several NAND_CMD_RNDOUT during read + */ +static struct nand_ecclayout at91_oobinfo_large = { + .eccbytes = 4, + .eccpos = {60, 61, 62, 63}, + .oobfree = { + {2, 58} + }, +}; + +/* oob layout for small page size + * bad block info is on bytes 4 and 5 + * the bytes have to be consecutives to avoid + * several NAND_CMD_RNDOUT during read + */ +static struct nand_ecclayout at91_oobinfo_small = { + .eccbytes = 4, + .eccpos = {0, 1, 2, 3}, + .oobfree = { + {6, 10} + }, +}; + +struct at91_nand_host { + struct nand_chip nand_chip; + struct mtd_info mtd; + void __iomem *io_base; + struct at91_nand_data *board; + struct device *dev; + void __iomem *ecc; +}; + +/* + * Enable NAND. + */ +static void at91_nand_enable(struct at91_nand_host *host) +{ + if (host->board->enable_pin) + gpio_set_value(host->board->enable_pin, 0); +} + +/* + * Disable NAND. + */ +static void at91_nand_disable(struct at91_nand_host *host) +{ + if (host->board->enable_pin) + gpio_set_value(host->board->enable_pin, 1); +} + +/* + * Hardware specific access to control-lines + */ +static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *nand_chip = mtd->priv; + struct at91_nand_host *host = nand_chip->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_NCE) + at91_nand_enable(host); + else + at91_nand_disable(host); + } + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + writeb(cmd, host->io_base + (1 << host->board->cle)); + else + writeb(cmd, host->io_base + (1 << host->board->ale)); +} + +/* + * Read the Device Ready pin. + */ +static int at91_nand_device_ready(struct mtd_info *mtd) +{ + struct nand_chip *nand_chip = mtd->priv; + struct at91_nand_host *host = nand_chip->priv; + + return gpio_get_value(host->board->rdy_pin); +} + +/* + * write oob for small pages + */ +static int at91_nand_write_oob_512(struct mtd_info *mtd, + struct nand_chip *chip, int page) +{ + int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; + int eccsize = chip->ecc.size, length = mtd->oobsize; + int len, pos, status = 0; + const uint8_t *bufpoi = chip->oob_poi; + + pos = eccsize + chunk; + + chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); + len = min_t(int, length, chunk); + chip->write_buf(mtd, bufpoi, len); + bufpoi += len; + length -= len; + if (length > 0) + chip->write_buf(mtd, bufpoi, length); + + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); + status = chip->waitfunc(mtd, chip); + + return status & NAND_STATUS_FAIL ? -EIO : 0; + +} + +/* + * read oob for small pages + */ +static int at91_nand_read_oob_512(struct mtd_info *mtd, + struct nand_chip *chip, int page, int sndcmd) +{ + if (sndcmd) { + chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); + sndcmd = 0; + } + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); + return sndcmd; +} + +/* + * Calculate HW ECC + * + * function called after a write + * + * mtd: MTD block structure + * dat: raw data (unused) + * ecc_code: buffer for ECC + */ +static int at91_nand_calculate(struct mtd_info *mtd, + const u_char *dat, unsigned char *ecc_code) +{ + struct nand_chip *nand_chip = mtd->priv; + struct at91_nand_host *host = nand_chip->priv; + uint32_t *eccpos = nand_chip->ecc.layout->eccpos; + unsigned int ecc_value; + + /* get the first 2 ECC bytes */ + ecc_value = ecc_readl(host->ecc, PR); + + ecc_code[eccpos[0]] = ecc_value & 0xFF; + ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; + + /* get the last 2 ECC bytes */ + ecc_value = ecc_readl(host->ecc, NPR) & AT91_ECC_NPARITY; + + ecc_code[eccpos[2]] = ecc_value & 0xFF; + ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; + + return 0; +} + +/* + * HW ECC read page function + * + * mtd: mtd info structure + * chip: nand chip info structure + * buf: buffer to store read data + */ +static int at91_nand_read_page(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf) +{ + int eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + uint32_t *eccpos = chip->ecc.layout->eccpos; + uint8_t *p = buf; + uint8_t *oob = chip->oob_poi; + uint8_t *ecc_pos; + int stat; + + /* read the page */ + chip->read_buf(mtd, p, eccsize); + + /* move to ECC position if needed */ + if (eccpos[0] != 0) { + /* This only works on large pages + * because the ECC controller waits for + * NAND_CMD_RNDOUTSTART after the + * NAND_CMD_RNDOUT. + * anyway, for small pages, the eccpos[0] == 0 + */ + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, + mtd->writesize + eccpos[0], -1); + } + + /* the ECC controller needs to read the ECC just after the data */ + ecc_pos = oob + eccpos[0]; + chip->read_buf(mtd, ecc_pos, eccbytes); + + /* check if there's an error */ + stat = chip->ecc.correct(mtd, p, oob, NULL); + + if (stat < 0) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; + + /* get back to oob start (end of page) */ + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); + + /* read the oob */ + chip->read_buf(mtd, oob, mtd->oobsize); + + return 0; +} + +/* + * HW ECC Correction + * + * function called after a read + * + * mtd: MTD block structure + * dat: raw data read from the chip + * read_ecc: ECC from the chip (unused) + * isnull: unused + * + * Detect and correct a 1 bit error for a page + */ +static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, + u_char *read_ecc, u_char *isnull) +{ + struct nand_chip *nand_chip = mtd->priv; + struct at91_nand_host *host = nand_chip->priv; + unsigned int ecc_status; + unsigned int ecc_word, ecc_bit; + + /* get the status from the Status Register */ + ecc_status = ecc_readl(host->ecc, SR); + + /* if there's no error */ + if (likely(!(ecc_status & AT91_ECC_RECERR))) + return 0; + + /* get error bit offset (4 bits) */ + ecc_bit = ecc_readl(host->ecc, PR) & AT91_ECC_BITADDR; + /* get word address (12 bits) */ + ecc_word = ecc_readl(host->ecc, PR) & AT91_ECC_WORDADDR; + ecc_word >>= 4; + + /* if there are multiple errors */ + if (ecc_status & AT91_ECC_MULERR) { + /* check if it is a freshly erased block + * (filled with 0xff) */ + if ((ecc_bit == AT91_ECC_BITADDR) + && (ecc_word == (AT91_ECC_WORDADDR >> 4))) { + /* the block has just been erased, return OK */ + return 0; + } + /* it doesn't seems to be a freshly + * erased block. + * We can't correct so many errors */ + dev_dbg(host->dev, "at91_nand : multiple errors detected." + " Unable to correct.\n"); + return -EIO; + } + + /* if there's a single bit error : we can correct it */ + if (ecc_status & AT91_ECC_ECCERR) { + /* there's nothing much to do here. + * the bit error is on the ECC itself. + */ + dev_dbg(host->dev, "at91_nand : one bit error on ECC code." + " Nothing to correct\n"); + return 0; + } + + dev_dbg(host->dev, "at91_nand : one bit error on data." + " (word offset in the page :" + " 0x%x bit offset : 0x%x)\n", + ecc_word, ecc_bit); + /* correct the error */ + if (nand_chip->options & NAND_BUSWIDTH_16) { + /* 16 bits words */ + ((unsigned short *) dat)[ecc_word] ^= (1 << ecc_bit); + } else { + /* 8 bits words */ + dat[ecc_word] ^= (1 << ecc_bit); + } + dev_dbg(host->dev, "at91_nand : error corrected\n"); + return 1; +} + +/* + * Enable HW ECC : unsused + */ +static void at91_nand_hwctl(struct mtd_info *mtd, int mode) { ; } + +#ifdef CONFIG_MTD_PARTITIONS +static const char *part_probes[] = { "cmdlinepart", NULL }; +#endif + +/* + * Probe for the NAND device. + */ +static int __init at91_nand_probe(struct platform_device *pdev) +{ + struct at91_nand_host *host; + struct mtd_info *mtd; + struct nand_chip *nand_chip; + struct resource *regs; + struct resource *mem; + int res; + +#ifdef CONFIG_MTD_PARTITIONS + struct mtd_partition *partitions = NULL; + int num_partitions = 0; +#endif + + /* Allocate memory for the device structure (and zero it) */ + host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL); + if (!host) { + printk(KERN_ERR "at91_nand: failed to allocate device structure.\n"); + return -ENOMEM; + } + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + printk(KERN_ERR "at91_nand: can't get I/O resource mem\n"); + return -ENXIO; + } + + host->io_base = ioremap(mem->start, mem->end - mem->start + 1); + if (host->io_base == NULL) { + printk(KERN_ERR "at91_nand: ioremap failed\n"); + kfree(host); + return -EIO; + } + + mtd = &host->mtd; + nand_chip = &host->nand_chip; + host->board = pdev->dev.platform_data; + host->dev = &pdev->dev; + + nand_chip->priv = host; /* link the private data structures */ + mtd->priv = nand_chip; + mtd->owner = THIS_MODULE; + + /* Set address of NAND IO lines */ + nand_chip->IO_ADDR_R = host->io_base; + nand_chip->IO_ADDR_W = host->io_base; + nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; + + if (host->board->rdy_pin) + nand_chip->dev_ready = at91_nand_device_ready; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!regs && hard_ecc) { + printk(KERN_ERR "at91_nand: can't get I/O resource " + "regs\nFalling back on software ECC\n"); + } + + nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ + if (no_ecc) + nand_chip->ecc.mode = NAND_ECC_NONE; + if (hard_ecc && regs) { + host->ecc = ioremap(regs->start, regs->end - regs->start + 1); + if (host->ecc == NULL) { + printk(KERN_ERR "at91_nand: ioremap failed\n"); + res = -EIO; + goto err_ecc_ioremap; + } + nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; + nand_chip->ecc.calculate = at91_nand_calculate; + nand_chip->ecc.correct = at91_nand_correct; + nand_chip->ecc.hwctl = at91_nand_hwctl; + nand_chip->ecc.read_page = at91_nand_read_page; + nand_chip->ecc.bytes = 4; + nand_chip->ecc.prepad = 0; + nand_chip->ecc.postpad = 0; + } + + nand_chip->chip_delay = 20; /* 20us command delay time */ + + if (host->board->bus_width_16) /* 16-bit bus width */ + nand_chip->options |= NAND_BUSWIDTH_16; + + platform_set_drvdata(pdev, host); + at91_nand_enable(host); + + if (host->board->det_pin) { + if (gpio_get_value(host->board->det_pin)) { + printk ("No SmartMedia card inserted.\n"); + res = ENXIO; + goto out; + } + } + + /* first scan to find the device and get the page size */ + if (nand_scan_ident(mtd, 1)) { + res = -ENXIO; + goto out; + } + + if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { + /* ECC is calculated for the whole page (1 step) */ + nand_chip->ecc.size = mtd->writesize; + + /* set ECC page size and oob layout */ + switch (mtd->writesize) { + case 512: + nand_chip->ecc.layout = &at91_oobinfo_small; + nand_chip->ecc.read_oob = at91_nand_read_oob_512; + nand_chip->ecc.write_oob = at91_nand_write_oob_512; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_528); + break; + case 1024: + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_1056); + break; + case 2048: + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_2112); + break; + case 4096: + nand_chip->ecc.layout = &at91_oobinfo_large; + ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_4224); + break; + default: + /* page size not handled by HW ECC */ + /* switching back to soft ECC */ + nand_chip->ecc.mode = NAND_ECC_SOFT; + nand_chip->ecc.calculate = NULL; + nand_chip->ecc.correct = NULL; + nand_chip->ecc.hwctl = NULL; + nand_chip->ecc.read_page = NULL; + nand_chip->ecc.postpad = 0; + nand_chip->ecc.prepad = 0; + nand_chip->ecc.bytes = 0; + break; + } + } + + /* second phase scan */ + if (nand_scan_tail(mtd)) { + res = -ENXIO; + goto out; + } + +#ifdef CONFIG_MTD_PARTITIONS +#ifdef CONFIG_MTD_CMDLINE_PARTS + mtd->name = "at91_nand"; + num_partitions = parse_mtd_partitions(mtd, part_probes, + &partitions, 0); +#endif + if (num_partitions <= 0 && host->board->partition_info) + partitions = host->board->partition_info(mtd->size, + &num_partitions); + + if ((!partitions) || (num_partitions == 0)) { + printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); + res = ENXIO; + goto release; + } + + res = add_mtd_partitions(mtd, partitions, num_partitions); +#else + res = add_mtd_device(mtd); +#endif + + if (!res) + return res; + +#ifdef CONFIG_MTD_PARTITIONS +release: +#endif + nand_release(mtd); + +out: + iounmap(host->ecc); + +err_ecc_ioremap: + at91_nand_disable(host); + platform_set_drvdata(pdev, NULL); + iounmap(host->io_base); + kfree(host); + return res; +} + +/* + * Remove a NAND device. + */ +static int __devexit at91_nand_remove(struct platform_device *pdev) +{ + struct at91_nand_host *host = platform_get_drvdata(pdev); + struct mtd_info *mtd = &host->mtd; + + nand_release(mtd); + + at91_nand_disable(host); + + iounmap(host->io_base); + iounmap(host->ecc); + kfree(host); + + return 0; +} + +static struct platform_driver at91_nand_driver = { + .probe = at91_nand_probe, + .remove = at91_nand_remove, + .driver = { + .name = "at91_nand", + .owner = THIS_MODULE, + }, +}; + +static int __init at91_nand_init(void) +{ + return platform_driver_register(&at91_nand_driver); +} + + +static void __exit at91_nand_exit(void) +{ + platform_driver_unregister(&at91_nand_driver); +} + + +module_init(at91_nand_init); +module_exit(at91_nand_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Rick Bronson"); +MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91 / AVR32"); +MODULE_ALIAS("platform:at91_nand"); diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h new file mode 100644 index 00000000000..170db869aac --- /dev/null +++ b/drivers/mtd/nand/atmel_nand_ecc.h @@ -0,0 +1,36 @@ +/* + * Error Corrected Code Controller (ECC) - System peripherals regsters. + * Based on AT91SAM9260 datasheet revision B. + * + * 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 ATMEL_NAND_ECC_H +#define ATMEL_NAND_ECC_H + +#define AT91_ECC_CR 0x00 /* Control register */ +#define AT91_ECC_RST (1 << 0) /* Reset parity */ + +#define AT91_ECC_MR 0x04 /* Mode register */ +#define AT91_ECC_PAGESIZE (3 << 0) /* Page Size */ +#define AT91_ECC_PAGESIZE_528 (0) +#define AT91_ECC_PAGESIZE_1056 (1) +#define AT91_ECC_PAGESIZE_2112 (2) +#define AT91_ECC_PAGESIZE_4224 (3) + +#define AT91_ECC_SR 0x08 /* Status register */ +#define AT91_ECC_RECERR (1 << 0) /* Recoverable Error */ +#define AT91_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ +#define AT91_ECC_MULERR (1 << 2) /* Multiple Errors */ + +#define AT91_ECC_PR 0x0c /* Parity register */ +#define AT91_ECC_BITADDR (0xf << 0) /* Bit Error Address */ +#define AT91_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ + +#define AT91_ECC_NPR 0x10 /* NParity register */ +#define AT91_ECC_NPARITY (0xffff << 0) /* NParity */ + +#endif diff --git a/include/asm-arm/arch-at91/at91_ecc.h b/include/asm-arm/arch-at91/at91_ecc.h deleted file mode 100644 index 1e5a8caca2d..00000000000 --- a/include/asm-arm/arch-at91/at91_ecc.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * include/asm-arm/arch-at91/at91_ecc.h - * - * Error Corrected Code Controller (ECC) - System peripherals regsters. - * Based on AT91SAM9260 datasheet revision B. - * - * 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 AT91_ECC_H -#define AT91_ECC_H - -#define AT91_ECC_CR 0x00 /* Control register */ -#define AT91_ECC_RST (1 << 0) /* Reset parity */ - -#define AT91_ECC_MR 0x04 /* Mode register */ -#define AT91_ECC_PAGESIZE (3 << 0) /* Page Size */ -#define AT91_ECC_PAGESIZE_528 (0) -#define AT91_ECC_PAGESIZE_1056 (1) -#define AT91_ECC_PAGESIZE_2112 (2) -#define AT91_ECC_PAGESIZE_4224 (3) - -#define AT91_ECC_SR 0x08 /* Status register */ -#define AT91_ECC_RECERR (1 << 0) /* Recoverable Error */ -#define AT91_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ -#define AT91_ECC_MULERR (1 << 2) /* Multiple Errors */ - -#define AT91_ECC_PR 0x0c /* Parity register */ -#define AT91_ECC_BITADDR (0xf << 0) /* Bit Error Address */ -#define AT91_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ - -#define AT91_ECC_NPR 0x10 /* NParity register */ -#define AT91_ECC_NPARITY (0xffff << 0) /* NParity */ - -#endif -- cgit v1.2.3-70-g09d2 From 3c3796cc32b6e53653a5eb868dc959b8c2779db9 Mon Sep 17 00:00:00 2001 From: HÃ¥vard Skinnemoen Date: Fri, 6 Jun 2008 18:04:53 +0200 Subject: [MTD] [NAND] rename at91_nand -> atmel_nand: internal symbols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is basically s/at91_nand/atmel_nand/g with some manual inspection. Signed-off-by: HÃ¥vard Skinnemoen Signed-off-by: David Woodhouse --- arch/arm/mach-at91/at91cap9_devices.c | 8 +- arch/arm/mach-at91/at91rm9200_devices.c | 8 +- arch/arm/mach-at91/at91sam9260_devices.c | 8 +- arch/arm/mach-at91/at91sam9261_devices.c | 12 +-- arch/arm/mach-at91/at91sam9263_devices.c | 8 +- arch/arm/mach-at91/at91sam9rl_devices.c | 12 +-- arch/arm/mach-at91/board-cam60.c | 2 +- arch/arm/mach-at91/board-cap9adk.c | 2 +- arch/arm/mach-at91/board-dk.c | 2 +- arch/arm/mach-at91/board-kb9202.c | 2 +- arch/arm/mach-at91/board-sam9-l9260.c | 2 +- arch/arm/mach-at91/board-sam9260ek.c | 2 +- arch/arm/mach-at91/board-sam9261ek.c | 2 +- arch/arm/mach-at91/board-sam9263ek.c | 2 +- arch/arm/mach-at91/board-sam9rlek.c | 2 +- arch/arm/mach-at91/board-yl-9200.c | 2 +- drivers/mtd/nand/atmel_nand.c | 152 +++++++++++++++---------------- drivers/mtd/nand/atmel_nand_ecc.h | 34 +++---- include/asm-arm/arch-at91/board.h | 4 +- 19 files changed, 133 insertions(+), 133 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index be526746e01..fe5148e9f0c 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -278,7 +278,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; +static struct atmel_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -296,7 +296,7 @@ static struct resource nand_resources[] = { }; static struct platform_device at91cap9_nand_device = { - .name = "at91_nand", + .name = "atmel_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -305,7 +305,7 @@ static struct platform_device at91cap9_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct at91_nand_data *data) +void __init at91_add_device_nand(struct atmel_nand_data *data) { unsigned long csa, mode; @@ -346,7 +346,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) platform_device_register(&at91cap9_nand_device); } #else -void __init at91_add_device_nand(struct at91_nand_data *data) {} +void __init at91_add_device_nand(struct atmel_nand_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index de19bee83f7..8ced9bc8209 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -369,7 +369,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; +static struct atmel_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -382,7 +382,7 @@ static struct resource nand_resources[] = { }; static struct platform_device at91rm9200_nand_device = { - .name = "at91_nand", + .name = "atmel_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -391,7 +391,7 @@ static struct platform_device at91rm9200_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct at91_nand_data *data) +void __init at91_add_device_nand(struct atmel_nand_data *data) { unsigned int csa; @@ -429,7 +429,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) platform_device_register(&at91rm9200_nand_device); } #else -void __init at91_add_device_nand(struct at91_nand_data *data) {} +void __init at91_add_device_nand(struct atmel_nand_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 393a32aefce..3aa62b1151b 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -283,7 +283,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; +static struct atmel_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -301,7 +301,7 @@ static struct resource nand_resources[] = { }; static struct platform_device at91sam9260_nand_device = { - .name = "at91_nand", + .name = "atmel_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -310,7 +310,7 @@ static struct platform_device at91sam9260_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct at91_nand_data *data) +void __init at91_add_device_nand(struct atmel_nand_data *data) { unsigned long csa, mode; @@ -351,7 +351,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) platform_device_register(&at91sam9260_nand_device); } #else -void __init at91_add_device_nand(struct at91_nand_data *data) {} +void __init at91_add_device_nand(struct atmel_nand_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 728bb8f3944..6b9e423ec47 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -199,7 +199,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; +static struct atmel_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -211,8 +211,8 @@ static struct resource nand_resources[] = { } }; -static struct platform_device at91_nand_device = { - .name = "at91_nand", +static struct platform_device atmel_nand_device = { + .name = "atmel_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -221,7 +221,7 @@ static struct platform_device at91_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct at91_nand_data *data) +void __init at91_add_device_nand(struct atmel_nand_data *data) { unsigned long csa, mode; @@ -262,11 +262,11 @@ void __init at91_add_device_nand(struct at91_nand_data *data) at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */ nand_data = *data; - platform_device_register(&at91_nand_device); + platform_device_register(&atmel_nand_device); } #else -void __init at91_add_device_nand(struct at91_nand_data *data) {} +void __init at91_add_device_nand(struct atmel_nand_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 719667e25c9..f1dfbfe094a 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -353,7 +353,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; +static struct atmel_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -371,7 +371,7 @@ static struct resource nand_resources[] = { }; static struct platform_device at91sam9263_nand_device = { - .name = "at91_nand", + .name = "atmel_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -380,7 +380,7 @@ static struct platform_device at91sam9263_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct at91_nand_data *data) +void __init at91_add_device_nand(struct atmel_nand_data *data) { unsigned long csa, mode; @@ -421,7 +421,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) platform_device_register(&at91sam9263_nand_device); } #else -void __init at91_add_device_nand(struct at91_nand_data *data) {} +void __init at91_add_device_nand(struct atmel_nand_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 054689804e7..b21f3339326 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -100,7 +100,7 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; +static struct atmel_nand_data nand_data; #define NAND_BASE AT91_CHIPSELECT_3 @@ -117,8 +117,8 @@ static struct resource nand_resources[] = { } }; -static struct platform_device at91_nand_device = { - .name = "at91_nand", +static struct platform_device atmel_nand_device = { + .name = "atmel_nand", .id = -1, .dev = { .platform_data = &nand_data, @@ -127,7 +127,7 @@ static struct platform_device at91_nand_device = { .num_resources = ARRAY_SIZE(nand_resources), }; -void __init at91_add_device_nand(struct at91_nand_data *data) +void __init at91_add_device_nand(struct atmel_nand_data *data) { unsigned long csa; @@ -164,11 +164,11 @@ void __init at91_add_device_nand(struct at91_nand_data *data) at91_set_A_periph(AT91_PIN_PB5, 0); /* NANDWE */ nand_data = *data; - platform_device_register(&at91_nand_device); + platform_device_register(&atmel_nand_device); } #else -void __init at91_add_device_nand(struct at91_nand_data *data) {} +void __init at91_add_device_nand(struct atmel_nand_data *data) {} #endif diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index b22a1a00405..af2c33aff1a 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -142,7 +142,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return cam60_nand_partition; } -static struct at91_nand_data __initdata cam60_nand_data = { +static struct atmel_nand_data __initdata cam60_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not there diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index e5512d1ff21..7144e1a89a2 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -175,7 +175,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return cap9adk_nand_partitions; } -static struct at91_nand_data __initdata cap9adk_nand_data = { +static struct atmel_nand_data __initdata cap9adk_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c index c1a813c7169..ffecacb71f8 100644 --- a/arch/arm/mach-at91/board-dk.c +++ b/arch/arm/mach-at91/board-dk.c @@ -150,7 +150,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return dk_nand_partition; } -static struct at91_nand_data __initdata dk_nand_data = { +static struct atmel_nand_data __initdata dk_nand_data = { .ale = 22, .cle = 21, .det_pin = AT91_PIN_PB1, diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index 4b39b9cda75..153450f168f 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c @@ -102,7 +102,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return kb9202_nand_partition; } -static struct at91_nand_data __initdata kb9202_nand_data = { +static struct atmel_nand_data __initdata kb9202_nand_data = { .ale = 22, .cle = 21, // .det_pin = ... not there diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 8f76af5e219..57a6221943e 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -141,7 +141,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct at91_nand_data __initdata ek_nand_data = { +static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 4d1d9c77708..6a680795c3c 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -178,7 +178,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct at91_nand_data __initdata ek_nand_data = { +static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index 08382c0df22..43dfbd0d543 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -183,7 +183,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct at91_nand_data __initdata ek_nand_data = { +static struct atmel_nand_data __initdata ek_nand_data = { .ale = 22, .cle = 21, // .det_pin = ... not connected diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index b4cd5d0ed59..6605a098011 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -187,7 +187,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct at91_nand_data __initdata ek_nand_data = { +static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index ffc0597aee8..35e69e51f37 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -88,7 +88,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return ek_nand_partition; } -static struct at91_nand_data __initdata ek_nand_data = { +static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, // .det_pin = ... not connected diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index b5717108991..e642b3a8bd1 100755 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -251,7 +251,7 @@ static struct mtd_partition * __init nand_partitions(int size, int *num_partitio return yl_9200_nand_partition; } -static struct at91_nand_data __initdata yl_9200_nand_data = { +static struct atmel_nand_data __initdata yl_9200_nand_data = { .ale= 6, .cle= 7, /*.det_pin = AT91_PIN_PCxx,*/ /*we don't have a det pin because NandFlash is fixed to board*/ diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 51b703155db..675a82ca77f 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -48,9 +48,9 @@ /* Register access macros */ #define ecc_readl(add, reg) \ - __raw_readl(add + AT91_ECC_##reg) + __raw_readl(add + ATMEL_ECC_##reg) #define ecc_writel(add, reg, value) \ - __raw_writel((value), add + AT91_ECC_##reg) + __raw_writel((value), add + ATMEL_ECC_##reg) #include "atmel_nand_ecc.h" /* Hardware ECC registers */ @@ -59,7 +59,7 @@ * the bytes have to be consecutives to avoid * several NAND_CMD_RNDOUT during read */ -static struct nand_ecclayout at91_oobinfo_large = { +static struct nand_ecclayout atmel_oobinfo_large = { .eccbytes = 4, .eccpos = {60, 61, 62, 63}, .oobfree = { @@ -72,7 +72,7 @@ static struct nand_ecclayout at91_oobinfo_large = { * the bytes have to be consecutives to avoid * several NAND_CMD_RNDOUT during read */ -static struct nand_ecclayout at91_oobinfo_small = { +static struct nand_ecclayout atmel_oobinfo_small = { .eccbytes = 4, .eccpos = {0, 1, 2, 3}, .oobfree = { @@ -80,11 +80,11 @@ static struct nand_ecclayout at91_oobinfo_small = { }, }; -struct at91_nand_host { +struct atmel_nand_host { struct nand_chip nand_chip; struct mtd_info mtd; void __iomem *io_base; - struct at91_nand_data *board; + struct atmel_nand_data *board; struct device *dev; void __iomem *ecc; }; @@ -92,7 +92,7 @@ struct at91_nand_host { /* * Enable NAND. */ -static void at91_nand_enable(struct at91_nand_host *host) +static void atmel_nand_enable(struct atmel_nand_host *host) { if (host->board->enable_pin) gpio_set_value(host->board->enable_pin, 0); @@ -101,7 +101,7 @@ static void at91_nand_enable(struct at91_nand_host *host) /* * Disable NAND. */ -static void at91_nand_disable(struct at91_nand_host *host) +static void atmel_nand_disable(struct atmel_nand_host *host) { if (host->board->enable_pin) gpio_set_value(host->board->enable_pin, 1); @@ -110,16 +110,16 @@ static void at91_nand_disable(struct at91_nand_host *host) /* * Hardware specific access to control-lines */ -static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *nand_chip = mtd->priv; - struct at91_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_chip->priv; if (ctrl & NAND_CTRL_CHANGE) { if (ctrl & NAND_NCE) - at91_nand_enable(host); + atmel_nand_enable(host); else - at91_nand_disable(host); + atmel_nand_disable(host); } if (cmd == NAND_CMD_NONE) return; @@ -133,10 +133,10 @@ static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) /* * Read the Device Ready pin. */ -static int at91_nand_device_ready(struct mtd_info *mtd) +static int atmel_nand_device_ready(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd->priv; - struct at91_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_chip->priv; return gpio_get_value(host->board->rdy_pin); } @@ -144,7 +144,7 @@ static int at91_nand_device_ready(struct mtd_info *mtd) /* * write oob for small pages */ -static int at91_nand_write_oob_512(struct mtd_info *mtd, +static int atmel_nand_write_oob_512(struct mtd_info *mtd, struct nand_chip *chip, int page) { int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; @@ -172,7 +172,7 @@ static int at91_nand_write_oob_512(struct mtd_info *mtd, /* * read oob for small pages */ -static int at91_nand_read_oob_512(struct mtd_info *mtd, +static int atmel_nand_read_oob_512(struct mtd_info *mtd, struct nand_chip *chip, int page, int sndcmd) { if (sndcmd) { @@ -192,11 +192,11 @@ static int at91_nand_read_oob_512(struct mtd_info *mtd, * dat: raw data (unused) * ecc_code: buffer for ECC */ -static int at91_nand_calculate(struct mtd_info *mtd, +static int atmel_nand_calculate(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) { struct nand_chip *nand_chip = mtd->priv; - struct at91_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_chip->priv; uint32_t *eccpos = nand_chip->ecc.layout->eccpos; unsigned int ecc_value; @@ -207,7 +207,7 @@ static int at91_nand_calculate(struct mtd_info *mtd, ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; /* get the last 2 ECC bytes */ - ecc_value = ecc_readl(host->ecc, NPR) & AT91_ECC_NPARITY; + ecc_value = ecc_readl(host->ecc, NPR) & ATMEL_ECC_NPARITY; ecc_code[eccpos[2]] = ecc_value & 0xFF; ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; @@ -222,7 +222,7 @@ static int at91_nand_calculate(struct mtd_info *mtd, * chip: nand chip info structure * buf: buffer to store read data */ -static int at91_nand_read_page(struct mtd_info *mtd, +static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf) { int eccsize = chip->ecc.size; @@ -281,11 +281,11 @@ static int at91_nand_read_page(struct mtd_info *mtd, * * Detect and correct a 1 bit error for a page */ -static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, +static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *isnull) { struct nand_chip *nand_chip = mtd->priv; - struct at91_nand_host *host = nand_chip->priv; + struct atmel_nand_host *host = nand_chip->priv; unsigned int ecc_status; unsigned int ecc_word, ecc_bit; @@ -293,43 +293,43 @@ static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, ecc_status = ecc_readl(host->ecc, SR); /* if there's no error */ - if (likely(!(ecc_status & AT91_ECC_RECERR))) + if (likely(!(ecc_status & ATMEL_ECC_RECERR))) return 0; /* get error bit offset (4 bits) */ - ecc_bit = ecc_readl(host->ecc, PR) & AT91_ECC_BITADDR; + ecc_bit = ecc_readl(host->ecc, PR) & ATMEL_ECC_BITADDR; /* get word address (12 bits) */ - ecc_word = ecc_readl(host->ecc, PR) & AT91_ECC_WORDADDR; + ecc_word = ecc_readl(host->ecc, PR) & ATMEL_ECC_WORDADDR; ecc_word >>= 4; /* if there are multiple errors */ - if (ecc_status & AT91_ECC_MULERR) { + if (ecc_status & ATMEL_ECC_MULERR) { /* check if it is a freshly erased block * (filled with 0xff) */ - if ((ecc_bit == AT91_ECC_BITADDR) - && (ecc_word == (AT91_ECC_WORDADDR >> 4))) { + if ((ecc_bit == ATMEL_ECC_BITADDR) + && (ecc_word == (ATMEL_ECC_WORDADDR >> 4))) { /* the block has just been erased, return OK */ return 0; } /* it doesn't seems to be a freshly * erased block. * We can't correct so many errors */ - dev_dbg(host->dev, "at91_nand : multiple errors detected." + dev_dbg(host->dev, "atmel_nand : multiple errors detected." " Unable to correct.\n"); return -EIO; } /* if there's a single bit error : we can correct it */ - if (ecc_status & AT91_ECC_ECCERR) { + if (ecc_status & ATMEL_ECC_ECCERR) { /* there's nothing much to do here. * the bit error is on the ECC itself. */ - dev_dbg(host->dev, "at91_nand : one bit error on ECC code." + dev_dbg(host->dev, "atmel_nand : one bit error on ECC code." " Nothing to correct\n"); return 0; } - dev_dbg(host->dev, "at91_nand : one bit error on data." + dev_dbg(host->dev, "atmel_nand : one bit error on data." " (word offset in the page :" " 0x%x bit offset : 0x%x)\n", ecc_word, ecc_bit); @@ -341,14 +341,14 @@ static int at91_nand_correct(struct mtd_info *mtd, u_char *dat, /* 8 bits words */ dat[ecc_word] ^= (1 << ecc_bit); } - dev_dbg(host->dev, "at91_nand : error corrected\n"); + dev_dbg(host->dev, "atmel_nand : error corrected\n"); return 1; } /* * Enable HW ECC : unsused */ -static void at91_nand_hwctl(struct mtd_info *mtd, int mode) { ; } +static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) { ; } #ifdef CONFIG_MTD_PARTITIONS static const char *part_probes[] = { "cmdlinepart", NULL }; @@ -357,9 +357,9 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; /* * Probe for the NAND device. */ -static int __init at91_nand_probe(struct platform_device *pdev) +static int __init atmel_nand_probe(struct platform_device *pdev) { - struct at91_nand_host *host; + struct atmel_nand_host *host; struct mtd_info *mtd; struct nand_chip *nand_chip; struct resource *regs; @@ -372,21 +372,21 @@ static int __init at91_nand_probe(struct platform_device *pdev) #endif /* Allocate memory for the device structure (and zero it) */ - host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL); + host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL); if (!host) { - printk(KERN_ERR "at91_nand: failed to allocate device structure.\n"); + printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n"); return -ENOMEM; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { - printk(KERN_ERR "at91_nand: can't get I/O resource mem\n"); + printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n"); return -ENXIO; } host->io_base = ioremap(mem->start, mem->end - mem->start + 1); if (host->io_base == NULL) { - printk(KERN_ERR "at91_nand: ioremap failed\n"); + printk(KERN_ERR "atmel_nand: ioremap failed\n"); kfree(host); return -EIO; } @@ -403,14 +403,14 @@ static int __init at91_nand_probe(struct platform_device *pdev) /* Set address of NAND IO lines */ nand_chip->IO_ADDR_R = host->io_base; nand_chip->IO_ADDR_W = host->io_base; - nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; + nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; if (host->board->rdy_pin) - nand_chip->dev_ready = at91_nand_device_ready; + nand_chip->dev_ready = atmel_nand_device_ready; regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!regs && hard_ecc) { - printk(KERN_ERR "at91_nand: can't get I/O resource " + printk(KERN_ERR "atmel_nand: can't get I/O resource " "regs\nFalling back on software ECC\n"); } @@ -420,15 +420,15 @@ static int __init at91_nand_probe(struct platform_device *pdev) if (hard_ecc && regs) { host->ecc = ioremap(regs->start, regs->end - regs->start + 1); if (host->ecc == NULL) { - printk(KERN_ERR "at91_nand: ioremap failed\n"); + printk(KERN_ERR "atmel_nand: ioremap failed\n"); res = -EIO; goto err_ecc_ioremap; } nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; - nand_chip->ecc.calculate = at91_nand_calculate; - nand_chip->ecc.correct = at91_nand_correct; - nand_chip->ecc.hwctl = at91_nand_hwctl; - nand_chip->ecc.read_page = at91_nand_read_page; + nand_chip->ecc.calculate = atmel_nand_calculate; + nand_chip->ecc.correct = atmel_nand_correct; + nand_chip->ecc.hwctl = atmel_nand_hwctl; + nand_chip->ecc.read_page = atmel_nand_read_page; nand_chip->ecc.bytes = 4; nand_chip->ecc.prepad = 0; nand_chip->ecc.postpad = 0; @@ -440,7 +440,7 @@ static int __init at91_nand_probe(struct platform_device *pdev) nand_chip->options |= NAND_BUSWIDTH_16; platform_set_drvdata(pdev, host); - at91_nand_enable(host); + atmel_nand_enable(host); if (host->board->det_pin) { if (gpio_get_value(host->board->det_pin)) { @@ -463,22 +463,22 @@ static int __init at91_nand_probe(struct platform_device *pdev) /* set ECC page size and oob layout */ switch (mtd->writesize) { case 512: - nand_chip->ecc.layout = &at91_oobinfo_small; - nand_chip->ecc.read_oob = at91_nand_read_oob_512; - nand_chip->ecc.write_oob = at91_nand_write_oob_512; - ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_528); + nand_chip->ecc.layout = &atmel_oobinfo_small; + nand_chip->ecc.read_oob = atmel_nand_read_oob_512; + nand_chip->ecc.write_oob = atmel_nand_write_oob_512; + ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528); break; case 1024: - nand_chip->ecc.layout = &at91_oobinfo_large; - ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_1056); + nand_chip->ecc.layout = &atmel_oobinfo_large; + ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056); break; case 2048: - nand_chip->ecc.layout = &at91_oobinfo_large; - ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_2112); + nand_chip->ecc.layout = &atmel_oobinfo_large; + ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112); break; case 4096: - nand_chip->ecc.layout = &at91_oobinfo_large; - ecc_writel(host->ecc, MR, AT91_ECC_PAGESIZE_4224); + nand_chip->ecc.layout = &atmel_oobinfo_large; + ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224); break; default: /* page size not handled by HW ECC */ @@ -503,7 +503,7 @@ static int __init at91_nand_probe(struct platform_device *pdev) #ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_CMDLINE_PARTS - mtd->name = "at91_nand"; + mtd->name = "atmel_nand"; num_partitions = parse_mtd_partitions(mtd, part_probes, &partitions, 0); #endif @@ -512,7 +512,7 @@ static int __init at91_nand_probe(struct platform_device *pdev) &num_partitions); if ((!partitions) || (num_partitions == 0)) { - printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); + printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n"); res = ENXIO; goto release; } @@ -534,7 +534,7 @@ out: iounmap(host->ecc); err_ecc_ioremap: - at91_nand_disable(host); + atmel_nand_disable(host); platform_set_drvdata(pdev, NULL); iounmap(host->io_base); kfree(host); @@ -544,14 +544,14 @@ err_ecc_ioremap: /* * Remove a NAND device. */ -static int __devexit at91_nand_remove(struct platform_device *pdev) +static int __devexit atmel_nand_remove(struct platform_device *pdev) { - struct at91_nand_host *host = platform_get_drvdata(pdev); + struct atmel_nand_host *host = platform_get_drvdata(pdev); struct mtd_info *mtd = &host->mtd; nand_release(mtd); - at91_nand_disable(host); + atmel_nand_disable(host); iounmap(host->io_base); iounmap(host->ecc); @@ -560,31 +560,31 @@ static int __devexit at91_nand_remove(struct platform_device *pdev) return 0; } -static struct platform_driver at91_nand_driver = { - .probe = at91_nand_probe, - .remove = at91_nand_remove, +static struct platform_driver atmel_nand_driver = { + .probe = atmel_nand_probe, + .remove = atmel_nand_remove, .driver = { - .name = "at91_nand", + .name = "atmel_nand", .owner = THIS_MODULE, }, }; -static int __init at91_nand_init(void) +static int __init atmel_nand_init(void) { - return platform_driver_register(&at91_nand_driver); + return platform_driver_register(&atmel_nand_driver); } -static void __exit at91_nand_exit(void) +static void __exit atmel_nand_exit(void) { - platform_driver_unregister(&at91_nand_driver); + platform_driver_unregister(&atmel_nand_driver); } -module_init(at91_nand_init); -module_exit(at91_nand_exit); +module_init(atmel_nand_init); +module_exit(atmel_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Rick Bronson"); MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91 / AVR32"); -MODULE_ALIAS("platform:at91_nand"); +MODULE_ALIAS("platform:atmel_nand"); diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h index 170db869aac..1ee7f993db1 100644 --- a/drivers/mtd/nand/atmel_nand_ecc.h +++ b/drivers/mtd/nand/atmel_nand_ecc.h @@ -11,26 +11,26 @@ #ifndef ATMEL_NAND_ECC_H #define ATMEL_NAND_ECC_H -#define AT91_ECC_CR 0x00 /* Control register */ -#define AT91_ECC_RST (1 << 0) /* Reset parity */ +#define ATMEL_ECC_CR 0x00 /* Control register */ +#define ATMEL_ECC_RST (1 << 0) /* Reset parity */ -#define AT91_ECC_MR 0x04 /* Mode register */ -#define AT91_ECC_PAGESIZE (3 << 0) /* Page Size */ -#define AT91_ECC_PAGESIZE_528 (0) -#define AT91_ECC_PAGESIZE_1056 (1) -#define AT91_ECC_PAGESIZE_2112 (2) -#define AT91_ECC_PAGESIZE_4224 (3) +#define ATMEL_ECC_MR 0x04 /* Mode register */ +#define ATMEL_ECC_PAGESIZE (3 << 0) /* Page Size */ +#define ATMEL_ECC_PAGESIZE_528 (0) +#define ATMEL_ECC_PAGESIZE_1056 (1) +#define ATMEL_ECC_PAGESIZE_2112 (2) +#define ATMEL_ECC_PAGESIZE_4224 (3) -#define AT91_ECC_SR 0x08 /* Status register */ -#define AT91_ECC_RECERR (1 << 0) /* Recoverable Error */ -#define AT91_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ -#define AT91_ECC_MULERR (1 << 2) /* Multiple Errors */ +#define ATMEL_ECC_SR 0x08 /* Status register */ +#define ATMEL_ECC_RECERR (1 << 0) /* Recoverable Error */ +#define ATMEL_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ +#define ATMEL_ECC_MULERR (1 << 2) /* Multiple Errors */ -#define AT91_ECC_PR 0x0c /* Parity register */ -#define AT91_ECC_BITADDR (0xf << 0) /* Bit Error Address */ -#define AT91_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ +#define ATMEL_ECC_PR 0x0c /* Parity register */ +#define ATMEL_ECC_BITADDR (0xf << 0) /* Bit Error Address */ +#define ATMEL_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ -#define AT91_ECC_NPR 0x10 /* NParity register */ -#define AT91_ECC_NPARITY (0xffff << 0) /* NParity */ +#define ATMEL_ECC_NPR 0x10 /* NParity register */ +#define ATMEL_ECC_NPARITY (0xffff << 0) /* NParity */ #endif diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h index dc189f01c5b..6296922a684 100644 --- a/include/asm-arm/arch-at91/board.h +++ b/include/asm-arm/arch-at91/board.h @@ -85,7 +85,7 @@ struct at91_usbh_data { extern void __init at91_add_device_usbh(struct at91_usbh_data *data); /* NAND / SmartMedia */ -struct at91_nand_data { +struct atmel_nand_data { u8 enable_pin; /* chip enable */ u8 det_pin; /* card detect */ u8 rdy_pin; /* ready/busy */ @@ -94,7 +94,7 @@ struct at91_nand_data { u8 bus_width_16; /* buswidth is 16 bit */ struct mtd_partition* (*partition_info)(int, int*); }; -extern void __init at91_add_device_nand(struct at91_nand_data *data); +extern void __init at91_add_device_nand(struct atmel_nand_data *data); /* I2C*/ extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices); -- cgit v1.2.3-70-g09d2 From 9fc697b0b01416edae99dd9c5c49fb69c9282744 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 10 Jun 2008 08:57:27 +0100 Subject: [ARM] 5082/1: pxa: Definition for the third USB port control register UP3OCR This adds the definition for the third USB port control register UP3OCR. It is used on the EZX GSM mobile phones. Signed-off-by: Stefan Schmidt Acked-by: Eric Miao Signed-off-by: Russell King --- include/asm-arm/arch-pxa/pxa27x-udc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/pxa27x-udc.h b/include/asm-arm/arch-pxa/pxa27x-udc.h index 2d4e9cd3a5e..bc1cf7d0773 100644 --- a/include/asm-arm/arch-pxa/pxa27x-udc.h +++ b/include/asm-arm/arch-pxa/pxa27x-udc.h @@ -82,6 +82,7 @@ Interrupt Enable */ #define UP2OCR __REG(0x40600020) /* USB Port 2 Output Control register */ +#define UP3OCR __REG(0x40600024) /* USB Port 2 Output Control register */ #define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ #define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ -- cgit v1.2.3-70-g09d2 From 2239aff6ab2b95af1f628eee7a809f21c41605b3 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 31 Mar 2008 12:38:31 -0400 Subject: [ARM] cache align destination pointer when copying memory for some processors The implementation for memory copy functions on ARM had a (disabled) provision for aligning the source pointer before loading registers with data. Turns out that aligning the _destination_ pointer is much more useful, as the read side is already sufficiently helped with the use of preload. So this changes the definition of the CALGN() macro to target the destination pointer instead, and turns it on for Feroceon processors where the gain is very noticeable. Signed-off-by: Nicolas Pitre Signed-off-by: Lennert Buytenhek --- arch/arm/lib/copy_template.S | 12 ++---------- arch/arm/lib/memmove.S | 12 ++---------- include/asm-arm/assembler.h | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 20 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S index cab355c0c1f..139cce64605 100644 --- a/arch/arm/lib/copy_template.S +++ b/arch/arm/lib/copy_template.S @@ -12,14 +12,6 @@ * published by the Free Software Foundation. */ -/* - * This can be used to enable code to cacheline align the source pointer. - * Experiments on tested architectures (StrongARM and XScale) didn't show - * this a worthwhile thing to do. That might be different in the future. - */ -//#define CALGN(code...) code -#define CALGN(code...) - /* * Theory of operation * ------------------- @@ -82,7 +74,7 @@ stmfd sp!, {r5 - r8} blt 5f - CALGN( ands ip, r1, #31 ) + CALGN( ands ip, r0, #31 ) CALGN( rsb r3, ip, #32 ) CALGN( sbcnes r4, r3, r2 ) @ C is always set here CALGN( bcs 2f ) @@ -168,7 +160,7 @@ subs r2, r2, #28 blt 14f - CALGN( ands ip, r1, #31 ) + CALGN( ands ip, r0, #31 ) CALGN( rsb ip, ip, #32 ) CALGN( sbcnes r4, ip, r2 ) @ C is always set here CALGN( subcc r2, r2, ip ) diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S index 018522c3ff2..2e301b7bd8f 100644 --- a/arch/arm/lib/memmove.S +++ b/arch/arm/lib/memmove.S @@ -13,14 +13,6 @@ #include #include -/* - * This can be used to enable code to cacheline align the source pointer. - * Experiments on tested architectures (StrongARM and XScale) didn't show - * this a worthwhile thing to do. That might be different in the future. - */ -//#define CALGN(code...) code -#define CALGN(code...) - .text /* @@ -55,7 +47,7 @@ ENTRY(memmove) stmfd sp!, {r5 - r8} blt 5f - CALGN( ands ip, r1, #31 ) + CALGN( ands ip, r0, #31 ) CALGN( sbcnes r4, ip, r2 ) @ C is always set here CALGN( bcs 2f ) CALGN( adr r4, 6f ) @@ -139,7 +131,7 @@ ENTRY(memmove) subs r2, r2, #28 blt 14f - CALGN( ands ip, r1, #31 ) + CALGN( ands ip, r0, #31 ) CALGN( sbcnes r4, ip, r2 ) @ C is always set here CALGN( subcc r2, r2, ip ) CALGN( bcc 15f ) diff --git a/include/asm-arm/assembler.h b/include/asm-arm/assembler.h index fce83282082..911393b2c6f 100644 --- a/include/asm-arm/assembler.h +++ b/include/asm-arm/assembler.h @@ -55,6 +55,21 @@ #define PLD(code...) #endif +/* + * This can be used to enable code to cacheline align the destination + * pointer when bulk writing to memory. Experiments on StrongARM and + * XScale didn't show this a worthwhile thing to do when the cache is not + * set to write-allocate (this would need further testing on XScale when WA + * is used). + * + * On Feroceon there is much to gain however, regardless of cache mode. + */ +#ifdef CONFIG_CPU_FEROCEON +#define CALGN(code...) code +#else +#define CALGN(code...) +#endif + /* * Enable and disable interrupts */ -- cgit v1.2.3-70-g09d2 From 6eef84a5496c678ab27b72bec0fc785c9cee063b Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 28 May 2008 16:20:56 +0200 Subject: [ARM] Orion: delete unused IO_SPACE_REMAP define This define isn't used anywhere in the kernel tree -- nuke it. Signed-off-by: Lennert Buytenhek Acked-by: Russell King --- include/asm-arm/arch-orion5x/io.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-orion5x/io.h b/include/asm-arm/arch-orion5x/io.h index 50f8c880220..d9a4b2065e5 100644 --- a/include/asm-arm/arch-orion5x/io.h +++ b/include/asm-arm/arch-orion5x/io.h @@ -14,7 +14,6 @@ #include "orion5x.h" #define IO_SPACE_LIMIT 0xffffffff -#define IO_SPACE_REMAP ORION5X_PCI_SYS_IO_BASE static inline void __iomem * __arch_ioremap(unsigned long paddr, size_t size, unsigned int mtype) -- cgit v1.2.3-70-g09d2 From d2b2a6bbc020e5a9a244f318d28515081e922882 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 31 May 2008 08:30:40 +0200 Subject: [ARM] Orion: add 88F5181L (Orion-VoIP) support Signed-off-by: Lennert Buytenhek Acked-by: Russell King --- arch/arm/Kconfig | 3 ++- arch/arm/mach-orion5x/common.c | 4 +++- include/asm-arm/arch-orion5x/orion5x.h | 6 ++++-- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a91b9ac9a0e..4bdf598611d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -386,7 +386,8 @@ config ARCH_ORION5X select PLAT_ORION help Support for the following Marvell Orion 5x series SoCs: - Orion-1 (5181), Orion-NAS (5182), Orion-2 (5281.) + Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182), + Orion-2 (5281). config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index b2986717319..faf4e321191 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -394,8 +394,10 @@ static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name) } else if (*dev == MV88F5181_DEV_ID) { if (*rev == MV88F5181_REV_B1) { *dev_name = "MV88F5181-Rev-B1"; + } else if (*rev == MV88F5181L_REV_A1) { + *dev_name = "MV88F5181L-Rev-A1"; } else { - *dev_name = "MV88F5181-Rev-Unsupported"; + *dev_name = "MV88F5181(L)-Rev-Unsupported"; } } else { *dev_name = "Device-Unknown"; diff --git a/include/asm-arm/arch-orion5x/orion5x.h b/include/asm-arm/arch-orion5x/orion5x.h index 206ddd71e19..20f7b406a79 100644 --- a/include/asm-arm/arch-orion5x/orion5x.h +++ b/include/asm-arm/arch-orion5x/orion5x.h @@ -2,7 +2,7 @@ * include/asm-arm/arch-orion5x/orion5x.h * * Generic definitions of Orion SoC flavors: - * Orion-1, Orion-NAS, Orion-VoIP, and Orion-2. + * Orion-1, Orion-VoIP, Orion-NAS, and Orion-2. * * Maintainer: Tzachi Perelstein * @@ -63,9 +63,11 @@ /******************************************************************************* * Supported Devices & Revisions ******************************************************************************/ -/* Orion-1 (88F5181) */ +/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */ #define MV88F5181_DEV_ID 0x5181 #define MV88F5181_REV_B1 3 +#define MV88F5181L_REV_A0 8 +#define MV88F5181L_REV_A1 9 /* Orion-NAS (88F5182) */ #define MV88F5182_DEV_ID 0x5182 #define MV88F5182_REV_A2 2 -- cgit v1.2.3-70-g09d2 From 0e3bc0503f7e7b5b0bd4416f43eeeca1b661e66e Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 4 Jun 2008 03:16:21 +0200 Subject: [ARM] Orion: use linux/serial_reg.h for Orion uncompress.h Signed-off-by: Lennert Buytenhek --- include/asm-arm/arch-orion5x/uncompress.h | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-orion5x/uncompress.h b/include/asm-arm/arch-orion5x/uncompress.h index 5c13d4fafb4..7548cedf2d7 100644 --- a/include/asm-arm/arch-orion5x/uncompress.h +++ b/include/asm-arm/arch-orion5x/uncompress.h @@ -8,23 +8,38 @@ * warranty of any kind, whether express or implied. */ +#include #include -#define MV_UART_THR ((volatile unsigned char *)(UART0_PHYS_BASE + 0x0)) -#define MV_UART_LSR ((volatile unsigned char *)(UART0_PHYS_BASE + 0x14)) - -#define LSR_THRE 0x20 +#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE) static void putc(const char c) { - int j = 0x1000; - while (--j && !(*MV_UART_LSR & LSR_THRE)) + unsigned char *base = SERIAL_BASE; + int i; + + for (i = 0; i < 0x1000; i++) { + if (base[UART_LSR << 2] & UART_LSR_THRE) + break; barrier(); - *MV_UART_THR = c; + } + + base[UART_TX << 2] = c; } static void flush(void) { + unsigned char *base = SERIAL_BASE; + unsigned char mask; + int i; + + mask = UART_LSR_TEMT | UART_LSR_THRE; + + for (i = 0; i < 0x1000; i++) { + if ((base[UART_LSR << 2] & mask) == mask) + break; + barrier(); + } } /* -- cgit v1.2.3-70-g09d2 From 79e90dd5aa95adfdc3117db8a559da3d0195ba58 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 28 May 2008 16:43:48 +0200 Subject: [ARM] Orion: nuke orion5x_{read,write} Nuke the Orion-specific orion5x_{read,write} wrappers. Signed-off-by: Lennert Buytenhek --- arch/arm/mach-orion5x/addr-map.c | 18 +++++++-------- arch/arm/mach-orion5x/db88f5281-setup.c | 2 +- arch/arm/mach-orion5x/dns323-setup.c | 2 +- arch/arm/mach-orion5x/gpio.c | 40 ++++++++++++++++----------------- arch/arm/mach-orion5x/irq.c | 18 +++++++-------- arch/arm/mach-orion5x/pci.c | 34 ++++++++++++++-------------- include/asm-arm/arch-orion5x/io.h | 7 ++---- 7 files changed, 59 insertions(+), 62 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c index 267e9f960a5..6f0dbda6c44 100644 --- a/arch/arm/mach-orion5x/addr-map.c +++ b/arch/arm/mach-orion5x/addr-map.c @@ -94,16 +94,16 @@ static void __init setup_cpu_win(int win, u32 base, u32 size, return; } - orion5x_write(CPU_WIN_BASE(win), base & 0xffff0000); - orion5x_write(CPU_WIN_CTRL(win), - ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1); + writel(base & 0xffff0000, CPU_WIN_BASE(win)); + writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1, + CPU_WIN_CTRL(win)); if (orion5x_cpu_win_can_remap(win)) { if (remap < 0) remap = base; - orion5x_write(CPU_WIN_REMAP_LO(win), remap & 0xffff0000); - orion5x_write(CPU_WIN_REMAP_HI(win), 0); + writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win)); + writel(0, CPU_WIN_REMAP_HI(win)); } } @@ -116,11 +116,11 @@ void __init orion5x_setup_cpu_mbus_bridge(void) * First, disable and clear windows. */ for (i = 0; i < 8; i++) { - orion5x_write(CPU_WIN_BASE(i), 0); - orion5x_write(CPU_WIN_CTRL(i), 0); + writel(0, CPU_WIN_BASE(i)); + writel(0, CPU_WIN_CTRL(i)); if (orion5x_cpu_win_can_remap(i)) { - orion5x_write(CPU_WIN_REMAP_LO(i), 0); - orion5x_write(CPU_WIN_REMAP_HI(i), 0); + writel(0, CPU_WIN_REMAP_LO(i)); + writel(0, CPU_WIN_REMAP_HI(i)); } } diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c index 00ad36ade57..88405e74e5e 100644 --- a/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/arch/arm/mach-orion5x/db88f5281-setup.c @@ -330,7 +330,7 @@ static void __init db88f5281_init(void) orion5x_init(); orion5x_mpp_conf(db88f5281_mpp_modes); - orion5x_write(MPP_DEV_CTRL, 0); /* DEV_D[31:16] */ + writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */ /* * Configure peripherals. diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 64730a045ff..3791ca6f001 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -269,7 +269,7 @@ static void __init dns323_init(void) orion5x_init(); orion5x_mpp_conf(dns323_mpp_modes); - orion5x_write(MPP_DEV_CTRL, 0); /* DEV_D[31:16] */ + writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */ /* * Configure peripherals. diff --git a/arch/arm/mach-orion5x/gpio.c b/arch/arm/mach-orion5x/gpio.c index 9fba6a16dc1..d09797990f4 100644 --- a/arch/arm/mach-orion5x/gpio.c +++ b/arch/arm/mach-orion5x/gpio.c @@ -96,10 +96,10 @@ int gpio_get_value(unsigned pin) { int val, mask = 1 << pin; - if (orion5x_read(GPIO_IO_CONF) & mask) - val = orion5x_read(GPIO_DATA_IN) ^ orion5x_read(GPIO_IN_POL); + if (readl(GPIO_IO_CONF) & mask) + val = readl(GPIO_DATA_IN) ^ readl(GPIO_IN_POL); else - val = orion5x_read(GPIO_OUT); + val = readl(GPIO_OUT); return val & mask; } @@ -191,39 +191,39 @@ void gpio_display(void) printk("GPIO, free\n"); } else { printk("GPIO, used by %s, ", gpio_label[i]); - if (orion5x_read(GPIO_IO_CONF) & (1 << i)) { + if (readl(GPIO_IO_CONF) & (1 << i)) { printk("input, active %s, level %s, edge %s\n", - ((orion5x_read(GPIO_IN_POL) >> i) & 1) ? "low" : "high", - ((orion5x_read(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked", - ((orion5x_read(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked"); + ((readl(GPIO_IN_POL) >> i) & 1) ? "low" : "high", + ((readl(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked", + ((readl(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked"); } else { - printk("output, val=%d\n", (orion5x_read(GPIO_OUT) >> i) & 1); + printk("output, val=%d\n", (readl(GPIO_OUT) >> i) & 1); } } } printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n", - MPP_0_7_CTRL, orion5x_read(MPP_0_7_CTRL)); + MPP_0_7_CTRL, readl(MPP_0_7_CTRL)); printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n", - MPP_8_15_CTRL, orion5x_read(MPP_8_15_CTRL)); + MPP_8_15_CTRL, readl(MPP_8_15_CTRL)); printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n", - MPP_16_19_CTRL, orion5x_read(MPP_16_19_CTRL)); + MPP_16_19_CTRL, readl(MPP_16_19_CTRL)); printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n", - MPP_DEV_CTRL, orion5x_read(MPP_DEV_CTRL)); + MPP_DEV_CTRL, readl(MPP_DEV_CTRL)); printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n", - GPIO_OUT, orion5x_read(GPIO_OUT)); + GPIO_OUT, readl(GPIO_OUT)); printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n", - GPIO_IO_CONF, orion5x_read(GPIO_IO_CONF)); + GPIO_IO_CONF, readl(GPIO_IO_CONF)); printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n", - GPIO_BLINK_EN, orion5x_read(GPIO_BLINK_EN)); + GPIO_BLINK_EN, readl(GPIO_BLINK_EN)); printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n", - GPIO_IN_POL, orion5x_read(GPIO_IN_POL)); + GPIO_IN_POL, readl(GPIO_IN_POL)); printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n", - GPIO_DATA_IN, orion5x_read(GPIO_DATA_IN)); + GPIO_DATA_IN, readl(GPIO_DATA_IN)); printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n", - GPIO_LEVEL_MASK, orion5x_read(GPIO_LEVEL_MASK)); + GPIO_LEVEL_MASK, readl(GPIO_LEVEL_MASK)); printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n", - GPIO_EDGE_CAUSE, orion5x_read(GPIO_EDGE_CAUSE)); + GPIO_EDGE_CAUSE, readl(GPIO_EDGE_CAUSE)); printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n", - GPIO_EDGE_MASK, orion5x_read(GPIO_EDGE_MASK)); + GPIO_EDGE_MASK, readl(GPIO_EDGE_MASK)); } diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c index dd21f38c5d3..e2a0084ab4a 100644 --- a/arch/arm/mach-orion5x/irq.c +++ b/arch/arm/mach-orion5x/irq.c @@ -82,7 +82,7 @@ static int orion5x_gpio_set_irq_type(u32 irq, u32 type) int pin = irq_to_gpio(irq); struct irq_desc *desc; - if ((orion5x_read(GPIO_IO_CONF) & (1 << pin)) == 0) { + if ((readl(GPIO_IO_CONF) & (1 << pin)) == 0) { printk(KERN_ERR "orion5x_gpio_set_irq_type failed " "(irq %d, pin %d).\n", irq, pin); return -EINVAL; @@ -117,7 +117,7 @@ static int orion5x_gpio_set_irq_type(u32 irq, u32 type) /* * set initial polarity based on current input level */ - if ((orion5x_read(GPIO_IN_POL) ^ orion5x_read(GPIO_DATA_IN)) + if ((readl(GPIO_IN_POL) ^ readl(GPIO_DATA_IN)) & (1 << pin)) orion5x_setbits(GPIO_IN_POL, (1 << pin)); /* falling */ else @@ -149,8 +149,8 @@ static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31); offs = (irq - IRQ_ORION5X_GPIO_0_7) * 8; - cause = (orion5x_read(GPIO_DATA_IN) & orion5x_read(GPIO_LEVEL_MASK)) | - (orion5x_read(GPIO_EDGE_CAUSE) & orion5x_read(GPIO_EDGE_MASK)); + cause = (readl(GPIO_DATA_IN) & readl(GPIO_LEVEL_MASK)) | + (readl(GPIO_EDGE_CAUSE) & readl(GPIO_EDGE_MASK)); for (pin = offs; pin < offs + 8; pin++) { if (cause & (1 << pin)) { @@ -158,9 +158,9 @@ static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) desc = irq_desc + irq; if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) { /* Swap polarity (race with GPIO line) */ - u32 polarity = orion5x_read(GPIO_IN_POL); + u32 polarity = readl(GPIO_IN_POL); polarity ^= 1 << pin; - orion5x_write(GPIO_IN_POL, polarity); + writel(polarity, GPIO_IN_POL); } desc_handle_irq(irq, desc); } @@ -175,9 +175,9 @@ static void __init orion5x_init_gpio_irq(void) /* * Mask and clear GPIO IRQ interrupts */ - orion5x_write(GPIO_LEVEL_MASK, 0x0); - orion5x_write(GPIO_EDGE_MASK, 0x0); - orion5x_write(GPIO_EDGE_CAUSE, 0x0); + writel(0x0, GPIO_LEVEL_MASK); + writel(0x0, GPIO_EDGE_MASK); + writel(0x0, GPIO_EDGE_CAUSE); /* * Register chained level handlers for GPIO IRQs by default. diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 275a50046c1..025ef63b1dd 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -268,7 +268,7 @@ static DEFINE_SPINLOCK(orion5x_pci_lock); static int orion5x_pci_local_bus_nr(void) { - u32 conf = orion5x_read(PCI_P2P_CONF); + u32 conf = readl(PCI_P2P_CONF); return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); } @@ -278,11 +278,11 @@ static int orion5x_pci_hw_rd_conf(int bus, int dev, u32 func, unsigned long flags; spin_lock_irqsave(&orion5x_pci_lock, flags); - orion5x_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) | - PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | - PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN); + writel(PCI_CONF_BUS(bus) | + PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | + PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR); - *val = orion5x_read(PCI_CONF_DATA); + *val = readl(PCI_CONF_DATA); if (size == 1) *val = (*val >> (8*(where & 0x3))) & 0xff; @@ -302,9 +302,9 @@ static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func, spin_lock_irqsave(&orion5x_pci_lock, flags); - orion5x_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) | - PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | - PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN); + writel(PCI_CONF_BUS(bus) | + PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | + PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR); if (size == 4) { __raw_writel(val, PCI_CONF_DATA); @@ -355,9 +355,9 @@ static struct pci_ops pci_ops = { static void __init orion5x_pci_set_bus_nr(int nr) { - u32 p2p = orion5x_read(PCI_P2P_CONF); + u32 p2p = readl(PCI_P2P_CONF); - if (orion5x_read(PCI_MODE) & PCI_MODE_PCIX) { + if (readl(PCI_MODE) & PCI_MODE_PCIX) { /* * PCI-X mode */ @@ -374,7 +374,7 @@ static void __init orion5x_pci_set_bus_nr(int nr) */ p2p &= ~PCI_P2P_BUS_MASK; p2p |= (nr << PCI_P2P_BUS_OFFS); - orion5x_write(PCI_P2P_CONF, p2p); + writel(p2p, PCI_P2P_CONF); } } @@ -401,7 +401,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram) * First, disable windows. */ win_enable = 0xffffffff; - orion5x_write(PCI_BAR_ENABLE, win_enable); + writel(win_enable, PCI_BAR_ENABLE); /* * Setup windows for DDR banks. @@ -427,10 +427,10 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram) */ reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index); orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0); - orion5x_write(PCI_BAR_SIZE_DDR_CS(cs->cs_index), - (cs->size - 1) & 0xfffff000); - orion5x_write(PCI_BAR_REMAP_DDR_CS(cs->cs_index), - cs->base & 0xfffff000); + writel((cs->size - 1) & 0xfffff000, + PCI_BAR_SIZE_DDR_CS(cs->cs_index)); + writel(cs->base & 0xfffff000, + PCI_BAR_REMAP_DDR_CS(cs->cs_index)); /* * Enable decode window for this chip select. @@ -441,7 +441,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram) /* * Re-enable decode windows. */ - orion5x_write(PCI_BAR_ENABLE, win_enable); + writel(win_enable, PCI_BAR_ENABLE); /* * Disable automatic update of address remaping when writing to BARs. diff --git a/include/asm-arm/arch-orion5x/io.h b/include/asm-arm/arch-orion5x/io.h index d9a4b2065e5..59f1bc96a23 100644 --- a/include/asm-arm/arch-orion5x/io.h +++ b/include/asm-arm/arch-orion5x/io.h @@ -52,15 +52,12 @@ static inline void __iomem *__io(unsigned long addr) /***************************************************************************** * Helpers to access Orion registers ****************************************************************************/ -#define orion5x_read(r) __raw_readl(r) -#define orion5x_write(r, val) __raw_writel(val, r) - /* * These are not preempt-safe. Locks, if needed, must be taken * care of by the caller. */ -#define orion5x_setbits(r, mask) orion5x_write((r), orion5x_read(r) | (mask)) -#define orion5x_clrbits(r, mask) orion5x_write((r), orion5x_read(r) & ~(mask)) +#define orion5x_setbits(r, mask) writel(readl(r) | (mask), (r)) +#define orion5x_clrbits(r, mask) writel(readl(r) & ~(mask), (r)) #endif -- cgit v1.2.3-70-g09d2 From 1219715de70956557b9dedf3ee021a73d4f4ec52 Mon Sep 17 00:00:00 2001 From: Ke Wei Date: Fri, 23 May 2008 10:23:22 +0200 Subject: [ARM] Orion: add a separate BRIDGE_INT_TIMER1_CLR define Some Feroceon-based SoCs have an MBUS bridge interrupt controller that requires writing a one instead of a zero to clear edge interrupt sources such as timer expiry. This patch adds a new BRIDGE_INT_TIMER1_CLR define, which platform code can set to either ~BRIDGE_INT_TIMER1 (write-zero-to-clear) or BRIDGE_INT_TIMER1 (write-one-to-clear) depending on the platform. Signed-off-by: Lennert Buytenhek --- arch/arm/plat-orion/time.c | 6 +++--- include/asm-arm/arch-orion5x/orion5x.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 28b5285446e..93c4ef9f006 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -74,7 +74,7 @@ orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev) /* * Clear and enable clockevent timer interrupt. */ - writel(~BRIDGE_INT_TIMER1, BRIDGE_CAUSE); + writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE); u = readl(BRIDGE_MASK); u |= BRIDGE_INT_TIMER1; @@ -138,7 +138,7 @@ orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) /* * ACK pending timer interrupt. */ - writel(~BRIDGE_INT_TIMER1, BRIDGE_CAUSE); + writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE); } local_irq_restore(flags); @@ -159,7 +159,7 @@ static irqreturn_t orion_timer_interrupt(int irq, void *dev_id) /* * ACK timer interrupt and call event handler. */ - writel(~BRIDGE_INT_TIMER1, BRIDGE_CAUSE); + writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE); orion_clkevt.event_handler(&orion_clkevt); return IRQ_HANDLED; diff --git a/include/asm-arm/arch-orion5x/orion5x.h b/include/asm-arm/arch-orion5x/orion5x.h index 20f7b406a79..10257f5c5e9 100644 --- a/include/asm-arm/arch-orion5x/orion5x.h +++ b/include/asm-arm/arch-orion5x/orion5x.h @@ -154,6 +154,7 @@ #define BRIDGE_MASK ORION5X_BRIDGE_REG(0x114) #define BRIDGE_INT_TIMER0 0x0002 #define BRIDGE_INT_TIMER1 0x0004 +#define BRIDGE_INT_TIMER1_CLR (~0x0004) #define MAIN_IRQ_CAUSE ORION5X_BRIDGE_REG(0x200) #define MAIN_IRQ_MASK ORION5X_BRIDGE_REG(0x204) -- cgit v1.2.3-70-g09d2 From 777f9bebad3476b7dbf5cd8abbd3414139ca0e48 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 22 Jun 2008 22:45:02 +0200 Subject: [ARM] add Marvell Loki (88RC8480) SoC support The Marvell Loki (88RC8480) is an ARM SoC based on a Feroceon CPU core running at between 400 MHz and 1.0 GHz, and features a 64 bit DDR controller, 512K of internal SRAM, two x4 PCI-Express ports, two Gigabit Ethernet ports, two 4x SAS/SATA controllers, two UARTs, two TWSI controllers, and IDMA/XOR engines. This patch adds support for the Marvell LB88RC8480 Development Board, enabling the use of the PCIe interfaces, the ethernet interfaces, the TWSI interfaces and the UARTs. Signed-off-by: Lennert Buytenhek --- arch/arm/Kconfig | 10 ++ arch/arm/Makefile | 1 + arch/arm/mach-loki/Kconfig | 13 ++ arch/arm/mach-loki/Makefile | 3 + arch/arm/mach-loki/Makefile.boot | 3 + arch/arm/mach-loki/addr-map.c | 121 +++++++++++++ arch/arm/mach-loki/common.c | 305 ++++++++++++++++++++++++++++++++ arch/arm/mach-loki/common.h | 36 ++++ arch/arm/mach-loki/irq.c | 21 +++ arch/arm/mach-loki/lb88rc8480-setup.c | 100 +++++++++++ arch/arm/mm/Kconfig | 2 +- include/asm-arm/arch-loki/debug-macro.S | 20 +++ include/asm-arm/arch-loki/dma.h | 1 + include/asm-arm/arch-loki/entry-macro.S | 30 ++++ include/asm-arm/arch-loki/hardware.h | 15 ++ include/asm-arm/arch-loki/io.h | 26 +++ include/asm-arm/arch-loki/irqs.h | 58 ++++++ include/asm-arm/arch-loki/loki.h | 97 ++++++++++ include/asm-arm/arch-loki/memory.h | 14 ++ include/asm-arm/arch-loki/system.h | 37 ++++ include/asm-arm/arch-loki/timex.h | 11 ++ include/asm-arm/arch-loki/uncompress.h | 47 +++++ include/asm-arm/arch-loki/vmalloc.h | 5 + 23 files changed, 975 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-loki/Kconfig create mode 100644 arch/arm/mach-loki/Makefile create mode 100644 arch/arm/mach-loki/Makefile.boot create mode 100644 arch/arm/mach-loki/addr-map.c create mode 100644 arch/arm/mach-loki/common.c create mode 100644 arch/arm/mach-loki/common.h create mode 100644 arch/arm/mach-loki/irq.c create mode 100644 arch/arm/mach-loki/lb88rc8480-setup.c create mode 100644 include/asm-arm/arch-loki/debug-macro.S create mode 100644 include/asm-arm/arch-loki/dma.h create mode 100644 include/asm-arm/arch-loki/entry-macro.S create mode 100644 include/asm-arm/arch-loki/hardware.h create mode 100644 include/asm-arm/arch-loki/io.h create mode 100644 include/asm-arm/arch-loki/irqs.h create mode 100644 include/asm-arm/arch-loki/loki.h create mode 100644 include/asm-arm/arch-loki/memory.h create mode 100644 include/asm-arm/arch-loki/system.h create mode 100644 include/asm-arm/arch-loki/timex.h create mode 100644 include/asm-arm/arch-loki/uncompress.h create mode 100644 include/asm-arm/arch-loki/vmalloc.h (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4bdf598611d..7a725f89b84 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -370,6 +370,14 @@ config ARCH_NS9XXX +config ARCH_LOKI + bool "Marvell Loki (88RC8480)" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select PLAT_ORION + help + Support for the Marvell Loki (88RC8480) SoC. + config ARCH_MXC bool "Freescale MXC/iMX-based" select ARCH_MTD_XIP @@ -508,6 +516,8 @@ source "arch/arm/mach-ixp2000/Kconfig" source "arch/arm/mach-ixp23xx/Kconfig" +source "arch/arm/mach-loki/Kconfig" + source "arch/arm/mach-pxa/Kconfig" source "arch/arm/mach-sa1100/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e72db27e0ba..2ea32a70c97 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -140,6 +140,7 @@ endif machine-$(CONFIG_ARCH_MX3) := mx3 machine-$(CONFIG_ARCH_ORION5X) := orion5x machine-$(CONFIG_ARCH_MSM7X00A) := msm + machine-$(CONFIG_ARCH_LOKI) := loki ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. diff --git a/arch/arm/mach-loki/Kconfig b/arch/arm/mach-loki/Kconfig new file mode 100644 index 00000000000..0045bdd761c --- /dev/null +++ b/arch/arm/mach-loki/Kconfig @@ -0,0 +1,13 @@ +if ARCH_LOKI + +menu "Marvell Loki (88RC8480) Implementations" + +config MACH_LB88RC8480 + bool "Marvell LB88RC8480 Development Board" + help + Say 'Y' here if you want your kernel to support the + Marvell LB88RC8480 Development Board. + +endmenu + +endif diff --git a/arch/arm/mach-loki/Makefile b/arch/arm/mach-loki/Makefile new file mode 100644 index 00000000000..d43233ee590 --- /dev/null +++ b/arch/arm/mach-loki/Makefile @@ -0,0 +1,3 @@ +obj-y += common.o addr-map.o irq.o + +obj-$(CONFIG_MACH_LB88RC8480) += lb88rc8480-setup.o diff --git a/arch/arm/mach-loki/Makefile.boot b/arch/arm/mach-loki/Makefile.boot new file mode 100644 index 00000000000..67039c3e0c4 --- /dev/null +++ b/arch/arm/mach-loki/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-loki/addr-map.c b/arch/arm/mach-loki/addr-map.c new file mode 100644 index 00000000000..ba25e56ade5 --- /dev/null +++ b/arch/arm/mach-loki/addr-map.c @@ -0,0 +1,121 @@ +/* + * arch/arm/mach-loki/addr-map.c + * + * Address map functions for Marvell Loki (88RC8480) SoCs + * + * 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 +#include +#include +#include +#include +#include "common.h" + +/* + * Generic Address Decode Windows bit settings + */ +#define TARGET_DDR 0 +#define TARGET_DEV_BUS 1 +#define TARGET_PCIE0 3 +#define TARGET_PCIE1 4 +#define ATTR_DEV_BOOT 0x0f +#define ATTR_DEV_CS2 0x1b +#define ATTR_DEV_CS1 0x1d +#define ATTR_DEV_CS0 0x1e +#define ATTR_PCIE_IO 0x51 +#define ATTR_PCIE_MEM 0x59 + +/* + * Helpers to get DDR bank info + */ +#define DDR_SIZE_CS(n) DDR_REG(0x1500 + ((n) << 3)) +#define DDR_BASE_CS(n) DDR_REG(0x1504 + ((n) << 3)) + +/* + * CPU Address Decode Windows registers + */ +#define CPU_WIN_CTRL(n) BRIDGE_REG(0x000 | ((n) << 4)) +#define CPU_WIN_BASE(n) BRIDGE_REG(0x004 | ((n) << 4)) +#define CPU_WIN_REMAP_LO(n) BRIDGE_REG(0x008 | ((n) << 4)) +#define CPU_WIN_REMAP_HI(n) BRIDGE_REG(0x00c | ((n) << 4)) + + +struct mbus_dram_target_info loki_mbus_dram_info; + +static void __init setup_cpu_win(int win, u32 base, u32 size, + u8 target, u8 attr, int remap) +{ + u32 ctrl; + + base &= 0xffff0000; + ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (1 << 5) | target; + + writel(base, CPU_WIN_BASE(win)); + writel(ctrl, CPU_WIN_CTRL(win)); + if (win < 2) { + if (remap < 0) + remap = base; + + writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win)); + writel(0, CPU_WIN_REMAP_HI(win)); + } +} + +void __init loki_setup_cpu_mbus(void) +{ + int i; + int cs; + + /* + * First, disable and clear windows. + */ + for (i = 0; i < 8; i++) { + writel(0, CPU_WIN_BASE(i)); + writel(0, CPU_WIN_CTRL(i)); + if (i < 2) { + writel(0, CPU_WIN_REMAP_LO(i)); + writel(0, CPU_WIN_REMAP_HI(i)); + } + } + + /* + * Setup windows for PCIe IO+MEM space. + */ + setup_cpu_win(2, LOKI_PCIE0_MEM_PHYS_BASE, LOKI_PCIE0_MEM_SIZE, + TARGET_PCIE0, ATTR_PCIE_MEM, -1); + setup_cpu_win(3, LOKI_PCIE1_MEM_PHYS_BASE, LOKI_PCIE1_MEM_SIZE, + TARGET_PCIE1, ATTR_PCIE_MEM, -1); + + /* + * Setup MBUS dram target info. + */ + loki_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; + + for (i = 0, cs = 0; i < 4; i++) { + u32 base = readl(DDR_BASE_CS(i)); + u32 size = readl(DDR_SIZE_CS(i)); + + /* + * Chip select enabled? + */ + if (size & 1) { + struct mbus_dram_window *w; + + w = &loki_mbus_dram_info.cs[cs++]; + w->cs_index = i; + w->mbus_attr = 0xf & ~(1 << i); + w->base = base & 0xffff0000; + w->size = (size | 0x0000ffff) + 1; + } + } + loki_mbus_dram_info.num_cs = cs; +} + +void __init loki_setup_dev_boot_win(u32 base, u32 size) +{ + setup_cpu_win(4, base, size, TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); +} diff --git a/arch/arm/mach-loki/common.c b/arch/arm/mach-loki/common.c new file mode 100644 index 00000000000..410f50399dd --- /dev/null +++ b/arch/arm/mach-loki/common.c @@ -0,0 +1,305 @@ +/* + * arch/arm/mach-loki/common.c + * + * Core functions for Marvell Loki (88RC8480) SoCs + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +/***************************************************************************** + * I/O Address Mapping + ****************************************************************************/ +static struct map_desc loki_io_desc[] __initdata = { + { + .virtual = LOKI_REGS_VIRT_BASE, + .pfn = __phys_to_pfn(LOKI_REGS_PHYS_BASE), + .length = LOKI_REGS_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init loki_map_io(void) +{ + iotable_init(loki_io_desc, ARRAY_SIZE(loki_io_desc)); +} + + +/***************************************************************************** + * GE0 + ****************************************************************************/ +struct mv643xx_eth_shared_platform_data loki_ge0_shared_data = { + .t_clk = LOKI_TCLK, + .dram = &loki_mbus_dram_info, +}; + +static struct resource loki_ge0_shared_resources[] = { + { + .name = "ge0 base", + .start = GE0_PHYS_BASE + 0x2000, + .end = GE0_PHYS_BASE + 0x3fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device loki_ge0_shared = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .dev = { + .platform_data = &loki_ge0_shared_data, + }, + .num_resources = 1, + .resource = loki_ge0_shared_resources, +}; + +static struct resource loki_ge0_resources[] = { + { + .name = "ge0 irq", + .start = IRQ_LOKI_GBE_A_INT, + .end = IRQ_LOKI_GBE_A_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device loki_ge0 = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = 1, + .resource = loki_ge0_resources, +}; + +void __init loki_ge0_init(struct mv643xx_eth_platform_data *eth_data) +{ + eth_data->shared = &loki_ge0_shared; + loki_ge0.dev.platform_data = eth_data; + + writel(0x00079220, GE0_VIRT_BASE + 0x20b0); + platform_device_register(&loki_ge0_shared); + platform_device_register(&loki_ge0); +} + + +/***************************************************************************** + * GE1 + ****************************************************************************/ +struct mv643xx_eth_shared_platform_data loki_ge1_shared_data = { + .t_clk = LOKI_TCLK, + .dram = &loki_mbus_dram_info, +}; + +static struct resource loki_ge1_shared_resources[] = { + { + .name = "ge1 base", + .start = GE1_PHYS_BASE + 0x2000, + .end = GE1_PHYS_BASE + 0x3fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device loki_ge1_shared = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 1, + .dev = { + .platform_data = &loki_ge1_shared_data, + }, + .num_resources = 1, + .resource = loki_ge1_shared_resources, +}; + +static struct resource loki_ge1_resources[] = { + { + .name = "ge1 irq", + .start = IRQ_LOKI_GBE_B_INT, + .end = IRQ_LOKI_GBE_B_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device loki_ge1 = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = 1, + .resource = loki_ge1_resources, +}; + +void __init loki_ge1_init(struct mv643xx_eth_platform_data *eth_data) +{ + eth_data->shared = &loki_ge1_shared; + loki_ge1.dev.platform_data = eth_data; + + writel(0x00079220, GE1_VIRT_BASE + 0x20b0); + platform_device_register(&loki_ge1_shared); + platform_device_register(&loki_ge1); +} + + +/***************************************************************************** + * SAS/SATA + ****************************************************************************/ +static struct resource loki_sas_resources[] = { + { + .name = "mvsas0 mem", + .start = SAS0_PHYS_BASE, + .end = SAS0_PHYS_BASE + 0x01ff, + .flags = IORESOURCE_MEM, + }, { + .name = "mvsas0 irq", + .start = IRQ_LOKI_SAS_A, + .end = IRQ_LOKI_SAS_A, + .flags = IORESOURCE_IRQ, + }, { + .name = "mvsas1 mem", + .start = SAS1_PHYS_BASE, + .end = SAS1_PHYS_BASE + 0x01ff, + .flags = IORESOURCE_MEM, + }, { + .name = "mvsas1 irq", + .start = IRQ_LOKI_SAS_B, + .end = IRQ_LOKI_SAS_B, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device loki_sas = { + .name = "mvsas", + .id = 0, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(loki_sas_resources), + .resource = loki_sas_resources, +}; + +void __init loki_sas_init(void) +{ + writel(0x8300f707, DDR_REG(0x1424)); + platform_device_register(&loki_sas); +} + + +/***************************************************************************** + * UART0 + ****************************************************************************/ +static struct plat_serial8250_port loki_uart0_data[] = { + { + .mapbase = UART0_PHYS_BASE, + .membase = (char *)UART0_VIRT_BASE, + .irq = IRQ_LOKI_UART0, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = LOKI_TCLK, + }, { + }, +}; + +static struct resource loki_uart0_resources[] = { + { + .start = UART0_PHYS_BASE, + .end = UART0_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_LOKI_UART0, + .end = IRQ_LOKI_UART0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device loki_uart0 = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = loki_uart0_data, + }, + .resource = loki_uart0_resources, + .num_resources = ARRAY_SIZE(loki_uart0_resources), +}; + +void __init loki_uart0_init(void) +{ + platform_device_register(&loki_uart0); +} + + +/***************************************************************************** + * UART1 + ****************************************************************************/ +static struct plat_serial8250_port loki_uart1_data[] = { + { + .mapbase = UART1_PHYS_BASE, + .membase = (char *)UART1_VIRT_BASE, + .irq = IRQ_LOKI_UART1, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = LOKI_TCLK, + }, { + }, +}; + +static struct resource loki_uart1_resources[] = { + { + .start = UART1_PHYS_BASE, + .end = UART1_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_LOKI_UART1, + .end = IRQ_LOKI_UART1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device loki_uart1 = { + .name = "serial8250", + .id = 1, + .dev = { + .platform_data = loki_uart1_data, + }, + .resource = loki_uart1_resources, + .num_resources = ARRAY_SIZE(loki_uart1_resources), +}; + +void __init loki_uart1_init(void) +{ + platform_device_register(&loki_uart1); +} + + +/***************************************************************************** + * Time handling + ****************************************************************************/ +static void loki_timer_init(void) +{ + orion_time_init(IRQ_LOKI_BRIDGE, LOKI_TCLK); +} + +struct sys_timer loki_timer = { + .init = loki_timer_init, +}; + + +/***************************************************************************** + * General + ****************************************************************************/ +void __init loki_init(void) +{ + printk(KERN_INFO "Loki ID: 88RC8480. TCLK=%d.\n", LOKI_TCLK); + + loki_setup_cpu_mbus(); +} diff --git a/arch/arm/mach-loki/common.h b/arch/arm/mach-loki/common.h new file mode 100644 index 00000000000..26054fd0f05 --- /dev/null +++ b/arch/arm/mach-loki/common.h @@ -0,0 +1,36 @@ +/* + * arch/arm/mach-loki/common.h + * + * Core functions for Marvell Loki (88RC8480) SoCs + * + * 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 __ARCH_LOKI_COMMON_H +#define __ARCH_LOKI_COMMON_H + +struct mv643xx_eth_platform_data; + +/* + * Basic Loki init functions used early by machine-setup. + */ +void loki_map_io(void); +void loki_init(void); +void loki_init_irq(void); + +extern struct mbus_dram_target_info loki_mbus_dram_info; +void loki_setup_cpu_mbus(void); +void loki_setup_dev_boot_win(u32 base, u32 size); + +void loki_ge0_init(struct mv643xx_eth_platform_data *eth_data); +void loki_ge1_init(struct mv643xx_eth_platform_data *eth_data); +void loki_sas_init(void); +void loki_uart0_init(void); +void loki_uart1_init(void); + +extern struct sys_timer loki_timer; + + +#endif diff --git a/arch/arm/mach-loki/irq.c b/arch/arm/mach-loki/irq.c new file mode 100644 index 00000000000..d839af91fe0 --- /dev/null +++ b/arch/arm/mach-loki/irq.c @@ -0,0 +1,21 @@ +/* + * arch/arm/mach-loki/irq.c + * + * Marvell Loki (88RC8480) IRQ handling. + * + * 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 +#include +#include +#include +#include +#include "common.h" + +void __init loki_init_irq(void) +{ + orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_OFF)); +} diff --git a/arch/arm/mach-loki/lb88rc8480-setup.c b/arch/arm/mach-loki/lb88rc8480-setup.c new file mode 100644 index 00000000000..d1b9e6e6253 --- /dev/null +++ b/arch/arm/mach-loki/lb88rc8480-setup.c @@ -0,0 +1,100 @@ +/* + * arch/arm/mach-loki/lb88rc8480-setup.c + * + * Marvell LB88RC8480 Development Board Setup + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +#define LB88RC8480_FLASH_BOOT_CS_BASE 0xf8000000 +#define LB88RC8480_FLASH_BOOT_CS_SIZE SZ_128M + +#define LB88RC8480_NOR_BOOT_BASE 0xff000000 +#define LB88RC8480_NOR_BOOT_SIZE SZ_16M + +static struct mtd_partition lb88rc8480_boot_flash_parts[] = { + { + .name = "kernel", + .offset = 0, + .size = SZ_2M, + }, { + .name = "root-fs", + .offset = SZ_2M, + .size = (SZ_8M + SZ_4M + SZ_1M), + }, { + .name = "u-boot", + .offset = (SZ_8M + SZ_4M + SZ_2M + SZ_1M), + .size = SZ_1M, + }, +}; + +static struct physmap_flash_data lb88rc8480_boot_flash_data = { + .parts = lb88rc8480_boot_flash_parts, + .nr_parts = ARRAY_SIZE(lb88rc8480_boot_flash_parts), + .width = 1, /* 8 bit bus width */ +}; + +static struct resource lb88rc8480_boot_flash_resource = { + .flags = IORESOURCE_MEM, + .start = LB88RC8480_NOR_BOOT_BASE, + .end = LB88RC8480_NOR_BOOT_BASE + LB88RC8480_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device lb88rc8480_boot_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &lb88rc8480_boot_flash_data, + }, + .num_resources = 1, + .resource = &lb88rc8480_boot_flash_resource, +}; + +static struct mv643xx_eth_platform_data lb88rc8480_ge0_data = { + .phy_addr = 1, + .mac_addr = { 0x00, 0x50, 0x43, 0x11, 0x22, 0x33 }, +}; + +static void __init lb88rc8480_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + loki_init(); + + loki_ge0_init(&lb88rc8480_ge0_data); + loki_sas_init(); + loki_uart0_init(); + loki_uart1_init(); + + loki_setup_dev_boot_win(LB88RC8480_FLASH_BOOT_CS_BASE, + LB88RC8480_FLASH_BOOT_CS_SIZE); + platform_device_register(&lb88rc8480_boot_flash); +} + +MACHINE_START(LB88RC8480, "Marvell LB88RC8480 Development Board") + /* Maintainer: Ke Wei */ + .phys_io = LOKI_REGS_PHYS_BASE, + .io_pg_offst = ((LOKI_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = lb88rc8480_init, + .map_io = loki_map_io, + .init_irq = loki_init_irq, + .timer = &loki_timer, +MACHINE_END diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 33ed048502a..08ca264459b 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -365,7 +365,7 @@ config CPU_XSC3 # Feroceon config CPU_FEROCEON bool - depends on ARCH_ORION5X + depends on ARCH_ORION5X || ARCH_LOKI default y select CPU_32v5 select CPU_ABRT_EV5T diff --git a/include/asm-arm/arch-loki/debug-macro.S b/include/asm-arm/arch-loki/debug-macro.S new file mode 100644 index 00000000000..585502e9651 --- /dev/null +++ b/include/asm-arm/arch-loki/debug-macro.S @@ -0,0 +1,20 @@ +/* + * include/asm-arm/arch-loki/debug-macro.S + * + * 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 + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =LOKI_REGS_PHYS_BASE + ldrne \rx, =LOKI_REGS_VIRT_BASE + orr \rx, \rx, #0x00012000 + .endm + +#define UART_SHIFT 2 +#include diff --git a/include/asm-arm/arch-loki/dma.h b/include/asm-arm/arch-loki/dma.h new file mode 100644 index 00000000000..40a8c178f10 --- /dev/null +++ b/include/asm-arm/arch-loki/dma.h @@ -0,0 +1 @@ +/* empty */ diff --git a/include/asm-arm/arch-loki/entry-macro.S b/include/asm-arm/arch-loki/entry-macro.S new file mode 100644 index 00000000000..693257cdbeb --- /dev/null +++ b/include/asm-arm/arch-loki/entry-macro.S @@ -0,0 +1,30 @@ +/* + * include/asm-arm/arch-loki/entry-macro.S + * + * Low-level IRQ helper macros for Marvell Loki (88RC8480) platforms + * + * 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 + + .macro disable_fiq + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =IRQ_VIRT_BASE + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \irqstat, [\base, #IRQ_CAUSE_OFF] + ldr \tmp, [\base, #IRQ_MASK_OFF] + mov \irqnr, #0 + ands \irqstat, \irqstat, \tmp + clzne \irqnr, \irqstat + rsbne \irqnr, \irqnr, #31 + .endm diff --git a/include/asm-arm/arch-loki/hardware.h b/include/asm-arm/arch-loki/hardware.h new file mode 100644 index 00000000000..f65b01c733b --- /dev/null +++ b/include/asm-arm/arch-loki/hardware.h @@ -0,0 +1,15 @@ +/* + * include/asm-arm/arch-loki/hardware.h + * + * 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_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include "loki.h" + + +#endif diff --git a/include/asm-arm/arch-loki/io.h b/include/asm-arm/arch-loki/io.h new file mode 100644 index 00000000000..e7418a915e7 --- /dev/null +++ b/include/asm-arm/arch-loki/io.h @@ -0,0 +1,26 @@ +/* + * include/asm-arm/arch-loki/io.h + * + * 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_IO_H +#define __ASM_ARCH_IO_H + +#include "loki.h" + +#define IO_SPACE_LIMIT 0xffffffff + +static inline void __iomem *__io(unsigned long addr) +{ + return (void __iomem *)((addr - LOKI_PCIE0_IO_PHYS_BASE) + + LOKI_PCIE0_IO_VIRT_BASE); +} + +#define __io(a) __io(a) +#define __mem_pci(a) (a) + + +#endif diff --git a/include/asm-arm/arch-loki/irqs.h b/include/asm-arm/arch-loki/irqs.h new file mode 100644 index 00000000000..7e497143807 --- /dev/null +++ b/include/asm-arm/arch-loki/irqs.h @@ -0,0 +1,58 @@ +/* + * include/asm-arm/arch-loki/irqs.h + * + * IRQ definitions for Marvell Loki (88RC8480) SoCs + * + * 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_IRQS_H +#define __ASM_ARCH_IRQS_H + +#include "loki.h" /* need GPIO_MAX */ + +/* + * Interrupt Controller + */ +#define IRQ_LOKI_PCIE_A_CPU_DRBL 0 +#define IRQ_LOKI_CPU_PCIE_A_DRBL 1 +#define IRQ_LOKI_PCIE_B_CPU_DRBL 2 +#define IRQ_LOKI_CPU_PCIE_B_DRBL 3 +#define IRQ_LOKI_COM_A_ERR 6 +#define IRQ_LOKI_COM_A_IN 7 +#define IRQ_LOKI_COM_A_OUT 8 +#define IRQ_LOKI_COM_B_ERR 9 +#define IRQ_LOKI_COM_B_IN 10 +#define IRQ_LOKI_COM_B_OUT 11 +#define IRQ_LOKI_DMA_A 12 +#define IRQ_LOKI_DMA_B 13 +#define IRQ_LOKI_SAS_A 14 +#define IRQ_LOKI_SAS_B 15 +#define IRQ_LOKI_DDR 16 +#define IRQ_LOKI_XOR 17 +#define IRQ_LOKI_BRIDGE 18 +#define IRQ_LOKI_PCIE_A_ERR 20 +#define IRQ_LOKI_PCIE_A_INT 21 +#define IRQ_LOKI_PCIE_B_ERR 22 +#define IRQ_LOKI_PCIE_B_INT 23 +#define IRQ_LOKI_GBE_A_INT 24 +#define IRQ_LOKI_GBE_B_INT 25 +#define IRQ_LOKI_DEV_ERR 26 +#define IRQ_LOKI_UART0 27 +#define IRQ_LOKI_UART1 28 +#define IRQ_LOKI_TWSI 29 +#define IRQ_LOKI_GPIO_23_0 30 +#define IRQ_LOKI_GPIO_25_24 31 + +/* + * Loki General Purpose Pins + */ +#define IRQ_LOKI_GPIO_START 32 +#define NR_GPIO_IRQS GPIO_MAX + +#define NR_IRQS (IRQ_LOKI_GPIO_START + NR_GPIO_IRQS) + + +#endif diff --git a/include/asm-arm/arch-loki/loki.h b/include/asm-arm/arch-loki/loki.h new file mode 100644 index 00000000000..5dd05ee0a4e --- /dev/null +++ b/include/asm-arm/arch-loki/loki.h @@ -0,0 +1,97 @@ +/* + * include/asm-arm/arch-loki/loki.h + * + * Generic definitions for Marvell Loki (88RC8480) SoC flavors + * + * 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_LOKI_H +#define __ASM_ARCH_LOKI_H + +/* + * Marvell Loki (88RC8480) address maps. + * + * phys + * d0000000 on-chip peripheral registers + * e0000000 PCIe 0 Memory space + * e8000000 PCIe 1 Memory space + * f0000000 PCIe 0 I/O space + * f0100000 PCIe 1 I/O space + * + * virt phys size + * fed00000 d0000000 1M on-chip peripheral registers + * fee00000 f0000000 64K PCIe 0 I/O space + * fef00000 f0100000 64K PCIe 1 I/O space + */ + +#define LOKI_REGS_PHYS_BASE 0xd0000000 +#define LOKI_REGS_VIRT_BASE 0xfed00000 +#define LOKI_REGS_SIZE SZ_1M + +#define LOKI_PCIE0_IO_PHYS_BASE 0xf0000000 +#define LOKI_PCIE0_IO_VIRT_BASE 0xfee00000 +#define LOKI_PCIE0_IO_BUS_BASE 0x00000000 +#define LOKI_PCIE0_IO_SIZE SZ_64K + +#define LOKI_PCIE1_IO_PHYS_BASE 0xf0100000 +#define LOKI_PCIE1_IO_VIRT_BASE 0xfef00000 +#define LOKI_PCIE1_IO_BUS_BASE 0x00000000 +#define LOKI_PCIE1_IO_SIZE SZ_64K + +#define LOKI_PCIE0_MEM_PHYS_BASE 0xe0000000 +#define LOKI_PCIE0_MEM_SIZE SZ_128M + +#define LOKI_PCIE1_MEM_PHYS_BASE 0xe8000000 +#define LOKI_PCIE1_MEM_SIZE SZ_128M + +/* + * Register Map + */ +#define DEV_BUS_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0x10000) +#define DEV_BUS_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0x10000) +#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000) +#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000) +#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100) +#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100) + +#define BRIDGE_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0x20000) +#define BRIDGE_REG(x) (BRIDGE_VIRT_BASE | (x)) +#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108) +#define SOFT_RESET_OUT_EN 0x00000004 +#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c) +#define SOFT_RESET 0x00000001 +#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE | 0x0110) +#define BRIDGE_MASK (BRIDGE_VIRT_BASE | 0x0114) +#define BRIDGE_INT_TIMER0 0x0002 +#define BRIDGE_INT_TIMER1 0x0004 +#define BRIDGE_INT_TIMER1_CLR 0x0004 +#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200) +#define IRQ_CAUSE_OFF 0x0000 +#define IRQ_MASK_OFF 0x0004 +#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) + +#define PCIE0_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0x30000) + +#define PCIE1_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0x40000) + +#define SAS0_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0x80000) + +#define SAS1_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0x90000) + +#define GE0_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0xa0000) +#define GE0_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0xa0000) + +#define GE1_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0xb0000) +#define GE1_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0xb0000) + +#define DDR_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0xf0000) +#define DDR_REG(x) (DDR_VIRT_BASE | (x)) + + +#define GPIO_MAX 8 + + +#endif diff --git a/include/asm-arm/arch-loki/memory.h b/include/asm-arm/arch-loki/memory.h new file mode 100644 index 00000000000..835101e4987 --- /dev/null +++ b/include/asm-arm/arch-loki/memory.h @@ -0,0 +1,14 @@ +/* + * include/asm-arm/arch-loki/memory.h + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#define PHYS_OFFSET UL(0x00000000) + +#define __virt_to_bus(x) __virt_to_phys(x) +#define __bus_to_virt(x) __phys_to_virt(x) + + +#endif diff --git a/include/asm-arm/arch-loki/system.h b/include/asm-arm/arch-loki/system.h new file mode 100644 index 00000000000..a3568ac8ec3 --- /dev/null +++ b/include/asm-arm/arch-loki/system.h @@ -0,0 +1,37 @@ +/* + * include/asm-arm/arch-loki/system.h + * + * 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_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#include +#include + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode) +{ + /* + * Enable soft reset to assert RSTOUTn. + */ + writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK); + + /* + * Assert soft reset. + */ + writel(SOFT_RESET, SYSTEM_SOFT_RESET); + + while (1) + ; +} + + +#endif diff --git a/include/asm-arm/arch-loki/timex.h b/include/asm-arm/arch-loki/timex.h new file mode 100644 index 00000000000..940014f97ca --- /dev/null +++ b/include/asm-arm/arch-loki/timex.h @@ -0,0 +1,11 @@ +/* + * include/asm-arm/arch-loki/timex.h + * + * 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. + */ + +#define CLOCK_TICK_RATE (100 * HZ) + +#define LOKI_TCLK 180000000 diff --git a/include/asm-arm/arch-loki/uncompress.h b/include/asm-arm/arch-loki/uncompress.h new file mode 100644 index 00000000000..89a0cf88d3a --- /dev/null +++ b/include/asm-arm/arch-loki/uncompress.h @@ -0,0 +1,47 @@ +/* + * include/asm-arm/arch-loki/uncompress.h + * + * 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 +#include + +#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE) + +static void putc(const char c) +{ + unsigned char *base = SERIAL_BASE; + int i; + + for (i = 0; i < 0x1000; i++) { + if (base[UART_LSR << 2] & UART_LSR_THRE) + break; + barrier(); + } + + base[UART_TX << 2] = c; +} + +static void flush(void) +{ + unsigned char *base = SERIAL_BASE; + unsigned char mask; + int i; + + mask = UART_LSR_TEMT | UART_LSR_THRE; + + for (i = 0; i < 0x1000; i++) { + if ((base[UART_LSR << 2] & mask) == mask) + break; + barrier(); + } +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-loki/vmalloc.h b/include/asm-arm/arch-loki/vmalloc.h new file mode 100644 index 00000000000..f5be0622049 --- /dev/null +++ b/include/asm-arm/arch-loki/vmalloc.h @@ -0,0 +1,5 @@ +/* + * include/asm-arm/arch-loki/vmalloc.h + */ + +#define VMALLOC_END 0xfe800000 -- cgit v1.2.3-70-g09d2 From 836a8051d54525e0782f156dcfa3c13d30f22840 Mon Sep 17 00:00:00 2001 From: Stanislav Samsonov Date: Tue, 3 Jun 2008 11:24:40 +0300 Subject: [ARM] Feroceon: L1 cache range operation support This patch adds support for the L1 D cache range operations that are supported by the Marvell Discovery Duo and Marvell Kirkwood ARM SoCs. Signed-off-by: Stanislav Samsonov Acked-by: Saeed Bishara Reviewed-by: Nicolas Pitre Signed-off-by: Lennert Buytenhek --- arch/arm/mm/proc-feroceon.S | 69 +++++++++++++++++++++++++++++++++++++++++++- include/asm-arm/cacheflush.h | 6 +--- 2 files changed, 69 insertions(+), 6 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index 61a5025bf03..c279652a98f 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -237,6 +237,20 @@ ENTRY(feroceon_flush_kern_dcache_page) mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr + .align 5 +ENTRY(feroceon_range_flush_kern_dcache_page) + mrs r2, cpsr + add r1, r0, #PAGE_SZ - CACHE_DLINESIZE @ top addr is inclusive + orr r3, r2, #PSR_I_BIT + msr cpsr_c, r3 @ disable interrupts + mcr p15, 5, r0, c15, c15, 0 @ D clean/inv range start + mcr p15, 5, r1, c15, c15, 1 @ D clean/inv range top + msr cpsr_c, r2 @ restore interrupts + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + /* * dma_inv_range(start, end) * @@ -253,10 +267,10 @@ ENTRY(feroceon_flush_kern_dcache_page) .align 5 ENTRY(feroceon_dma_inv_range) tst r0, #CACHE_DLINESIZE - 1 + bic r0, r0, #CACHE_DLINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry tst r1, #CACHE_DLINESIZE - 1 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry - bic r0, r0, #CACHE_DLINESIZE - 1 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -264,6 +278,22 @@ ENTRY(feroceon_dma_inv_range) mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr + .align 5 +ENTRY(feroceon_range_dma_inv_range) + mrs r2, cpsr + tst r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry + cmp r1, r0 + subne r1, r1, #1 @ top address is inclusive + orr r3, r2, #PSR_I_BIT + msr cpsr_c, r3 @ disable interrupts + mcr p15, 5, r0, c15, c14, 0 @ D inv range start + mcr p15, 5, r1, c15, c14, 1 @ D inv range top + msr cpsr_c, r2 @ restore interrupts + mov pc, lr + /* * dma_clean_range(start, end) * @@ -284,6 +314,19 @@ ENTRY(feroceon_dma_clean_range) mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr + .align 5 +ENTRY(feroceon_range_dma_clean_range) + mrs r2, cpsr + cmp r1, r0 + subne r1, r1, #1 @ top address is inclusive + orr r3, r2, #PSR_I_BIT + msr cpsr_c, r3 @ disable interrupts + mcr p15, 5, r0, c15, c13, 0 @ D clean range start + mcr p15, 5, r1, c15, c13, 1 @ D clean range top + msr cpsr_c, r2 @ restore interrupts + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + /* * dma_flush_range(start, end) * @@ -302,6 +345,19 @@ ENTRY(feroceon_dma_flush_range) mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr + .align 5 +ENTRY(feroceon_range_dma_flush_range) + mrs r2, cpsr + cmp r1, r0 + subne r1, r1, #1 @ top address is inclusive + orr r3, r2, #PSR_I_BIT + msr cpsr_c, r3 @ disable interrupts + mcr p15, 5, r0, c15, c15, 0 @ D clean/inv range start + mcr p15, 5, r1, c15, c15, 1 @ D clean/inv range top + msr cpsr_c, r2 @ restore interrupts + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + ENTRY(feroceon_cache_fns) .long feroceon_flush_kern_cache_all .long feroceon_flush_user_cache_all @@ -313,6 +369,17 @@ ENTRY(feroceon_cache_fns) .long feroceon_dma_clean_range .long feroceon_dma_flush_range +ENTRY(feroceon_range_cache_fns) + .long feroceon_flush_kern_cache_all + .long feroceon_flush_user_cache_all + .long feroceon_flush_user_cache_range + .long feroceon_coherent_kern_range + .long feroceon_coherent_user_range + .long feroceon_range_flush_kern_dcache_page + .long feroceon_range_dma_inv_range + .long feroceon_range_dma_clean_range + .long feroceon_range_dma_flush_range + .align 5 ENTRY(cpu_feroceon_dcache_clean_area) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 759a97b56ee..b85d426bb52 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -95,11 +95,7 @@ #endif #if defined(CONFIG_CPU_FEROCEON) -# ifdef _CACHE -# define MULTI_CACHE 1 -# else -# define _CACHE feroceon -# endif +# define MULTI_CACHE 1 #endif #if defined(CONFIG_CPU_V6) -- cgit v1.2.3-70-g09d2 From 99c6dc117d27d6259214812bd0b113aaf467f600 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 22 Jun 2008 22:45:04 +0200 Subject: [ARM] Feroceon: L2 cache support This patch adds support for the unified Feroceon L2 cache controller as found in e.g. the Marvell Kirkwood and Marvell Discovery Duo families of ARM SoCs. Note that: - Page table walks are outer uncacheable on Kirkwood and Discovery Duo, since the ARMv5 spec provides no way to indicate outer cacheability of page table walks (specifying it in TTBR[4:3] is an ARMv6+ feature). This requires adding L2 cache clean instructions to proc-feroceon.S (dcache_clean_area(), set_pte()) as well as to tlbflush.h ({flush,clean}_pmd_entry()). The latter case is handled by defining a new TLB type (TLB_FEROCEON) which is almost identical to the v4wbi one but provides a TLB_L2CLEAN_FR flag. - The Feroceon L2 cache controller supports L2 range (i.e. 'clean L2 range by MVA' and 'invalidate L2 range by MVA') operations, and this patch uses those range operations for all Linux outer cache operations, as they are faster than the regular per-line operations. L2 range operations are not interruptible on this hardware, which avoids potential livelock issues, but can be bad for interrupt latency, so there is a compile-time tunable (MAX_RANGE_SIZE) which allows you to select the maximum range size to operate on at once. (Valid range is between one cache line and one 4KiB page, and must be a multiple of the line size.) Signed-off-by: Lennert Buytenhek --- arch/arm/mm/Kconfig | 15 +- arch/arm/mm/Makefile | 2 + arch/arm/mm/cache-feroceon-l2.c | 318 +++++++++++++++++++++++++ arch/arm/mm/proc-feroceon.S | 20 ++ include/asm-arm/plat-orion/cache-feroceon-l2.h | 11 + include/asm-arm/tlbflush.h | 30 +++ 6 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mm/cache-feroceon-l2.c create mode 100644 include/asm-arm/plat-orion/cache-feroceon-l2.h (limited to 'include/asm-arm') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 08ca264459b..3b90051c0e0 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -373,7 +373,7 @@ config CPU_FEROCEON select CPU_CACHE_VIVT select CPU_CP15_MMU select CPU_COPY_FEROCEON if MMU - select CPU_TLB_V4WBI if MMU + select CPU_TLB_FEROCEON if MMU config CPU_FEROCEON_OLD_ID bool "Accept early Feroceon cores with an ARM926 ID" @@ -551,6 +551,11 @@ config CPU_TLB_V4WBI ARM Architecture Version 4 TLB with writeback cache and invalidate instruction cache entry. +config CPU_TLB_FEROCEON + bool + help + Feroceon TLB (v4wbi with non-outer-cachable page table walks). + config CPU_TLB_V6 bool @@ -709,6 +714,14 @@ config OUTER_CACHE bool default n +config CACHE_FEROCEON_L2 + bool "Enable the Feroceon L2 cache controller" + depends on FOOBAR + default y + select OUTER_CACHE + help + This option enables the Feroceon L2 cache controller. + config CACHE_L2X0 bool "Enable the L2x0 outer cache controller" depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 32b2d2d213a..f64b92557b1 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o +obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o @@ -73,4 +74,5 @@ obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o obj-$(CONFIG_CPU_V6) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o +obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c new file mode 100644 index 00000000000..20eec4ba173 --- /dev/null +++ b/arch/arm/mm/cache-feroceon-l2.c @@ -0,0 +1,318 @@ +/* + * arch/arm/mm/cache-feroceon-l2.c - Feroceon L2 cache controller support + * + * Copyright (C) 2008 Marvell Semiconductor + * + * 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. + * + * References: + * - Unified Layer 2 Cache for Feroceon CPU Cores, + * Document ID MV-S104858-00, Rev. A, October 23 2007. + */ + +#include +#include +#include + + +/* + * Low-level cache maintenance operations. + * + * As well as the regular 'clean/invalidate/flush L2 cache line by + * MVA' instructions, the Feroceon L2 cache controller also features + * 'clean/invalidate L2 range by MVA' operations. + * + * Cache range operations are initiated by writing the start and + * end addresses to successive cp15 registers, and process every + * cache line whose first byte address lies in the inclusive range + * [start:end]. + * + * The cache range operations stall the CPU pipeline until completion. + * + * The range operations require two successive cp15 writes, in + * between which we don't want to be preempted. + */ +static inline void l2_clean_pa(unsigned long addr) +{ + __asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr)); +} + +static inline void l2_clean_mva_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + + /* + * Make sure 'start' and 'end' reference the same page, as + * L2 is PIPT and range operations only do a TLB lookup on + * the start address. + */ + BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); + + raw_local_irq_save(flags); + __asm__("mcr p15, 1, %0, c15, c9, 4" : : "r" (start)); + __asm__("mcr p15, 1, %0, c15, c9, 5" : : "r" (end)); + raw_local_irq_restore(flags); +} + +static inline void l2_clean_pa_range(unsigned long start, unsigned long end) +{ + l2_clean_mva_range(__phys_to_virt(start), __phys_to_virt(end)); +} + +static inline void l2_clean_inv_pa(unsigned long addr) +{ + __asm__("mcr p15, 1, %0, c15, c10, 3" : : "r" (addr)); +} + +static inline void l2_inv_pa(unsigned long addr) +{ + __asm__("mcr p15, 1, %0, c15, c11, 3" : : "r" (addr)); +} + +static inline void l2_inv_mva_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + + /* + * Make sure 'start' and 'end' reference the same page, as + * L2 is PIPT and range operations only do a TLB lookup on + * the start address. + */ + BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); + + raw_local_irq_save(flags); + __asm__("mcr p15, 1, %0, c15, c11, 4" : : "r" (start)); + __asm__("mcr p15, 1, %0, c15, c11, 5" : : "r" (end)); + raw_local_irq_restore(flags); +} + +static inline void l2_inv_pa_range(unsigned long start, unsigned long end) +{ + l2_inv_mva_range(__phys_to_virt(start), __phys_to_virt(end)); +} + + +/* + * Linux primitives. + * + * Note that the end addresses passed to Linux primitives are + * noninclusive, while the hardware cache range operations use + * inclusive start and end addresses. + */ +#define CACHE_LINE_SIZE 32 +#define MAX_RANGE_SIZE 1024 + +static int l2_wt_override; + +static unsigned long calc_range_end(unsigned long start, unsigned long end) +{ + unsigned long range_end; + + BUG_ON(start & (CACHE_LINE_SIZE - 1)); + BUG_ON(end & (CACHE_LINE_SIZE - 1)); + + /* + * Try to process all cache lines between 'start' and 'end'. + */ + range_end = end; + + /* + * Limit the number of cache lines processed at once, + * since cache range operations stall the CPU pipeline + * until completion. + */ + if (range_end > start + MAX_RANGE_SIZE) + range_end = start + MAX_RANGE_SIZE; + + /* + * Cache range operations can't straddle a page boundary. + */ + if (range_end > (start | (PAGE_SIZE - 1)) + 1) + range_end = (start | (PAGE_SIZE - 1)) + 1; + + return range_end; +} + +static void feroceon_l2_inv_range(unsigned long start, unsigned long end) +{ + /* + * Clean and invalidate partial first cache line. + */ + if (start & (CACHE_LINE_SIZE - 1)) { + l2_clean_inv_pa(start & ~(CACHE_LINE_SIZE - 1)); + start = (start | (CACHE_LINE_SIZE - 1)) + 1; + } + + /* + * Clean and invalidate partial last cache line. + */ + if (end & (CACHE_LINE_SIZE - 1)) { + l2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1)); + end &= ~(CACHE_LINE_SIZE - 1); + } + + /* + * Invalidate all full cache lines between 'start' and 'end'. + */ + while (start != end) { + unsigned long range_end = calc_range_end(start, end); + l2_inv_pa_range(start, range_end - CACHE_LINE_SIZE); + start = range_end; + } + + dsb(); +} + +static void feroceon_l2_clean_range(unsigned long start, unsigned long end) +{ + /* + * If L2 is forced to WT, the L2 will always be clean and we + * don't need to do anything here. + */ + if (!l2_wt_override) { + start &= ~(CACHE_LINE_SIZE - 1); + end = (end + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1); + while (start != end) { + unsigned long range_end = calc_range_end(start, end); + l2_clean_pa_range(start, range_end - CACHE_LINE_SIZE); + start = range_end; + } + } + + dsb(); +} + +static void feroceon_l2_flush_range(unsigned long start, unsigned long end) +{ + start &= ~(CACHE_LINE_SIZE - 1); + end = (end + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1); + while (start != end) { + unsigned long range_end = calc_range_end(start, end); + if (!l2_wt_override) + l2_clean_pa_range(start, range_end - CACHE_LINE_SIZE); + l2_inv_pa_range(start, range_end - CACHE_LINE_SIZE); + start = range_end; + } + + dsb(); +} + + +/* + * Routines to disable and re-enable the D-cache and I-cache at run + * time. These are necessary because the L2 cache can only be enabled + * or disabled while the L1 Dcache and Icache are both disabled. + */ +static void __init invalidate_and_disable_dcache(void) +{ + u32 cr; + + cr = get_cr(); + if (cr & CR_C) { + unsigned long flags; + + raw_local_irq_save(flags); + flush_cache_all(); + set_cr(cr & ~CR_C); + raw_local_irq_restore(flags); + } +} + +static void __init enable_dcache(void) +{ + u32 cr; + + cr = get_cr(); + if (!(cr & CR_C)) + set_cr(cr | CR_C); +} + +static void __init __invalidate_icache(void) +{ + int dummy; + + __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0\n" : "=r" (dummy)); +} + +static void __init invalidate_and_disable_icache(void) +{ + u32 cr; + + cr = get_cr(); + if (cr & CR_I) { + set_cr(cr & ~CR_I); + __invalidate_icache(); + } +} + +static void __init enable_icache(void) +{ + u32 cr; + + cr = get_cr(); + if (!(cr & CR_I)) + set_cr(cr | CR_I); +} + +static inline u32 read_extra_features(void) +{ + u32 u; + + __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (u)); + + return u; +} + +static inline void write_extra_features(u32 u) +{ + __asm__("mcr p15, 1, %0, c15, c1, 0" : : "r" (u)); +} + +static void __init disable_l2_prefetch(void) +{ + u32 u; + + /* + * Read the CPU Extra Features register and verify that the + * Disable L2 Prefetch bit is set. + */ + u = read_extra_features(); + if (!(u & 0x01000000)) { + printk(KERN_INFO "Feroceon L2: Disabling L2 prefetch.\n"); + write_extra_features(u | 0x01000000); + } +} + +static void __init enable_l2(void) +{ + u32 u; + + u = read_extra_features(); + if (!(u & 0x00400000)) { + printk(KERN_INFO "Feroceon L2: Enabling L2\n"); + + invalidate_and_disable_dcache(); + invalidate_and_disable_icache(); + write_extra_features(u | 0x00400000); + enable_icache(); + enable_dcache(); + } +} + +void __init feroceon_l2_init(int __l2_wt_override) +{ + l2_wt_override = __l2_wt_override; + + disable_l2_prefetch(); + + outer_cache.inv_range = feroceon_l2_inv_range; + outer_cache.clean_range = feroceon_l2_clean_range; + outer_cache.flush_range = feroceon_l2_flush_range; + + enable_l2(); + + printk(KERN_INFO "Feroceon L2: Cache support initialised%s.\n", + l2_wt_override ? ", in WT override mode" : ""); +} diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index c279652a98f..cecf96ee07d 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -79,6 +79,13 @@ ENTRY(cpu_feroceon_proc_fin) mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE msr cpsr_c, ip bl feroceon_flush_kern_cache_all + +#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) + mov r0, #0 + mcr p15, 1, r0, c15, c9, 0 @ clean L2 + mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif + mrc p15, 0, r0, c1, c0, 0 @ ctrl register bic r0, r0, #0x1000 @ ...i............ bic r0, r0, #0x000e @ ............wca. @@ -382,10 +389,20 @@ ENTRY(feroceon_range_cache_fns) .align 5 ENTRY(cpu_feroceon_dcache_clean_area) +#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) + mov r2, r0 + mov r3, r1 +#endif 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHE_DLINESIZE subs r1, r1, #CACHE_DLINESIZE bhi 1b +#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) +1: mcr p15, 1, r2, c15, c9, 1 @ clean L2 entry + add r2, r2, #CACHE_DLINESIZE + subs r3, r3, #CACHE_DLINESIZE + bhi 1b +#endif mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr @@ -449,6 +466,9 @@ ENTRY(cpu_feroceon_set_pte_ext) str r2, [r0] @ hardware version mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) + mcr p15, 1, r0, c15, c9, 1 @ clean L2 entry +#endif mcr p15, 0, r0, c7, c10, 4 @ drain WB #endif mov pc, lr diff --git a/include/asm-arm/plat-orion/cache-feroceon-l2.h b/include/asm-arm/plat-orion/cache-feroceon-l2.h new file mode 100644 index 00000000000..ba4e016d3ec --- /dev/null +++ b/include/asm-arm/plat-orion/cache-feroceon-l2.h @@ -0,0 +1,11 @@ +/* + * include/asm-arm/plat-orion/cache-feroceon-l2.h + * + * Copyright (C) 2008 Marvell Semiconductor + * + * 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. + */ + +extern void __init feroceon_l2_init(int l2_wt_override); diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h index 8c6bc1bb9d1..909656c747e 100644 --- a/include/asm-arm/tlbflush.h +++ b/include/asm-arm/tlbflush.h @@ -39,6 +39,7 @@ #define TLB_V6_D_ASID (1 << 17) #define TLB_V6_I_ASID (1 << 18) +#define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ #define TLB_DCLEAN (1 << 30) #define TLB_WB (1 << 31) @@ -51,6 +52,7 @@ * v4 - ARMv4 without write buffer * v4wb - ARMv4 with write buffer without I TLB flush entry instruction * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction + * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction */ #undef _TLB @@ -103,6 +105,23 @@ # define v4wbi_always_flags (-1UL) #endif +#define fr_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_L2CLEAN_FR | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_I_PAGE | TLB_V4_D_PAGE) + +#ifdef CONFIG_CPU_TLB_FEROCEON +# define fr_possible_flags fr_tlb_flags +# define fr_always_flags fr_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wbi +# endif +#else +# define fr_possible_flags 0 +# define fr_always_flags (-1UL) +#endif + #define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \ TLB_V4_I_FULL | TLB_V4_D_FULL | \ TLB_V4_D_PAGE) @@ -245,12 +264,14 @@ extern struct cpu_tlb_fns cpu_tlb; #define possible_tlb_flags (v3_possible_flags | \ v4_possible_flags | \ v4wbi_possible_flags | \ + fr_possible_flags | \ v4wb_possible_flags | \ v6wbi_possible_flags) #define always_tlb_flags (v3_always_flags & \ v4_always_flags & \ v4wbi_always_flags & \ + fr_always_flags & \ v4wb_always_flags & \ v6wbi_always_flags) @@ -417,6 +438,11 @@ static inline void flush_pmd_entry(pmd_t *pmd) if (tlb_flag(TLB_DCLEAN)) asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" : : "r" (pmd) : "cc"); + + if (tlb_flag(TLB_L2CLEAN_FR)) + asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" + : : "r" (pmd) : "cc"); + if (tlb_flag(TLB_WB)) dsb(); } @@ -428,6 +454,10 @@ static inline void clean_pmd_entry(pmd_t *pmd) if (tlb_flag(TLB_DCLEAN)) asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" : : "r" (pmd) : "cc"); + + if (tlb_flag(TLB_L2CLEAN_FR)) + asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" + : : "r" (pmd) : "cc"); } #undef tlb_flag -- cgit v1.2.3-70-g09d2 From 651c74c74bf84ba966b52588ba3329606f3fd8d4 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 22 Jun 2008 22:45:06 +0200 Subject: [ARM] add Marvell Kirkwood (88F6000) SoC support The Marvell Kirkwood (88F6000) is a family of ARM SoCs based on a Shiva CPU core, and features a DDR2 controller, a x1 PCIe interface, a USB 2.0 interface, a SPI controller, a crypto accelerator, a TS interface, and IDMA/XOR engines, and depending on the model, also features one or two Gigabit Ethernet interfaces, two SATA II interfaces, one or two TWSI interfaces, one or two UARTs, a TDM/SLIC interface, a NAND controller, an I2S/SPDIF interface, and an SDIO interface. This patch adds supports for the Marvell DB-88F6281-BP Development Board and the RD-88F6192-NAS and the RD-88F6281 Reference Designs, enabling support for the PCIe interface, the USB interface, the ethernet interfaces, the SATA interfaces, the TWSI interfaces, the UARTs, and the NAND controller. Signed-off-by: Saeed Bishara Signed-off-by: Lennert Buytenhek --- arch/arm/Kconfig | 12 + arch/arm/Makefile | 1 + arch/arm/mach-kirkwood/Kconfig | 25 ++ arch/arm/mach-kirkwood/Makefile | 5 + arch/arm/mach-kirkwood/Makefile.boot | 3 + arch/arm/mach-kirkwood/addr-map.c | 139 ++++++++++++ arch/arm/mach-kirkwood/common.c | 326 +++++++++++++++++++++++++++ arch/arm/mach-kirkwood/common.h | 42 ++++ arch/arm/mach-kirkwood/db88f6281-bp-setup.c | 68 ++++++ arch/arm/mach-kirkwood/irq.c | 22 ++ arch/arm/mach-kirkwood/pcie.c | 180 +++++++++++++++ arch/arm/mach-kirkwood/rd88f6192-nas-setup.c | 69 ++++++ arch/arm/mach-kirkwood/rd88f6281-setup.c | 112 +++++++++ arch/arm/mm/Kconfig | 4 +- include/asm-arm/arch-kirkwood/debug-macro.S | 20 ++ include/asm-arm/arch-kirkwood/dma.h | 1 + include/asm-arm/arch-kirkwood/entry-macro.S | 40 ++++ include/asm-arm/arch-kirkwood/hardware.h | 21 ++ include/asm-arm/arch-kirkwood/io.h | 26 +++ include/asm-arm/arch-kirkwood/irqs.h | 63 ++++++ include/asm-arm/arch-kirkwood/kirkwood.h | 99 ++++++++ include/asm-arm/arch-kirkwood/memory.h | 14 ++ include/asm-arm/arch-kirkwood/system.h | 37 +++ include/asm-arm/arch-kirkwood/timex.h | 11 + include/asm-arm/arch-kirkwood/uncompress.h | 47 ++++ include/asm-arm/arch-kirkwood/vmalloc.h | 5 + 26 files changed, 1390 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-kirkwood/Kconfig create mode 100644 arch/arm/mach-kirkwood/Makefile create mode 100644 arch/arm/mach-kirkwood/Makefile.boot create mode 100644 arch/arm/mach-kirkwood/addr-map.c create mode 100644 arch/arm/mach-kirkwood/common.c create mode 100644 arch/arm/mach-kirkwood/common.h create mode 100644 arch/arm/mach-kirkwood/db88f6281-bp-setup.c create mode 100644 arch/arm/mach-kirkwood/irq.c create mode 100644 arch/arm/mach-kirkwood/pcie.c create mode 100644 arch/arm/mach-kirkwood/rd88f6192-nas-setup.c create mode 100644 arch/arm/mach-kirkwood/rd88f6281-setup.c create mode 100644 include/asm-arm/arch-kirkwood/debug-macro.S create mode 100644 include/asm-arm/arch-kirkwood/dma.h create mode 100644 include/asm-arm/arch-kirkwood/entry-macro.S create mode 100644 include/asm-arm/arch-kirkwood/hardware.h create mode 100644 include/asm-arm/arch-kirkwood/io.h create mode 100644 include/asm-arm/arch-kirkwood/irqs.h create mode 100644 include/asm-arm/arch-kirkwood/kirkwood.h create mode 100644 include/asm-arm/arch-kirkwood/memory.h create mode 100644 include/asm-arm/arch-kirkwood/system.h create mode 100644 include/asm-arm/arch-kirkwood/timex.h create mode 100644 include/asm-arm/arch-kirkwood/uncompress.h create mode 100644 include/asm-arm/arch-kirkwood/vmalloc.h (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7a725f89b84..3535cae73d2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -352,6 +352,16 @@ config ARCH_L7200 If you have any questions or comments about the Linux kernel port to this board, send e-mail to . +config ARCH_KIRKWOOD + bool "Marvell Kirkwood" + select PCI + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select PLAT_ORION + help + Support for the following Marvell Kirkwood series SoCs: + 88F6180, 88F6192 and 88F6281. + config ARCH_KS8695 bool "Micrel/Kendin KS8695" select GENERIC_GPIO @@ -530,6 +540,8 @@ source "arch/arm/mach-omap2/Kconfig" source "arch/arm/mach-orion5x/Kconfig" +source "arch/arm/mach-kirkwood/Kconfig" + source "arch/arm/plat-s3c24xx/Kconfig" source "arch/arm/plat-s3c/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 2ea32a70c97..1459b3849c8 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -135,6 +135,7 @@ endif machine-$(CONFIG_ARCH_NETX) := netx machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx machine-$(CONFIG_ARCH_DAVINCI) := davinci + machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood machine-$(CONFIG_ARCH_KS8695) := ks8695 incdir-$(CONFIG_ARCH_MXC) := mxc machine-$(CONFIG_ARCH_MX3) := mx3 diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig new file mode 100644 index 00000000000..3600cd9f051 --- /dev/null +++ b/arch/arm/mach-kirkwood/Kconfig @@ -0,0 +1,25 @@ +if ARCH_KIRKWOOD + +menu "Marvell Kirkwood Implementations" + +config MACH_DB88F6281_BP + bool "Marvell DB-88F6281-BP Development Board" + help + Say 'Y' here if you want your kernel to support the + Marvell DB-88F6281-BP Development Board. + +config MACH_RD88F6192_NAS + bool "Marvell RD-88F6192-NAS Reference Board" + help + Say 'Y' here if you want your kernel to support the + Marvell RD-88F6192-NAS Reference Board. + +config MACH_RD88F6281 + bool "Marvell RD-88F6281 Reference Board" + help + Say 'Y' here if you want your kernel to support the + Marvell RD-88F6281 Reference Board. + +endmenu + +endif diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile new file mode 100644 index 00000000000..e14bf40bfb0 --- /dev/null +++ b/arch/arm/mach-kirkwood/Makefile @@ -0,0 +1,5 @@ +obj-y += common.o addr-map.o irq.o pcie.o + +obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o +obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o +obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6281-setup.o diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot new file mode 100644 index 00000000000..67039c3e0c4 --- /dev/null +++ b/arch/arm/mach-kirkwood/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c new file mode 100644 index 00000000000..a39f0f3c473 --- /dev/null +++ b/arch/arm/mach-kirkwood/addr-map.c @@ -0,0 +1,139 @@ +/* + * arch/arm/mach-kirkwood/addr-map.c + * + * Address map functions for Marvell Kirkwood SoCs + * + * 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 +#include +#include +#include +#include +#include "common.h" + +/* + * Generic Address Decode Windows bit settings + */ +#define TARGET_DDR 0 +#define TARGET_DEV_BUS 1 +#define TARGET_PCIE 4 +#define ATTR_DEV_SPI_ROM 0x1e +#define ATTR_DEV_BOOT 0x1d +#define ATTR_DEV_NAND 0x2f +#define ATTR_DEV_CS3 0x37 +#define ATTR_DEV_CS2 0x3b +#define ATTR_DEV_CS1 0x3d +#define ATTR_DEV_CS0 0x3e +#define ATTR_PCIE_IO 0xe0 +#define ATTR_PCIE_MEM 0xe8 + +/* + * Helpers to get DDR bank info + */ +#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) +#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) + +/* + * CPU Address Decode Windows registers + */ +#define WIN_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) +#define WIN_CTRL_OFF 0x0000 +#define WIN_BASE_OFF 0x0004 +#define WIN_REMAP_LO_OFF 0x0008 +#define WIN_REMAP_HI_OFF 0x000c + + +struct mbus_dram_target_info kirkwood_mbus_dram_info; + +static int __init cpu_win_can_remap(int win) +{ + if (win < 4) + return 1; + + return 0; +} + +static void __init setup_cpu_win(int win, u32 base, u32 size, + u8 target, u8 attr, int remap) +{ + void __iomem *addr = (void __iomem *)WIN_OFF(win); + u32 ctrl; + + base &= 0xffff0000; + ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; + + writel(base, addr + WIN_BASE_OFF); + writel(ctrl, addr + WIN_CTRL_OFF); + if (cpu_win_can_remap(win)) { + if (remap < 0) + remap = base; + + writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF); + writel(0, addr + WIN_REMAP_HI_OFF); + } +} + +void __init kirkwood_setup_cpu_mbus(void) +{ + void __iomem *addr; + int i; + int cs; + + /* + * First, disable and clear windows. + */ + for (i = 0; i < 8; i++) { + addr = (void __iomem *)WIN_OFF(i); + + writel(0, addr + WIN_BASE_OFF); + writel(0, addr + WIN_CTRL_OFF); + if (cpu_win_can_remap(i)) { + writel(0, addr + WIN_REMAP_LO_OFF); + writel(0, addr + WIN_REMAP_HI_OFF); + } + } + + /* + * Setup windows for PCIe IO+MEM space. + */ + setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, + TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE); + setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, + TARGET_PCIE, ATTR_PCIE_MEM, -1); + + /* + * Setup window for NAND controller. + */ + setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, + TARGET_DEV_BUS, ATTR_DEV_NAND, -1); + + /* + * Setup MBUS dram target info. + */ + kirkwood_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; + + addr = (void __iomem *)DDR_WINDOW_CPU_BASE; + + for (i = 0, cs = 0; i < 4; i++) { + u32 base = readl(addr + DDR_BASE_CS_OFF(i)); + u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); + + /* + * Chip select enabled? + */ + if (size & 1) { + struct mbus_dram_window *w; + + w = &kirkwood_mbus_dram_info.cs[cs++]; + w->cs_index = i; + w->mbus_attr = 0xf & ~(1 << i); + w->base = base & 0xffff0000; + w->size = (size | 0x0000ffff) + 1; + } + } + kirkwood_mbus_dram_info.num_cs = cs; +} diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c new file mode 100644 index 00000000000..e73384fbbba --- /dev/null +++ b/arch/arm/mach-kirkwood/common.c @@ -0,0 +1,326 @@ +/* + * arch/arm/mach-kirkwood/common.c + * + * Core functions for Marvell Kirkwood SoCs + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +/***************************************************************************** + * I/O Address Mapping + ****************************************************************************/ +static struct map_desc kirkwood_io_desc[] __initdata = { + { + .virtual = KIRKWOOD_PCIE_IO_VIRT_BASE, + .pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE), + .length = KIRKWOOD_PCIE_IO_SIZE, + .type = MT_DEVICE, + }, { + .virtual = KIRKWOOD_REGS_VIRT_BASE, + .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE), + .length = KIRKWOOD_REGS_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init kirkwood_map_io(void) +{ + iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); +} + + +/***************************************************************************** + * EHCI + ****************************************************************************/ +static struct orion_ehci_data kirkwood_ehci_data = { + .dram = &kirkwood_mbus_dram_info, +}; + +static u64 ehci_dmamask = 0xffffffffUL; + + +/***************************************************************************** + * EHCI0 + ****************************************************************************/ +static struct resource kirkwood_ehci_resources[] = { + { + .start = USB_PHYS_BASE, + .end = USB_PHYS_BASE + 0x0fff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_KIRKWOOD_USB, + .end = IRQ_KIRKWOOD_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kirkwood_ehci = { + .name = "orion-ehci", + .id = 0, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &kirkwood_ehci_data, + }, + .resource = kirkwood_ehci_resources, + .num_resources = ARRAY_SIZE(kirkwood_ehci_resources), +}; + +void __init kirkwood_ehci_init(void) +{ + platform_device_register(&kirkwood_ehci); +} + + +/***************************************************************************** + * GE00 + ****************************************************************************/ +struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = { + .t_clk = KIRKWOOD_TCLK, + .dram = &kirkwood_mbus_dram_info, +}; + +static struct resource kirkwood_ge00_shared_resources[] = { + { + .name = "ge00 base", + .start = GE00_PHYS_BASE + 0x2000, + .end = GE00_PHYS_BASE + 0x3fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device kirkwood_ge00_shared = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .dev = { + .platform_data = &kirkwood_ge00_shared_data, + }, + .num_resources = 1, + .resource = kirkwood_ge00_shared_resources, +}; + +static struct resource kirkwood_ge00_resources[] = { + { + .name = "ge00 irq", + .start = IRQ_KIRKWOOD_GE00_SUM, + .end = IRQ_KIRKWOOD_GE00_SUM, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kirkwood_ge00 = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = 1, + .resource = kirkwood_ge00_resources, +}; + +void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) +{ + eth_data->shared = &kirkwood_ge00_shared; + kirkwood_ge00.dev.platform_data = eth_data; + + platform_device_register(&kirkwood_ge00_shared); + platform_device_register(&kirkwood_ge00); +} + + +/***************************************************************************** + * SoC RTC + ****************************************************************************/ +static struct resource kirkwood_rtc_resource = { + .start = RTC_PHYS_BASE, + .end = RTC_PHYS_BASE + SZ_16 - 1, + .flags = IORESOURCE_MEM, +}; + +void __init kirkwood_rtc_init(void) +{ + platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource, 1); +} + + +/***************************************************************************** + * SATA + ****************************************************************************/ +static struct resource kirkwood_sata_resources[] = { + { + .name = "sata base", + .start = SATA_PHYS_BASE, + .end = SATA_PHYS_BASE + 0x5000 - 1, + .flags = IORESOURCE_MEM, + }, { + .name = "sata irq", + .start = IRQ_KIRKWOOD_SATA, + .end = IRQ_KIRKWOOD_SATA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kirkwood_sata = { + .name = "sata_mv", + .id = 0, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(kirkwood_sata_resources), + .resource = kirkwood_sata_resources, +}; + +void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) +{ + sata_data->dram = &kirkwood_mbus_dram_info; + kirkwood_sata.dev.platform_data = sata_data; + platform_device_register(&kirkwood_sata); +} + + +/***************************************************************************** + * UART0 + ****************************************************************************/ +static struct plat_serial8250_port kirkwood_uart0_data[] = { + { + .mapbase = UART0_PHYS_BASE, + .membase = (char *)UART0_VIRT_BASE, + .irq = IRQ_KIRKWOOD_UART_0, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = KIRKWOOD_TCLK, + }, { + }, +}; + +static struct resource kirkwood_uart0_resources[] = { + { + .start = UART0_PHYS_BASE, + .end = UART0_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_KIRKWOOD_UART_0, + .end = IRQ_KIRKWOOD_UART_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kirkwood_uart0 = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = kirkwood_uart0_data, + }, + .resource = kirkwood_uart0_resources, + .num_resources = ARRAY_SIZE(kirkwood_uart0_resources), +}; + +void __init kirkwood_uart0_init(void) +{ + platform_device_register(&kirkwood_uart0); +} + + +/***************************************************************************** + * UART1 + ****************************************************************************/ +static struct plat_serial8250_port kirkwood_uart1_data[] = { + { + .mapbase = UART1_PHYS_BASE, + .membase = (char *)UART1_VIRT_BASE, + .irq = IRQ_KIRKWOOD_UART_1, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = KIRKWOOD_TCLK, + }, { + }, +}; + +static struct resource kirkwood_uart1_resources[] = { + { + .start = UART1_PHYS_BASE, + .end = UART1_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_KIRKWOOD_UART_1, + .end = IRQ_KIRKWOOD_UART_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kirkwood_uart1 = { + .name = "serial8250", + .id = 1, + .dev = { + .platform_data = kirkwood_uart1_data, + }, + .resource = kirkwood_uart1_resources, + .num_resources = ARRAY_SIZE(kirkwood_uart1_resources), +}; + +void __init kirkwood_uart1_init(void) +{ + platform_device_register(&kirkwood_uart1); +} + + +/***************************************************************************** + * Time handling + ****************************************************************************/ +static void kirkwood_timer_init(void) +{ + orion_time_init(IRQ_KIRKWOOD_BRIDGE, KIRKWOOD_TCLK); +} + +struct sys_timer kirkwood_timer = { + .init = kirkwood_timer_init, +}; + + +/***************************************************************************** + * General + ****************************************************************************/ +static char * __init kirkwood_id(void) +{ + switch (readl(DEVICE_ID) & 0x3) { + case 0: + return "88F6180"; + case 1: + return "88F6192"; + case 2: + return "88F6281"; + } + + return "unknown 88F6000 variant"; +} + +void __init kirkwood_init(void) +{ + printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n", + kirkwood_id(), KIRKWOOD_TCLK); + + kirkwood_setup_cpu_mbus(); + +#ifdef CONFIG_CACHE_FEROCEON_L2 + feroceon_l2_init(1); +#endif +} diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h new file mode 100644 index 00000000000..5dee2f6b40a --- /dev/null +++ b/arch/arm/mach-kirkwood/common.h @@ -0,0 +1,42 @@ +/* + * arch/arm/mach-kirkwood/common.h + * + * Core functions for Marvell Kirkwood SoCs + * + * 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 __ARCH_KIRKWOOD_COMMON_H +#define __ARCH_KIRKWOOD_COMMON_H + +struct mv643xx_eth_platform_data; +struct mv_sata_platform_data; + +/* + * Basic Kirkwood init functions used early by machine-setup. + */ +void kirkwood_map_io(void); +void kirkwood_init(void); +void kirkwood_init_irq(void); + +extern struct mbus_dram_target_info kirkwood_mbus_dram_info; +void kirkwood_setup_cpu_mbus(void); +void kirkwood_setup_pcie_io_win(int window, u32 base, u32 size, + int maj, int min); +void kirkwood_setup_pcie_mem_win(int window, u32 base, u32 size, + int maj, int min); + +void kirkwood_ehci_init(void); +void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data); +void kirkwood_pcie_init(void); +void kirkwood_rtc_init(void); +void kirkwood_sata_init(struct mv_sata_platform_data *sata_data); +void kirkwood_uart0_init(void); +void kirkwood_uart1_init(void); + +extern struct sys_timer kirkwood_timer; + + +#endif diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c new file mode 100644 index 00000000000..d5c482c628e --- /dev/null +++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c @@ -0,0 +1,68 @@ +/* + * arch/arm/mach-kirkwood/db88f6281-bp-setup.c + * + * Marvell DB-88F6281-BP Development Board Setup + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +static struct mv643xx_eth_platform_data db88f6281_ge00_data = { + .phy_addr = 8, +}; + +static struct mv_sata_platform_data db88f6281_sata_data = { + .n_ports = 2, +}; + +static void __init db88f6281_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&db88f6281_ge00_data); + kirkwood_rtc_init(); + kirkwood_sata_init(&db88f6281_sata_data); + kirkwood_uart0_init(); + kirkwood_uart1_init(); +} + +static int __init db88f6281_pci_init(void) +{ + if (machine_is_db88f6281_bp()) + kirkwood_pcie_init(); + + return 0; +} +subsys_initcall(db88f6281_pci_init); + +MACHINE_START(DB88F6281_BP, "Marvell DB-88F6281-BP Development Board") + /* Maintainer: Saeed Bishara */ + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = db88f6281_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &kirkwood_timer, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c new file mode 100644 index 00000000000..302bb2cf666 --- /dev/null +++ b/arch/arm/mach-kirkwood/irq.c @@ -0,0 +1,22 @@ +/* + * arch/arm/mach-kirkwood/irq.c + * + * Kirkwood IRQ handling. + * + * 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 +#include +#include +#include +#include +#include "common.h" + +void __init kirkwood_init_irq(void) +{ + orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); + orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); +} diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c new file mode 100644 index 00000000000..8282d0ff84b --- /dev/null +++ b/arch/arm/mach-kirkwood/pcie.c @@ -0,0 +1,180 @@ +/* + * arch/arm/mach-kirkwood/pcie.c + * + * PCIe functions for Marvell Kirkwood SoCs + * + * 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 +#include +#include +#include +#include +#include "common.h" + + +#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE) + +static int pcie_valid_config(int bus, int dev) +{ + /* + * Don't go out when trying to access -- + * 1. nonexisting device on local bus + * 2. where there's no device connected (no link) + */ + if (bus == 0 && dev == 0) + return 1; + + if (!orion_pcie_link_up(PCIE_BASE)) + return 0; + + if (bus == 0 && dev != 1) + return 0; + + return 1; +} + + +/* + * PCIe config cycles are done by programming the PCIE_CONF_ADDR register + * and then reading the PCIE_CONF_DATA register. Need to make sure these + * transactions are atomic. + */ +static DEFINE_SPINLOCK(kirkwood_pcie_lock); + +static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, + int size, u32 *val) +{ + unsigned long flags; + int ret; + + if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) { + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + spin_lock_irqsave(&kirkwood_pcie_lock, flags); + ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val); + spin_unlock_irqrestore(&kirkwood_pcie_lock, flags); + + return ret; +} + +static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 val) +{ + unsigned long flags; + int ret; + + if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + spin_lock_irqsave(&kirkwood_pcie_lock, flags); + ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val); + spin_unlock_irqrestore(&kirkwood_pcie_lock, flags); + + return ret; +} + +static struct pci_ops pcie_ops = { + .read = pcie_rd_conf, + .write = pcie_wr_conf, +}; + + +static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + /* + * Generic PCIe unit setup. + */ + orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info); + + /* + * Request resources. + */ + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("pcie_setup unable to alloc resources"); + + /* + * IORESOURCE_IO + */ + res[0].name = "PCIe I/O Space"; + res[0].flags = IORESOURCE_IO; + res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE; + res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; + if (request_resource(&ioport_resource, &res[0])) + panic("Request PCIe IO resource failed\n"); + sys->resource[0] = &res[0]; + + /* + * IORESOURCE_MEM + */ + res[1].name = "PCIe Memory Space"; + res[1].flags = IORESOURCE_MEM; + res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE; + res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1; + if (request_resource(&iomem_resource, &res[1])) + panic("Request PCIe Memory resource failed\n"); + sys->resource[1] = &res[1]; + + sys->resource[2] = NULL; + sys->io_offset = 0; + + return 1; +} + +static void __devinit rc_pci_fixup(struct pci_dev *dev) +{ + /* + * Prevent enumeration of root complex. + */ + if (dev->bus->parent == NULL && dev->devfn == 0) { + int i; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); + +static struct pci_bus __init * +kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys) +{ + struct pci_bus *bus; + + if (nr == 0) { + bus = pci_scan_bus(sys->busnr, &pcie_ops, sys); + } else { + bus = NULL; + BUG(); + } + + return bus; +} + +static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + return IRQ_KIRKWOOD_PCIE; +} + +static struct hw_pci kirkwood_pci __initdata = { + .nr_controllers = 1, + .swizzle = pci_std_swizzle, + .setup = kirkwood_pcie_setup, + .scan = kirkwood_pcie_scan_bus, + .map_irq = kirkwood_pcie_map_irq, +}; + +void __init kirkwood_pcie_init(void) +{ + pci_common_init(&kirkwood_pci); +} diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c new file mode 100644 index 00000000000..6cf642c504d --- /dev/null +++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c @@ -0,0 +1,69 @@ +/* + * arch/arm/mach-kirkwood/rd88f6192-nas-setup.c + * + * Marvell RD-88F6192-NAS Reference Board Setup + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +#define RD88F6192_GPIO_USB_VBUS 10 + +static struct mv643xx_eth_platform_data rd88f6192_ge00_data = { + .phy_addr = 8, +}; + +static struct mv_sata_platform_data rd88f6192_sata_data = { + .n_ports = 2, +}; + +static void __init rd88f6192_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&rd88f6192_ge00_data); + kirkwood_rtc_init(); + kirkwood_sata_init(&rd88f6192_sata_data); + kirkwood_uart0_init(); +} + +static int __init rd88f6192_pci_init(void) +{ + if (machine_is_rd88f6192_nas()) + kirkwood_pcie_init(); + + return 0; +} +subsys_initcall(rd88f6192_pci_init); + +MACHINE_START(RD88F6192_NAS, "Marvell RD-88F6192-NAS Development Board") + /* Maintainer: Saeed Bishara */ + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = rd88f6192_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &kirkwood_timer, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c new file mode 100644 index 00000000000..fe8b242d206 --- /dev/null +++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c @@ -0,0 +1,112 @@ +/* + * arch/arm/mach-kirkwood/rd88f6281-setup.c + * + * Marvell RD-88F6281 Reference Board Setup + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +static struct mtd_partition rd88f6281_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_2M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct resource rd88f6281_nand_resource = { + .flags = IORESOURCE_MEM, + .start = KIRKWOOD_NAND_MEM_PHYS_BASE, + .end = KIRKWOOD_NAND_MEM_PHYS_BASE + + KIRKWOOD_NAND_MEM_SIZE - 1, +}; + +static struct orion_nand_data rd88f6281_nand_data = { + .parts = rd88f6281_nand_parts, + .nr_parts = ARRAY_SIZE(rd88f6281_nand_parts), + .cle = 0, + .ale = 1, + .width = 8, +}; + +static struct platform_device rd88f6281_nand_flash = { + .name = "orion_nand", + .id = -1, + .dev = { + .platform_data = &rd88f6281_nand_data, + }, + .resource = &rd88f6281_nand_resource, + .num_resources = 1, +}; + +static struct mv643xx_eth_platform_data rd88f6281_ge00_data = { + .phy_addr = -1, +}; + +static struct mv_sata_platform_data rd88f6281_sata_data = { + .n_ports = 2, +}; + +static void __init rd88f6281_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&rd88f6281_ge00_data); + kirkwood_rtc_init(); + kirkwood_sata_init(&rd88f6281_sata_data); + kirkwood_uart0_init(); + kirkwood_uart1_init(); + + platform_device_register(&rd88f6281_nand_flash); +} + +static int __init rd88f6281_pci_init(void) +{ + if (machine_is_rd88f6281()) + kirkwood_pcie_init(); + + return 0; +} +subsys_initcall(rd88f6281_pci_init); + +MACHINE_START(RD88F6281, "Marvell RD-88F6281 Reference Board") + /* Maintainer: Saeed Bishara */ + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = rd88f6281_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &kirkwood_timer, +MACHINE_END diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 3b90051c0e0..a7a6efec897 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -365,7 +365,7 @@ config CPU_XSC3 # Feroceon config CPU_FEROCEON bool - depends on ARCH_ORION5X || ARCH_LOKI + depends on ARCH_ORION5X || ARCH_LOKI || ARCH_KIRKWOOD default y select CPU_32v5 select CPU_ABRT_EV5T @@ -716,7 +716,7 @@ config OUTER_CACHE config CACHE_FEROCEON_L2 bool "Enable the Feroceon L2 cache controller" - depends on FOOBAR + depends on ARCH_KIRKWOOD default y select OUTER_CACHE help diff --git a/include/asm-arm/arch-kirkwood/debug-macro.S b/include/asm-arm/arch-kirkwood/debug-macro.S new file mode 100644 index 00000000000..f55fb8ad9ee --- /dev/null +++ b/include/asm-arm/arch-kirkwood/debug-macro.S @@ -0,0 +1,20 @@ +/* + * include/asm-arm/arch-kirkwood/debug-macro.S + * + * 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 + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =KIRKWOOD_REGS_PHYS_BASE + ldrne \rx, =KIRKWOOD_REGS_VIRT_BASE + orr \rx, \rx, #0x00012000 + .endm + +#define UART_SHIFT 2 +#include diff --git a/include/asm-arm/arch-kirkwood/dma.h b/include/asm-arm/arch-kirkwood/dma.h new file mode 100644 index 00000000000..40a8c178f10 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/dma.h @@ -0,0 +1 @@ +/* empty */ diff --git a/include/asm-arm/arch-kirkwood/entry-macro.S b/include/asm-arm/arch-kirkwood/entry-macro.S new file mode 100644 index 00000000000..fc6a43d9355 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/entry-macro.S @@ -0,0 +1,40 @@ +/* + * include/asm-arm/arch-kirkwood/entry-macro.S + * + * Low-level IRQ helper macros for Marvell Kirkwood platforms + * + * 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 + + .macro disable_fiq + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =IRQ_VIRT_BASE + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + @ check low interrupts + ldr \irqstat, [\base, #IRQ_CAUSE_LOW_OFF] + ldr \tmp, [\base, #IRQ_MASK_LOW_OFF] + mov \irqnr, #31 + ands \irqstat, \irqstat, \tmp + bne 1001f + + @ if no low interrupts set, check high interrupts + ldr \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF] + ldr \tmp, [\base, #IRQ_MASK_HIGH_OFF] + mov \irqnr, #63 + ands \irqstat, \irqstat, \tmp + + @ find first active interrupt source +1001: clzne \irqstat, \irqstat + subne \irqnr, \irqnr, \irqstat + .endm diff --git a/include/asm-arm/arch-kirkwood/hardware.h b/include/asm-arm/arch-kirkwood/hardware.h new file mode 100644 index 00000000000..e695719771a --- /dev/null +++ b/include/asm-arm/arch-kirkwood/hardware.h @@ -0,0 +1,21 @@ +/* + * include/asm-arm/arch-kirkwood/hardware.h + * + * 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_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include "kirkwood.h" + +#define pcibios_assign_all_busses() 1 + +#define PCIBIOS_MIN_IO 0x00001000 +#define PCIBIOS_MIN_MEM 0x01000000 +#define PCIMEM_BASE KIRKWOOD_PCIE_MEM_PHYS_BASE /* mem base for VGA */ + + +#endif diff --git a/include/asm-arm/arch-kirkwood/io.h b/include/asm-arm/arch-kirkwood/io.h new file mode 100644 index 00000000000..0ef6e95f5d5 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/io.h @@ -0,0 +1,26 @@ +/* + * include/asm-arm/arch-kirkwood/io.h + * + * 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_IO_H +#define __ASM_ARCH_IO_H + +#include "kirkwood.h" + +#define IO_SPACE_LIMIT 0xffffffff + +static inline void __iomem *__io(unsigned long addr) +{ + return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_PHYS_BASE) + + KIRKWOOD_PCIE_IO_VIRT_BASE); +} + +#define __io(a) __io(a) +#define __mem_pci(a) (a) + + +#endif diff --git a/include/asm-arm/arch-kirkwood/irqs.h b/include/asm-arm/arch-kirkwood/irqs.h new file mode 100644 index 00000000000..2e7b5da6335 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/irqs.h @@ -0,0 +1,63 @@ +/* + * include/asm-arm/arch-kirkwood/irqs.h + * + * IRQ definitions for Marvell Kirkwood SoCs + * + * 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_IRQS_H +#define __ASM_ARCH_IRQS_H + +#include "kirkwood.h" /* need GPIO_MAX */ + +/* + * Low Interrupt Controller + */ +#define IRQ_KIRKWOOD_HIGH_SUM 0 +#define IRQ_KIRKWOOD_BRIDGE 1 +#define IRQ_KIRKWOOD_HOST2CPU 2 +#define IRQ_KIRKWOOD_CPU2HOST 3 +#define IRQ_KIRKWOOD_XOR_00 5 +#define IRQ_KIRKWOOD_XOR_01 6 +#define IRQ_KIRKWOOD_XOR_10 7 +#define IRQ_KIRKWOOD_XOR_11 8 +#define IRQ_KIRKWOOD_PCIE 9 +#define IRQ_KIRKWOOD_GE00_SUM 11 +#define IRQ_KIRKWOOD_GE01_SUM 15 +#define IRQ_KIRKWOOD_USB 19 +#define IRQ_KIRKWOOD_SATA 21 +#define IRQ_KIRKWOOD_CRYPTO 22 +#define IRQ_KIRKWOOD_SPI 23 +#define IRQ_KIRKWOOD_I2S 24 +#define IRQ_KIRKWOOD_TS_0 26 +#define IRQ_KIRKWOOD_SDIO 28 +#define IRQ_KIRKWOOD_TWSI 29 +#define IRQ_KIRKWOOD_AVB 30 +#define IRQ_KIRKWOOD_TDMI 31 + +/* + * High Interrupt Controller + */ +#define IRQ_KIRKWOOD_UART_0 33 +#define IRQ_KIRKWOOD_UART_1 34 +#define IRQ_KIRKWOOD_GPIO_LOW_0_7 35 +#define IRQ_KIRKWOOD_GPIO_LOW_8_15 36 +#define IRQ_KIRKWOOD_GPIO_LOW_16_23 37 +#define IRQ_KIRKWOOD_GPIO_LOW_24_31 38 +#define IRQ_KIRKWOOD_GPIO_HIGH_0_7 39 +#define IRQ_KIRKWOOD_GPIO_HIGH_8_15 40 +#define IRQ_KIRKWOOD_GPIO_HIGH_16_23 41 + +/* + * KIRKWOOD General Purpose Pins + */ +#define IRQ_KIRKWOOD_GPIO_START 64 +#define NR_GPIO_IRQS GPIO_MAX + +#define NR_IRQS (IRQ_KIRKWOOD_GPIO_START + NR_GPIO_IRQS) + + +#endif diff --git a/include/asm-arm/arch-kirkwood/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h new file mode 100644 index 00000000000..520250dbd8a --- /dev/null +++ b/include/asm-arm/arch-kirkwood/kirkwood.h @@ -0,0 +1,99 @@ +/* + * include/asm-arm/arch-kirkwood/kirkwood.h + * + * Generic definitions for Marvell Kirkwood SoC flavors: + * 88F6180, 88F6192 and 88F6281. + * + * 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_KIRKWOOD_H +#define __ASM_ARCH_KIRKWOOD_H + +/* + * Marvell Kirkwood address maps. + * + * phys + * e0000000 PCIe Memory space + * f1000000 on-chip peripheral registers + * f2000000 PCIe I/O space + * f3000000 NAND controller address window + * + * virt phys size + * fee00000 f1000000 1M on-chip peripheral registers + * fef00000 f2000000 1M PCIe I/O space + */ + +#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf3000000 +#define KIRKWOOD_NAND_MEM_SIZE SZ_64K /* 1K is sufficient, but 64K + * is the minimal window size + */ + +#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 +#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfef00000 +#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000 +#define KIRKWOOD_PCIE_IO_SIZE SZ_1M + +#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000 +#define KIRKWOOD_REGS_VIRT_BASE 0xfee00000 +#define KIRKWOOD_REGS_SIZE SZ_1M + +#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000 +#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M + +/* + * MBUS bridge registers. + */ +#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000) +#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104) +#define CPU_RESET 0x00000002 +//#define L2_WRITETHROUGH 0x00020000 +#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108) +#define SOFT_RESET_OUT_EN 0x00000004 +#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c) +#define SOFT_RESET 0x00000001 +#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE | 0x0110) +#define BRIDGE_MASK (BRIDGE_VIRT_BASE | 0x0114) +#define BRIDGE_INT_TIMER0 0x0002 +#define BRIDGE_INT_TIMER1 0x0004 +#define BRIDGE_INT_TIMER1_CLR (~0x0004) +#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200) +#define IRQ_CAUSE_LOW_OFF 0x0000 +#define IRQ_MASK_LOW_OFF 0x0004 +#define IRQ_CAUSE_HIGH_OFF 0x0010 +#define IRQ_MASK_HIGH_OFF 0x0014 +#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) + +/* + * Register Map + */ +#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x00000) +#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE | 0x1500) + +#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x10000) +#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x10000) +#define SAMPLE_AT_RESET (DEV_BUS_VIRT_BASE | 0x0030) +#define DEVICE_ID (DEV_BUS_VIRT_BASE | 0x0034) +#define RTC_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0300) +#define SPI_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0600) +#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000) +#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000) +#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100) +#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100) + +#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000) + +#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000) + +#define GE00_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x70000) +#define GE01_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x74000) + +#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x80000) + + +#define GPIO_MAX 50 + + +#endif diff --git a/include/asm-arm/arch-kirkwood/memory.h b/include/asm-arm/arch-kirkwood/memory.h new file mode 100644 index 00000000000..e5108f408ce --- /dev/null +++ b/include/asm-arm/arch-kirkwood/memory.h @@ -0,0 +1,14 @@ +/* + * include/asm-arm/arch-kirkwood/memory.h + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#define PHYS_OFFSET UL(0x00000000) + +#define __virt_to_bus(x) __virt_to_phys(x) +#define __bus_to_virt(x) __phys_to_virt(x) + + +#endif diff --git a/include/asm-arm/arch-kirkwood/system.h b/include/asm-arm/arch-kirkwood/system.h new file mode 100644 index 00000000000..8dde7e37985 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/system.h @@ -0,0 +1,37 @@ +/* + * include/asm-arm/arch-kirkwood/system.h + * + * 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_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#include +#include + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode) +{ + /* + * Enable soft reset to assert RSTOUTn. + */ + writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK); + + /* + * Assert soft reset. + */ + writel(SOFT_RESET, SYSTEM_SOFT_RESET); + + while (1) + ; +} + + +#endif diff --git a/include/asm-arm/arch-kirkwood/timex.h b/include/asm-arm/arch-kirkwood/timex.h new file mode 100644 index 00000000000..82122e134e3 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/timex.h @@ -0,0 +1,11 @@ +/* + * include/asm-arm/arch-kirkwood/timex.h + * + * 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. + */ + +#define CLOCK_TICK_RATE (100 * HZ) + +#define KIRKWOOD_TCLK 166666667 diff --git a/include/asm-arm/arch-kirkwood/uncompress.h b/include/asm-arm/arch-kirkwood/uncompress.h new file mode 100644 index 00000000000..a9062b6d768 --- /dev/null +++ b/include/asm-arm/arch-kirkwood/uncompress.h @@ -0,0 +1,47 @@ +/* + * include/asm-arm/arch-kirkwood/uncompress.h + * + * 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 +#include + +#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE) + +static void putc(const char c) +{ + unsigned char *base = SERIAL_BASE; + int i; + + for (i = 0; i < 0x1000; i++) { + if (base[UART_LSR << 2] & UART_LSR_THRE) + break; + barrier(); + } + + base[UART_TX << 2] = c; +} + +static void flush(void) +{ + unsigned char *base = SERIAL_BASE; + unsigned char mask; + int i; + + mask = UART_LSR_TEMT | UART_LSR_THRE; + + for (i = 0; i < 0x1000; i++) { + if ((base[UART_LSR << 2] & mask) == mask) + break; + barrier(); + } +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-kirkwood/vmalloc.h b/include/asm-arm/arch-kirkwood/vmalloc.h new file mode 100644 index 00000000000..41852c6e77f --- /dev/null +++ b/include/asm-arm/arch-kirkwood/vmalloc.h @@ -0,0 +1,5 @@ +/* + * include/asm-arm/arch-kirkwood/vmalloc.h + */ + +#define VMALLOC_END 0xfe800000 -- cgit v1.2.3-70-g09d2 From a9311cfed241ebcd6b5f9be5c8c6d519bf22f9e7 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 22 Jun 2008 22:45:09 +0200 Subject: [ARM] Orion: PCIe x4/x1 detection support The Discovery Duo (MV78xx0) has two x4 PCIe ports which can either be used in x4 mode or in quad x1 mode. This patch adds an accessor function to the generic plat-orion PCIe handling code to detect in which of the two modes we're running (which is determined by strap pins and/or configured by the bootloader). Signed-off-by: Lennert Buytenhek --- arch/arm/plat-orion/pcie.c | 6 ++++++ include/asm-arm/plat-orion/pcie.h | 1 + 2 files changed, 7 insertions(+) (limited to 'include/asm-arm') diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c index abfda53f180..ca32c60e14d 100644 --- a/arch/arm/plat-orion/pcie.c +++ b/arch/arm/plat-orion/pcie.c @@ -39,6 +39,7 @@ #define PCIE_CONF_DATA_OFF 0x18fc #define PCIE_MASK_OFF 0x1910 #define PCIE_CTRL_OFF 0x1a00 +#define PCIE_CTRL_X1_MODE 0x0001 #define PCIE_STAT_OFF 0x1a04 #define PCIE_STAT_DEV_OFFS 20 #define PCIE_STAT_DEV_MASK 0x1f @@ -62,6 +63,11 @@ int orion_pcie_link_up(void __iomem *base) return !(readl(base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN); } +int __init orion_pcie_x4_mode(void __iomem *base) +{ + return !(readl(base + PCIE_CTRL_OFF) & PCIE_CTRL_X1_MODE); +} + int orion_pcie_get_local_bus_nr(void __iomem *base) { u32 stat = readl(base + PCIE_STAT_OFF); diff --git a/include/asm-arm/plat-orion/pcie.h b/include/asm-arm/plat-orion/pcie.h index 6434ac685d2..e61b7bd97af 100644 --- a/include/asm-arm/plat-orion/pcie.h +++ b/include/asm-arm/plat-orion/pcie.h @@ -14,6 +14,7 @@ u32 orion_pcie_dev_id(void __iomem *base); u32 orion_pcie_rev(void __iomem *base); int orion_pcie_link_up(void __iomem *base); +int orion_pcie_x4_mode(void __iomem *base); int orion_pcie_get_local_bus_nr(void __iomem *base); void orion_pcie_set_local_bus_nr(void __iomem *base, int nr); void orion_pcie_setup(void __iomem *base, -- cgit v1.2.3-70-g09d2 From 794d15b25df5dda10efba600d6dd6cd74a7aa9cb Mon Sep 17 00:00:00 2001 From: Stanislav Samsonov Date: Sun, 22 Jun 2008 22:45:10 +0200 Subject: [ARM] add Marvell 78xx0 ARM SoC support The Marvell Discovery Duo (MV78xx0) is a family of ARM SoCs featuring (depending on the model) one or two Feroceon CPU cores with 512K of L2 cache and VFP coprocessors running at (depending on the model) between 800 MHz and 1.2 GHz, and features a DDR2 controller, two PCIe interfaces that can each run either in x4 or quad x1 mode, three USB 2.0 interfaces, two 3Gb/s SATA II interfaces, a SPI interface, two TWSI interfaces, a crypto accelerator, IDMA/XOR engines, a SPI interface, four UARTs, and depending on the model, two or four gigabit ethernet interfaces. This patch adds basic support for the platform, and allows booting on the MV78x00 development board, with functional UARTs, SATA, PCIe, GigE and USB ports. Signed-off-by: Stanislav Samsonov Signed-off-by: Lennert Buytenhek --- arch/arm/Kconfig | 12 + arch/arm/Makefile | 1 + arch/arm/mach-mv78xx0/Kconfig | 13 + arch/arm/mach-mv78xx0/Makefile | 2 + arch/arm/mach-mv78xx0/Makefile.boot | 3 + arch/arm/mach-mv78xx0/addr-map.c | 156 ++++++ arch/arm/mach-mv78xx0/common.c | 754 +++++++++++++++++++++++++++++ arch/arm/mach-mv78xx0/common.h | 49 ++ arch/arm/mach-mv78xx0/db78x00-bp-setup.c | 94 ++++ arch/arm/mach-mv78xx0/irq.c | 22 + arch/arm/mach-mv78xx0/pcie.c | 312 ++++++++++++ arch/arm/mm/Kconfig | 4 +- include/asm-arm/arch-mv78xx0/debug-macro.S | 20 + include/asm-arm/arch-mv78xx0/dma.h | 1 + include/asm-arm/arch-mv78xx0/entry-macro.S | 39 ++ include/asm-arm/arch-mv78xx0/hardware.h | 21 + include/asm-arm/arch-mv78xx0/io.h | 26 + include/asm-arm/arch-mv78xx0/irqs.h | 91 ++++ include/asm-arm/arch-mv78xx0/memory.h | 14 + include/asm-arm/arch-mv78xx0/mv78xx0.h | 126 +++++ include/asm-arm/arch-mv78xx0/system.h | 37 ++ include/asm-arm/arch-mv78xx0/timex.h | 9 + include/asm-arm/arch-mv78xx0/uncompress.h | 47 ++ include/asm-arm/arch-mv78xx0/vmalloc.h | 5 + 24 files changed, 1856 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-mv78xx0/Kconfig create mode 100644 arch/arm/mach-mv78xx0/Makefile create mode 100644 arch/arm/mach-mv78xx0/Makefile.boot create mode 100644 arch/arm/mach-mv78xx0/addr-map.c create mode 100644 arch/arm/mach-mv78xx0/common.c create mode 100644 arch/arm/mach-mv78xx0/common.h create mode 100644 arch/arm/mach-mv78xx0/db78x00-bp-setup.c create mode 100644 arch/arm/mach-mv78xx0/irq.c create mode 100644 arch/arm/mach-mv78xx0/pcie.c create mode 100644 include/asm-arm/arch-mv78xx0/debug-macro.S create mode 100644 include/asm-arm/arch-mv78xx0/dma.h create mode 100644 include/asm-arm/arch-mv78xx0/entry-macro.S create mode 100644 include/asm-arm/arch-mv78xx0/hardware.h create mode 100644 include/asm-arm/arch-mv78xx0/io.h create mode 100644 include/asm-arm/arch-mv78xx0/irqs.h create mode 100644 include/asm-arm/arch-mv78xx0/memory.h create mode 100644 include/asm-arm/arch-mv78xx0/mv78xx0.h create mode 100644 include/asm-arm/arch-mv78xx0/system.h create mode 100644 include/asm-arm/arch-mv78xx0/timex.h create mode 100644 include/asm-arm/arch-mv78xx0/uncompress.h create mode 100644 include/asm-arm/arch-mv78xx0/vmalloc.h (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3535cae73d2..5bf60d5897d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -388,6 +388,16 @@ config ARCH_LOKI help Support for the Marvell Loki (88RC8480) SoC. +config ARCH_MV78XX0 + bool "Marvell MV78xx0" + select PCI + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select PLAT_ORION + help + Support for the following Marvell MV78xx0 series SoCs: + MV781x0, MV782x0. + config ARCH_MXC bool "Freescale MXC/iMX-based" select ARCH_MTD_XIP @@ -528,6 +538,8 @@ source "arch/arm/mach-ixp23xx/Kconfig" source "arch/arm/mach-loki/Kconfig" +source "arch/arm/mach-mv78xx0/Kconfig" + source "arch/arm/mach-pxa/Kconfig" source "arch/arm/mach-sa1100/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1459b3849c8..b53237bb6f1 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -142,6 +142,7 @@ endif machine-$(CONFIG_ARCH_ORION5X) := orion5x machine-$(CONFIG_ARCH_MSM7X00A) := msm machine-$(CONFIG_ARCH_LOKI) := loki + machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig new file mode 100644 index 00000000000..d83cb86837d --- /dev/null +++ b/arch/arm/mach-mv78xx0/Kconfig @@ -0,0 +1,13 @@ +if ARCH_MV78XX0 + +menu "Marvell MV78xx0 Implementations" + +config MACH_DB78X00_BP + bool "Marvell DB-78x00-BP Development Board" + help + Say 'Y' here if you want your kernel to support the + Marvell DB-78x00-BP Development Board. + +endmenu + +endif diff --git a/arch/arm/mach-mv78xx0/Makefile b/arch/arm/mach-mv78xx0/Makefile new file mode 100644 index 00000000000..ec16c05c3b1 --- /dev/null +++ b/arch/arm/mach-mv78xx0/Makefile @@ -0,0 +1,2 @@ +obj-y += common.o addr-map.o irq.o pcie.o +obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o diff --git a/arch/arm/mach-mv78xx0/Makefile.boot b/arch/arm/mach-mv78xx0/Makefile.boot new file mode 100644 index 00000000000..67039c3e0c4 --- /dev/null +++ b/arch/arm/mach-mv78xx0/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c new file mode 100644 index 00000000000..4004b672a2e --- /dev/null +++ b/arch/arm/mach-mv78xx0/addr-map.c @@ -0,0 +1,156 @@ +/* + * arch/arm/mach-mv78xx0/addr-map.c + * + * Address map functions for Marvell MV78xx0 SoCs + * + * 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 +#include +#include +#include +#include "common.h" + +/* + * Generic Address Decode Windows bit settings + */ +#define TARGET_DDR 0 +#define TARGET_DEV_BUS 1 +#define TARGET_PCIE0 4 +#define TARGET_PCIE1 8 +#define TARGET_PCIE(i) ((i) ? TARGET_PCIE1 : TARGET_PCIE0) +#define ATTR_DEV_SPI_ROM 0x1f +#define ATTR_DEV_BOOT 0x2f +#define ATTR_DEV_CS3 0x37 +#define ATTR_DEV_CS2 0x3b +#define ATTR_DEV_CS1 0x3d +#define ATTR_DEV_CS0 0x3e +#define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l))) +#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l))) + +/* + * Helpers to get DDR bank info + */ +#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) +#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) + +/* + * CPU Address Decode Windows registers + */ +#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) +#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) +#define WIN_CTRL_OFF 0x0000 +#define WIN_BASE_OFF 0x0004 +#define WIN_REMAP_LO_OFF 0x0008 +#define WIN_REMAP_HI_OFF 0x000c + + +struct mbus_dram_target_info mv78xx0_mbus_dram_info; + +static void __init __iomem *win_cfg_base(int win) +{ + /* + * Find the control register base address for this window. + * + * BRIDGE_VIRT_BASE points to the right (CPU0's or CPU1's) + * MBUS bridge depending on which CPU core we're running on, + * so we don't need to take that into account here. + */ + + return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win)); +} + +static int __init cpu_win_can_remap(int win) +{ + if (win < 8) + return 1; + + return 0; +} + +static void __init setup_cpu_win(int win, u32 base, u32 size, + u8 target, u8 attr, int remap) +{ + void __iomem *addr = win_cfg_base(win); + u32 ctrl; + + base &= 0xffff0000; + ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; + + writel(base, addr + WIN_BASE_OFF); + writel(ctrl, addr + WIN_CTRL_OFF); + if (cpu_win_can_remap(win)) { + if (remap < 0) + remap = base; + + writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF); + writel(0, addr + WIN_REMAP_HI_OFF); + } +} + +void __init mv78xx0_setup_cpu_mbus(void) +{ + void __iomem *addr; + int i; + int cs; + + /* + * First, disable and clear windows. + */ + for (i = 0; i < 14; i++) { + addr = win_cfg_base(i); + + writel(0, addr + WIN_BASE_OFF); + writel(0, addr + WIN_CTRL_OFF); + if (cpu_win_can_remap(i)) { + writel(0, addr + WIN_REMAP_LO_OFF); + writel(0, addr + WIN_REMAP_HI_OFF); + } + } + + /* + * Setup MBUS dram target info. + */ + mv78xx0_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; + + if (mv78xx0_core_index() == 0) + addr = (void __iomem *)DDR_WINDOW_CPU0_BASE; + else + addr = (void __iomem *)DDR_WINDOW_CPU1_BASE; + + for (i = 0, cs = 0; i < 4; i++) { + u32 base = readl(addr + DDR_BASE_CS_OFF(i)); + u32 size = readl(addr + DDR_SIZE_CS_OFF(i)); + + /* + * Chip select enabled? + */ + if (size & 1) { + struct mbus_dram_window *w; + + w = &mv78xx0_mbus_dram_info.cs[cs++]; + w->cs_index = i; + w->mbus_attr = 0xf & ~(1 << i); + w->base = base & 0xffff0000; + w->size = (size | 0x0000ffff) + 1; + } + } + mv78xx0_mbus_dram_info.num_cs = cs; +} + +void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, + int maj, int min) +{ + setup_cpu_win(window, base, size, TARGET_PCIE(maj), + ATTR_PCIE_IO(min), -1); +} + +void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, + int maj, int min) +{ + setup_cpu_win(window, base, size, TARGET_PCIE(maj), + ATTR_PCIE_MEM(min), -1); +} diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c new file mode 100644 index 00000000000..d27b83b7bf6 --- /dev/null +++ b/arch/arm/mach-mv78xx0/common.c @@ -0,0 +1,754 @@ +/* + * arch/arm/mach-mv78xx0/common.c + * + * Core functions for Marvell MV78xx0 SoCs + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + + +/***************************************************************************** + * Common bits + ****************************************************************************/ +int mv78xx0_core_index(void) +{ + u32 extra; + + /* + * Read Extra Features register. + */ + __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra)); + + return !!(extra & 0x00004000); +} + +static int get_hclk(void) +{ + int hclk; + + /* + * HCLK tick rate is configured by DEV_D[7:5] pins. + */ + switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) { + case 0: + hclk = 166666667; + break; + case 1: + hclk = 200000000; + break; + case 2: + hclk = 266666667; + break; + case 3: + hclk = 333333333; + break; + case 4: + hclk = 400000000; + break; + default: + panic("unknown HCLK PLL setting: %.8x\n", + readl(SAMPLE_AT_RESET_LOW)); + } + + return hclk; +} + +static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk) +{ + u32 cfg; + + /* + * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1 + * PCLK/L2CLK by bits [19:14]. + */ + if (core_index == 0) { + cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f; + } else { + cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f; + } + + /* + * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK + * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6). + */ + *pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1; + + /* + * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK + * ratio (1, 2, 3). + */ + *l2clk = *pclk / (((cfg >> 4) & 3) + 1); +} + +static int get_tclk(void) +{ + int tclk; + + /* + * TCLK tick rate is configured by DEV_A[2:0] strap pins. + */ + switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) { + case 1: + tclk = 166666667; + break; + case 3: + tclk = 200000000; + break; + default: + panic("unknown TCLK PLL setting: %.8x\n", + readl(SAMPLE_AT_RESET_HIGH)); + } + + return tclk; +} + + +/***************************************************************************** + * I/O Address Mapping + ****************************************************************************/ +static struct map_desc mv78xx0_io_desc[] __initdata = { + { + .virtual = MV78XX0_CORE_REGS_VIRT_BASE, + .pfn = 0, + .length = MV78XX0_CORE_REGS_SIZE, + .type = MT_DEVICE, + }, { + .virtual = MV78XX0_PCIE_IO_VIRT_BASE(0), + .pfn = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)), + .length = MV78XX0_PCIE_IO_SIZE * 8, + .type = MT_DEVICE, + }, { + .virtual = MV78XX0_REGS_VIRT_BASE, + .pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE), + .length = MV78XX0_REGS_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init mv78xx0_map_io(void) +{ + unsigned long phys; + + /* + * Map the right set of per-core registers depending on + * which core we are running on. + */ + if (mv78xx0_core_index() == 0) { + phys = MV78XX0_CORE0_REGS_PHYS_BASE; + } else { + phys = MV78XX0_CORE1_REGS_PHYS_BASE; + } + mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys); + + iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc)); +} + + +/***************************************************************************** + * EHCI + ****************************************************************************/ +static struct orion_ehci_data mv78xx0_ehci_data = { + .dram = &mv78xx0_mbus_dram_info, +}; + +static u64 ehci_dmamask = 0xffffffffUL; + + +/***************************************************************************** + * EHCI0 + ****************************************************************************/ +static struct resource mv78xx0_ehci0_resources[] = { + { + .start = USB0_PHYS_BASE, + .end = USB0_PHYS_BASE + 0x0fff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_MV78XX0_USB_0, + .end = IRQ_MV78XX0_USB_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_ehci0 = { + .name = "orion-ehci", + .id = 0, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mv78xx0_ehci_data, + }, + .resource = mv78xx0_ehci0_resources, + .num_resources = ARRAY_SIZE(mv78xx0_ehci0_resources), +}; + +void __init mv78xx0_ehci0_init(void) +{ + platform_device_register(&mv78xx0_ehci0); +} + + +/***************************************************************************** + * EHCI1 + ****************************************************************************/ +static struct resource mv78xx0_ehci1_resources[] = { + { + .start = USB1_PHYS_BASE, + .end = USB1_PHYS_BASE + 0x0fff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_MV78XX0_USB_1, + .end = IRQ_MV78XX0_USB_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_ehci1 = { + .name = "orion-ehci", + .id = 1, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mv78xx0_ehci_data, + }, + .resource = mv78xx0_ehci1_resources, + .num_resources = ARRAY_SIZE(mv78xx0_ehci1_resources), +}; + +void __init mv78xx0_ehci1_init(void) +{ + platform_device_register(&mv78xx0_ehci1); +} + + +/***************************************************************************** + * EHCI2 + ****************************************************************************/ +static struct resource mv78xx0_ehci2_resources[] = { + { + .start = USB2_PHYS_BASE, + .end = USB2_PHYS_BASE + 0x0fff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_MV78XX0_USB_2, + .end = IRQ_MV78XX0_USB_2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_ehci2 = { + .name = "orion-ehci", + .id = 2, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mv78xx0_ehci_data, + }, + .resource = mv78xx0_ehci2_resources, + .num_resources = ARRAY_SIZE(mv78xx0_ehci2_resources), +}; + +void __init mv78xx0_ehci2_init(void) +{ + platform_device_register(&mv78xx0_ehci2); +} + + +/***************************************************************************** + * GE00 + ****************************************************************************/ +struct mv643xx_eth_shared_platform_data mv78xx0_ge00_shared_data = { + .t_clk = 0, + .dram = &mv78xx0_mbus_dram_info, +}; + +static struct resource mv78xx0_ge00_shared_resources[] = { + { + .name = "ge00 base", + .start = GE00_PHYS_BASE + 0x2000, + .end = GE00_PHYS_BASE + 0x3fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv78xx0_ge00_shared = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .dev = { + .platform_data = &mv78xx0_ge00_shared_data, + }, + .num_resources = 1, + .resource = mv78xx0_ge00_shared_resources, +}; + +static struct resource mv78xx0_ge00_resources[] = { + { + .name = "ge00 irq", + .start = IRQ_MV78XX0_GE00_SUM, + .end = IRQ_MV78XX0_GE00_SUM, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_ge00 = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = 1, + .resource = mv78xx0_ge00_resources, +}; + +void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data) +{ + eth_data->shared = &mv78xx0_ge00_shared; + mv78xx0_ge00.dev.platform_data = eth_data; + + platform_device_register(&mv78xx0_ge00_shared); + platform_device_register(&mv78xx0_ge00); +} + + +/***************************************************************************** + * GE01 + ****************************************************************************/ +struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = { + .t_clk = 0, + .dram = &mv78xx0_mbus_dram_info, +}; + +static struct resource mv78xx0_ge01_shared_resources[] = { + { + .name = "ge01 base", + .start = GE01_PHYS_BASE + 0x2000, + .end = GE01_PHYS_BASE + 0x3fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv78xx0_ge01_shared = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 1, + .dev = { + .platform_data = &mv78xx0_ge01_shared_data, + }, + .num_resources = 1, + .resource = mv78xx0_ge01_shared_resources, +}; + +static struct resource mv78xx0_ge01_resources[] = { + { + .name = "ge01 irq", + .start = IRQ_MV78XX0_GE01_SUM, + .end = IRQ_MV78XX0_GE01_SUM, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_ge01 = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = 1, + .resource = mv78xx0_ge01_resources, +}; + +void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data) +{ + eth_data->shared = &mv78xx0_ge01_shared; + eth_data->shared_smi = &mv78xx0_ge00_shared; + mv78xx0_ge01.dev.platform_data = eth_data; + + platform_device_register(&mv78xx0_ge01_shared); + platform_device_register(&mv78xx0_ge01); +} + + +/***************************************************************************** + * GE10 + ****************************************************************************/ +struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = { + .t_clk = 0, + .dram = &mv78xx0_mbus_dram_info, +}; + +static struct resource mv78xx0_ge10_shared_resources[] = { + { + .name = "ge10 base", + .start = GE10_PHYS_BASE + 0x2000, + .end = GE10_PHYS_BASE + 0x3fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv78xx0_ge10_shared = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 2, + .dev = { + .platform_data = &mv78xx0_ge10_shared_data, + }, + .num_resources = 1, + .resource = mv78xx0_ge10_shared_resources, +}; + +static struct resource mv78xx0_ge10_resources[] = { + { + .name = "ge10 irq", + .start = IRQ_MV78XX0_GE10_SUM, + .end = IRQ_MV78XX0_GE10_SUM, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_ge10 = { + .name = MV643XX_ETH_NAME, + .id = 2, + .num_resources = 1, + .resource = mv78xx0_ge10_resources, +}; + +void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data) +{ + eth_data->shared = &mv78xx0_ge10_shared; + eth_data->shared_smi = &mv78xx0_ge00_shared; + mv78xx0_ge10.dev.platform_data = eth_data; + + platform_device_register(&mv78xx0_ge10_shared); + platform_device_register(&mv78xx0_ge10); +} + + +/***************************************************************************** + * GE11 + ****************************************************************************/ +struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = { + .t_clk = 0, + .dram = &mv78xx0_mbus_dram_info, +}; + +static struct resource mv78xx0_ge11_shared_resources[] = { + { + .name = "ge11 base", + .start = GE11_PHYS_BASE + 0x2000, + .end = GE11_PHYS_BASE + 0x3fff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv78xx0_ge11_shared = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 3, + .dev = { + .platform_data = &mv78xx0_ge11_shared_data, + }, + .num_resources = 1, + .resource = mv78xx0_ge11_shared_resources, +}; + +static struct resource mv78xx0_ge11_resources[] = { + { + .name = "ge11 irq", + .start = IRQ_MV78XX0_GE11_SUM, + .end = IRQ_MV78XX0_GE11_SUM, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_ge11 = { + .name = MV643XX_ETH_NAME, + .id = 3, + .num_resources = 1, + .resource = mv78xx0_ge11_resources, +}; + +void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data) +{ + eth_data->shared = &mv78xx0_ge11_shared; + eth_data->shared_smi = &mv78xx0_ge00_shared; + mv78xx0_ge11.dev.platform_data = eth_data; + + platform_device_register(&mv78xx0_ge11_shared); + platform_device_register(&mv78xx0_ge11); +} + + +/***************************************************************************** + * SATA + ****************************************************************************/ +static struct resource mv78xx0_sata_resources[] = { + { + .name = "sata base", + .start = SATA_PHYS_BASE, + .end = SATA_PHYS_BASE + 0x5000 - 1, + .flags = IORESOURCE_MEM, + }, { + .name = "sata irq", + .start = IRQ_MV78XX0_SATA, + .end = IRQ_MV78XX0_SATA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_sata = { + .name = "sata_mv", + .id = 0, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(mv78xx0_sata_resources), + .resource = mv78xx0_sata_resources, +}; + +void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data) +{ + sata_data->dram = &mv78xx0_mbus_dram_info; + mv78xx0_sata.dev.platform_data = sata_data; + platform_device_register(&mv78xx0_sata); +} + + +/***************************************************************************** + * UART0 + ****************************************************************************/ +static struct plat_serial8250_port mv78xx0_uart0_data[] = { + { + .mapbase = UART0_PHYS_BASE, + .membase = (char *)UART0_VIRT_BASE, + .irq = IRQ_MV78XX0_UART_0, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = 0, + }, { + }, +}; + +static struct resource mv78xx0_uart0_resources[] = { + { + .start = UART0_PHYS_BASE, + .end = UART0_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_MV78XX0_UART_0, + .end = IRQ_MV78XX0_UART_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_uart0 = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = mv78xx0_uart0_data, + }, + .resource = mv78xx0_uart0_resources, + .num_resources = ARRAY_SIZE(mv78xx0_uart0_resources), +}; + +void __init mv78xx0_uart0_init(void) +{ + platform_device_register(&mv78xx0_uart0); +} + + +/***************************************************************************** + * UART1 + ****************************************************************************/ +static struct plat_serial8250_port mv78xx0_uart1_data[] = { + { + .mapbase = UART1_PHYS_BASE, + .membase = (char *)UART1_VIRT_BASE, + .irq = IRQ_MV78XX0_UART_1, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = 0, + }, { + }, +}; + +static struct resource mv78xx0_uart1_resources[] = { + { + .start = UART1_PHYS_BASE, + .end = UART1_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_MV78XX0_UART_1, + .end = IRQ_MV78XX0_UART_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_uart1 = { + .name = "serial8250", + .id = 1, + .dev = { + .platform_data = mv78xx0_uart1_data, + }, + .resource = mv78xx0_uart1_resources, + .num_resources = ARRAY_SIZE(mv78xx0_uart1_resources), +}; + +void __init mv78xx0_uart1_init(void) +{ + platform_device_register(&mv78xx0_uart1); +} + + +/***************************************************************************** + * UART2 + ****************************************************************************/ +static struct plat_serial8250_port mv78xx0_uart2_data[] = { + { + .mapbase = UART2_PHYS_BASE, + .membase = (char *)UART2_VIRT_BASE, + .irq = IRQ_MV78XX0_UART_2, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = 0, + }, { + }, +}; + +static struct resource mv78xx0_uart2_resources[] = { + { + .start = UART2_PHYS_BASE, + .end = UART2_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_MV78XX0_UART_2, + .end = IRQ_MV78XX0_UART_2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_uart2 = { + .name = "serial8250", + .id = 2, + .dev = { + .platform_data = mv78xx0_uart2_data, + }, + .resource = mv78xx0_uart2_resources, + .num_resources = ARRAY_SIZE(mv78xx0_uart2_resources), +}; + +void __init mv78xx0_uart2_init(void) +{ + platform_device_register(&mv78xx0_uart2); +} + + +/***************************************************************************** + * UART3 + ****************************************************************************/ +static struct plat_serial8250_port mv78xx0_uart3_data[] = { + { + .mapbase = UART3_PHYS_BASE, + .membase = (char *)UART3_VIRT_BASE, + .irq = IRQ_MV78XX0_UART_3, + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = 0, + }, { + }, +}; + +static struct resource mv78xx0_uart3_resources[] = { + { + .start = UART3_PHYS_BASE, + .end = UART3_PHYS_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_MV78XX0_UART_3, + .end = IRQ_MV78XX0_UART_3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mv78xx0_uart3 = { + .name = "serial8250", + .id = 3, + .dev = { + .platform_data = mv78xx0_uart3_data, + }, + .resource = mv78xx0_uart3_resources, + .num_resources = ARRAY_SIZE(mv78xx0_uart3_resources), +}; + +void __init mv78xx0_uart3_init(void) +{ + platform_device_register(&mv78xx0_uart3); +} + + +/***************************************************************************** + * Time handling + ****************************************************************************/ +static void mv78xx0_timer_init(void) +{ + orion_time_init(IRQ_MV78XX0_TIMER_1, get_tclk()); +} + +struct sys_timer mv78xx0_timer = { + .init = mv78xx0_timer_init, +}; + + +/***************************************************************************** + * General + ****************************************************************************/ +static int __init is_l2_writethrough(void) +{ + return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH); +} + +void __init mv78xx0_init(void) +{ + int core_index; + int hclk; + int pclk; + int l2clk; + int tclk; + + core_index = mv78xx0_core_index(); + hclk = get_hclk(); + get_pclk_l2clk(hclk, core_index, &pclk, &l2clk); + tclk = get_tclk(); + + printk(KERN_INFO "MV78xx0 core #%d, ", core_index); + printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000); + printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000); + printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000); + printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000); + + mv78xx0_setup_cpu_mbus(); + +#ifdef CONFIG_CACHE_FEROCEON_L2 + feroceon_l2_init(is_l2_writethrough()); +#endif + + mv78xx0_ge00_shared_data.t_clk = tclk; + mv78xx0_ge01_shared_data.t_clk = tclk; + mv78xx0_ge10_shared_data.t_clk = tclk; + mv78xx0_ge11_shared_data.t_clk = tclk; + mv78xx0_uart0_data[0].uartclk = tclk; + mv78xx0_uart1_data[0].uartclk = tclk; + mv78xx0_uart2_data[0].uartclk = tclk; + mv78xx0_uart3_data[0].uartclk = tclk; +} diff --git a/arch/arm/mach-mv78xx0/common.h b/arch/arm/mach-mv78xx0/common.h new file mode 100644 index 00000000000..78af5de319d --- /dev/null +++ b/arch/arm/mach-mv78xx0/common.h @@ -0,0 +1,49 @@ +/* + * arch/arm/mach-mv78xx0/common.h + * + * Core functions for Marvell MV78xx0 SoCs + * + * 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 __ARCH_MV78XX0_COMMON_H +#define __ARCH_MV78XX0_COMMON_H + +struct mv643xx_eth_platform_data; +struct mv_sata_platform_data; + +/* + * Basic MV78xx0 init functions used early by machine-setup. + */ +int mv78xx0_core_index(void); +void mv78xx0_map_io(void); +void mv78xx0_init(void); +void mv78xx0_init_irq(void); + +extern struct mbus_dram_target_info mv78xx0_mbus_dram_info; +void mv78xx0_setup_cpu_mbus(void); +void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, + int maj, int min); +void mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, + int maj, int min); + +void mv78xx0_ehci0_init(void); +void mv78xx0_ehci1_init(void); +void mv78xx0_ehci2_init(void); +void mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data); +void mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data); +void mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data); +void mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data); +void mv78xx0_pcie_init(int init_port0, int init_port1); +void mv78xx0_sata_init(struct mv_sata_platform_data *sata_data); +void mv78xx0_uart0_init(void); +void mv78xx0_uart1_init(void); +void mv78xx0_uart2_init(void); +void mv78xx0_uart3_init(void); + +extern struct sys_timer mv78xx0_timer; + + +#endif diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c new file mode 100644 index 00000000000..0c93d19193d --- /dev/null +++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c @@ -0,0 +1,94 @@ +/* + * arch/arm/mach-mv78xx0/db78x00-bp-setup.c + * + * Marvell DB-78x00-BP Development Board Setup + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +static struct mv643xx_eth_platform_data db78x00_ge00_data = { + .phy_addr = 8, +}; + +static struct mv643xx_eth_platform_data db78x00_ge01_data = { + .phy_addr = 9, +}; + +static struct mv643xx_eth_platform_data db78x00_ge10_data = { + .phy_addr = -1, +}; + +static struct mv643xx_eth_platform_data db78x00_ge11_data = { + .phy_addr = -1, +}; + +static struct mv_sata_platform_data db78x00_sata_data = { + .n_ports = 2, +}; + +static void __init db78x00_init(void) +{ + /* + * Basic MV78xx0 setup. Needs to be called early. + */ + mv78xx0_init(); + + /* + * Partition on-chip peripherals between the two CPU cores. + */ + if (mv78xx0_core_index() == 0) { + mv78xx0_ehci0_init(); + mv78xx0_ehci1_init(); + mv78xx0_ehci2_init(); + mv78xx0_ge00_init(&db78x00_ge00_data); + mv78xx0_ge01_init(&db78x00_ge01_data); + mv78xx0_ge10_init(&db78x00_ge10_data); + mv78xx0_ge11_init(&db78x00_ge11_data); + mv78xx0_sata_init(&db78x00_sata_data); + mv78xx0_uart0_init(); + mv78xx0_uart2_init(); + } else { + mv78xx0_uart1_init(); + mv78xx0_uart3_init(); + } +} + +static int __init db78x00_pci_init(void) +{ + if (machine_is_db78x00_bp()) { + /* + * Assign the x16 PCIe slot on the board to CPU core + * #0, and let CPU core #1 have the four x1 slots. + */ + if (mv78xx0_core_index() == 0) + mv78xx0_pcie_init(0, 1); + else + mv78xx0_pcie_init(1, 0); + } + + return 0; +} +subsys_initcall(db78x00_pci_init); + +MACHINE_START(DB78X00_BP, "Marvell DB-78x00-BP Development Board") + /* Maintainer: Lennert Buytenhek */ + .phys_io = MV78XX0_REGS_PHYS_BASE, + .io_pg_offst = ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = db78x00_init, + .map_io = mv78xx0_map_io, + .init_irq = mv78xx0_init_irq, + .timer = &mv78xx0_timer, +MACHINE_END diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c new file mode 100644 index 00000000000..60f4ee4d453 --- /dev/null +++ b/arch/arm/mach-mv78xx0/irq.c @@ -0,0 +1,22 @@ +/* + * arch/arm/mach-mv78xx0/irq.c + * + * MV78xx0 IRQ handling. + * + * 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 +#include +#include +#include +#include +#include "common.h" + +void __init mv78xx0_init_irq(void) +{ + orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); + orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); +} diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c new file mode 100644 index 00000000000..b78e1443159 --- /dev/null +++ b/arch/arm/mach-mv78xx0/pcie.c @@ -0,0 +1,312 @@ +/* + * arch/arm/mach-mv78xx0/pcie.c + * + * PCIe functions for Marvell MV78xx0 SoCs + * + * 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 +#include +#include +#include +#include +#include "common.h" + +struct pcie_port { + u8 maj; + u8 min; + u8 root_bus_nr; + void __iomem *base; + spinlock_t conf_lock; + char io_space_name[16]; + char mem_space_name[16]; + struct resource res[2]; +}; + +static struct pcie_port pcie_port[8]; +static int num_pcie_ports; +static struct resource pcie_io_space; +static struct resource pcie_mem_space; + + +static void __init mv78xx0_pcie_preinit(void) +{ + int i; + u32 size_each; + u32 start; + int win; + + pcie_io_space.name = "PCIe I/O Space"; + pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0); + pcie_io_space.end = + MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1; + pcie_io_space.flags = IORESOURCE_IO; + if (request_resource(&iomem_resource, &pcie_io_space)) + panic("can't allocate PCIe I/O space"); + + pcie_mem_space.name = "PCIe MEM Space"; + pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE; + pcie_mem_space.end = + MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1; + pcie_mem_space.flags = IORESOURCE_MEM; + if (request_resource(&iomem_resource, &pcie_mem_space)) + panic("can't allocate PCIe MEM space"); + + for (i = 0; i < num_pcie_ports; i++) { + struct pcie_port *pp = pcie_port + i; + + snprintf(pp->io_space_name, sizeof(pp->io_space_name), + "PCIe %d.%d I/O", pp->maj, pp->min); + pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0; + pp->res[0].name = pp->io_space_name; + pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i); + pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1; + pp->res[0].flags = IORESOURCE_IO; + + snprintf(pp->mem_space_name, sizeof(pp->mem_space_name), + "PCIe %d.%d MEM", pp->maj, pp->min); + pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0; + pp->res[1].name = pp->mem_space_name; + pp->res[1].flags = IORESOURCE_MEM; + } + + switch (num_pcie_ports) { + case 0: + size_each = 0; + break; + + case 1: + size_each = 0x30000000; + break; + + case 2 ... 3: + size_each = 0x10000000; + break; + + case 4 ... 6: + size_each = 0x08000000; + break; + + case 7: + size_each = 0x04000000; + break; + + default: + panic("invalid number of PCIe ports"); + } + + start = MV78XX0_PCIE_MEM_PHYS_BASE; + for (i = 0; i < num_pcie_ports; i++) { + struct pcie_port *pp = pcie_port + i; + + pp->res[1].start = start; + pp->res[1].end = start + size_each - 1; + start += size_each; + } + + for (i = 0; i < num_pcie_ports; i++) { + struct pcie_port *pp = pcie_port + i; + + if (request_resource(&pcie_io_space, &pp->res[0])) + panic("can't allocate PCIe I/O sub-space"); + + if (request_resource(&pcie_mem_space, &pp->res[1])) + panic("can't allocate PCIe MEM sub-space"); + } + + win = 0; + for (i = 0; i < num_pcie_ports; i++) { + struct pcie_port *pp = pcie_port + i; + + mv78xx0_setup_pcie_io_win(win++, pp->res[0].start, + pp->res[0].end - pp->res[0].start + 1, + pp->maj, pp->min); + + mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start, + pp->res[1].end - pp->res[1].start + 1, + pp->maj, pp->min); + } +} + +static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) +{ + struct pcie_port *pp; + + if (nr >= num_pcie_ports) + return 0; + + pp = &pcie_port[nr]; + pp->root_bus_nr = sys->busnr; + + /* + * Generic PCIe unit setup. + */ + orion_pcie_set_local_bus_nr(pp->base, sys->busnr); + orion_pcie_setup(pp->base, &mv78xx0_mbus_dram_info); + + sys->resource[0] = &pp->res[0]; + sys->resource[1] = &pp->res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static struct pcie_port *bus_to_port(int bus) +{ + int i; + + for (i = num_pcie_ports - 1; i >= 0; i--) { + int rbus = pcie_port[i].root_bus_nr; + if (rbus != -1 && rbus <= bus) + break; + } + + return i >= 0 ? pcie_port + i : NULL; +} + +static int pcie_valid_config(struct pcie_port *pp, int bus, int dev) +{ + /* + * Don't go out when trying to access nonexisting devices + * on the local bus. + */ + if (bus == pp->root_bus_nr && dev > 1) + return 0; + + return 1; +} + +static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, + int size, u32 *val) +{ + struct pcie_port *pp = bus_to_port(bus->number); + unsigned long flags; + int ret; + + if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) { + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + spin_lock_irqsave(&pp->conf_lock, flags); + ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val); + spin_unlock_irqrestore(&pp->conf_lock, flags); + + return ret; +} + +static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 val) +{ + struct pcie_port *pp = bus_to_port(bus->number); + unsigned long flags; + int ret; + + if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + spin_lock_irqsave(&pp->conf_lock, flags); + ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val); + spin_unlock_irqrestore(&pp->conf_lock, flags); + + return ret; +} + +static struct pci_ops pcie_ops = { + .read = pcie_rd_conf, + .write = pcie_wr_conf, +}; + +static void __devinit rc_pci_fixup(struct pci_dev *dev) +{ + /* + * Prevent enumeration of root complex. + */ + if (dev->bus->parent == NULL && dev->devfn == 0) { + int i; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); + +static struct pci_bus __init * +mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys) +{ + struct pci_bus *bus; + + if (nr < num_pcie_ports) { + bus = pci_scan_bus(sys->busnr, &pcie_ops, sys); + } else { + bus = NULL; + BUG(); + } + + return bus; +} + +static int __init mv78xx0_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + struct pcie_port *pp = bus_to_port(dev->bus->number); + + return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min; +} + +static struct hw_pci mv78xx0_pci __initdata = { + .nr_controllers = 8, + .preinit = mv78xx0_pcie_preinit, + .swizzle = pci_std_swizzle, + .setup = mv78xx0_pcie_setup, + .scan = mv78xx0_pcie_scan_bus, + .map_irq = mv78xx0_pcie_map_irq, +}; + +static void __init add_pcie_port(int maj, int min, unsigned long base) +{ + printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min); + + if (orion_pcie_link_up((void __iomem *)base)) { + struct pcie_port *pp = &pcie_port[num_pcie_ports++]; + + printk("link up\n"); + + pp->maj = maj; + pp->min = min; + pp->root_bus_nr = -1; + pp->base = (void __iomem *)base; + spin_lock_init(&pp->conf_lock); + memset(pp->res, 0, sizeof(pp->res)); + } else { + printk("link down, ignoring\n"); + } +} + +void __init mv78xx0_pcie_init(int init_port0, int init_port1) +{ + if (init_port0) { + add_pcie_port(0, 0, PCIE00_VIRT_BASE); + if (!orion_pcie_x4_mode((void __iomem *)PCIE00_VIRT_BASE)) { + add_pcie_port(0, 1, PCIE01_VIRT_BASE); + add_pcie_port(0, 2, PCIE02_VIRT_BASE); + add_pcie_port(0, 3, PCIE03_VIRT_BASE); + } + } + + if (init_port1) { + add_pcie_port(1, 0, PCIE10_VIRT_BASE); + if (!orion_pcie_x4_mode((void __iomem *)PCIE10_VIRT_BASE)) { + add_pcie_port(1, 1, PCIE11_VIRT_BASE); + add_pcie_port(1, 2, PCIE12_VIRT_BASE); + add_pcie_port(1, 3, PCIE13_VIRT_BASE); + } + } + + pci_common_init(&mv78xx0_pci); +} diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index a7a6efec897..236603bbafd 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -365,7 +365,7 @@ config CPU_XSC3 # Feroceon config CPU_FEROCEON bool - depends on ARCH_ORION5X || ARCH_LOKI || ARCH_KIRKWOOD + depends on ARCH_ORION5X || ARCH_LOKI || ARCH_KIRKWOOD || ARCH_MV78XX0 default y select CPU_32v5 select CPU_ABRT_EV5T @@ -716,7 +716,7 @@ config OUTER_CACHE config CACHE_FEROCEON_L2 bool "Enable the Feroceon L2 cache controller" - depends on ARCH_KIRKWOOD + depends on ARCH_KIRKWOOD || ARCH_MV78XX0 default y select OUTER_CACHE help diff --git a/include/asm-arm/arch-mv78xx0/debug-macro.S b/include/asm-arm/arch-mv78xx0/debug-macro.S new file mode 100644 index 00000000000..d0595bd645e --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/debug-macro.S @@ -0,0 +1,20 @@ +/* + * include/asm-arm/arch-mv78xx0/debug-macro.S + * + * 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 + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =MV78XX0_REGS_PHYS_BASE + ldrne \rx, =MV78XX0_REGS_VIRT_BASE + orr \rx, \rx, #0x00012000 + .endm + +#define UART_SHIFT 2 +#include diff --git a/include/asm-arm/arch-mv78xx0/dma.h b/include/asm-arm/arch-mv78xx0/dma.h new file mode 100644 index 00000000000..40a8c178f10 --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/dma.h @@ -0,0 +1 @@ +/* empty */ diff --git a/include/asm-arm/arch-mv78xx0/entry-macro.S b/include/asm-arm/arch-mv78xx0/entry-macro.S new file mode 100644 index 00000000000..e9a606b1266 --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/entry-macro.S @@ -0,0 +1,39 @@ +/* + * include/asm-arm/arch-mv78xx0/entry-macro.S + * + * Low-level IRQ helper macros for Marvell MV78xx0 platforms + * + * 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 + + .macro disable_fiq + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =IRQ_VIRT_BASE + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + @ check low interrupts + ldr \irqstat, [\base, #IRQ_CAUSE_LOW_OFF] + ldr \tmp, [\base, #IRQ_MASK_LOW_OFF] + mov \irqnr, #31 + ands \irqstat, \irqstat, \tmp + + @ if no low interrupts set, check high interrupts + ldreq \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF] + ldreq \tmp, [\base, #IRQ_MASK_HIGH_OFF] + moveq \irqnr, #63 + andeqs \irqstat, \irqstat, \tmp + + @ find first active interrupt source + clzne \irqstat, \irqstat + subne \irqnr, \irqnr, \irqstat + .endm diff --git a/include/asm-arm/arch-mv78xx0/hardware.h b/include/asm-arm/arch-mv78xx0/hardware.h new file mode 100644 index 00000000000..8e17926086c --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/hardware.h @@ -0,0 +1,21 @@ +/* + * include/asm-arm/arch-mv78xx0/hardware.h + * + * 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_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include "mv78xx0.h" + +#define pcibios_assign_all_busses() 1 + +#define PCIBIOS_MIN_IO 0x00001000 +#define PCIBIOS_MIN_MEM 0x01000000 +#define PCIMEM_BASE MV78XX0_PCIE_MEM_PHYS_BASE /* mem base for VGA */ + + +#endif diff --git a/include/asm-arm/arch-mv78xx0/io.h b/include/asm-arm/arch-mv78xx0/io.h new file mode 100644 index 00000000000..415d4c98e3d --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/io.h @@ -0,0 +1,26 @@ +/* + * include/asm-arm/arch-mv78xx0/io.h + * + * 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_IO_H +#define __ASM_ARCH_IO_H + +#include "mv78xx0.h" + +#define IO_SPACE_LIMIT 0xffffffff + +static inline void __iomem *__io(unsigned long addr) +{ + return (void __iomem *)((addr - MV78XX0_PCIE_IO_PHYS_BASE(0)) + + MV78XX0_PCIE_IO_VIRT_BASE(0)); +} + +#define __io(a) __io(a) +#define __mem_pci(a) (a) + + +#endif diff --git a/include/asm-arm/arch-mv78xx0/irqs.h b/include/asm-arm/arch-mv78xx0/irqs.h new file mode 100644 index 00000000000..75930450cd6 --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/irqs.h @@ -0,0 +1,91 @@ +/* + * include/asm-arm/arch-mv78xx0/irqs.h + * + * IRQ definitions for Marvell MV78xx0 SoCs + * + * 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_IRQS_H +#define __ASM_ARCH_IRQS_H + +#include "mv78xx0.h" /* need GPIO_MAX */ + +/* + * MV78xx0 Low Interrupt Controller + */ +#define IRQ_MV78XX0_ERR 0 +#define IRQ_MV78XX0_SPI 1 +#define IRQ_MV78XX0_I2C_0 2 +#define IRQ_MV78XX0_I2C_1 3 +#define IRQ_MV78XX0_IDMA_0 4 +#define IRQ_MV78XX0_IDMA_1 5 +#define IRQ_MV78XX0_IDMA_2 6 +#define IRQ_MV78XX0_IDMA_3 7 +#define IRQ_MV78XX0_TIMER_0 8 +#define IRQ_MV78XX0_TIMER_1 9 +#define IRQ_MV78XX0_TIMER_2 10 +#define IRQ_MV78XX0_TIMER_3 11 +#define IRQ_MV78XX0_UART_0 12 +#define IRQ_MV78XX0_UART_1 13 +#define IRQ_MV78XX0_UART_2 14 +#define IRQ_MV78XX0_UART_3 15 +#define IRQ_MV78XX0_USB_0 16 +#define IRQ_MV78XX0_USB_1 17 +#define IRQ_MV78XX0_USB_2 18 +#define IRQ_MV78XX0_CRYPTO 19 +#define IRQ_MV78XX0_SDIO_0 20 +#define IRQ_MV78XX0_SDIO_1 21 +#define IRQ_MV78XX0_XOR_0 22 +#define IRQ_MV78XX0_XOR_1 23 +#define IRQ_MV78XX0_I2S_0 24 +#define IRQ_MV78XX0_I2S_1 25 +#define IRQ_MV78XX0_SATA 26 +#define IRQ_MV78XX0_TDMI 27 + +/* + * MV78xx0 High Interrupt Controller + */ +#define IRQ_MV78XX0_PCIE_00 32 +#define IRQ_MV78XX0_PCIE_01 33 +#define IRQ_MV78XX0_PCIE_02 34 +#define IRQ_MV78XX0_PCIE_03 35 +#define IRQ_MV78XX0_PCIE_10 36 +#define IRQ_MV78XX0_PCIE_11 37 +#define IRQ_MV78XX0_PCIE_12 38 +#define IRQ_MV78XX0_PCIE_13 39 +#define IRQ_MV78XX0_GE00_SUM 40 +#define IRQ_MV78XX0_GE00_RX 41 +#define IRQ_MV78XX0_GE00_TX 42 +#define IRQ_MV78XX0_GE00_MISC 43 +#define IRQ_MV78XX0_GE01_SUM 44 +#define IRQ_MV78XX0_GE01_RX 45 +#define IRQ_MV78XX0_GE01_TX 46 +#define IRQ_MV78XX0_GE01_MISC 47 +#define IRQ_MV78XX0_GE10_SUM 48 +#define IRQ_MV78XX0_GE10_RX 49 +#define IRQ_MV78XX0_GE10_TX 50 +#define IRQ_MV78XX0_GE10_MISC 51 +#define IRQ_MV78XX0_GE11_SUM 52 +#define IRQ_MV78XX0_GE11_RX 53 +#define IRQ_MV78XX0_GE11_TX 54 +#define IRQ_MV78XX0_GE11_MISC 55 +#define IRQ_MV78XX0_GPIO_0_7 56 +#define IRQ_MV78XX0_GPIO_8_15 57 +#define IRQ_MV78XX0_GPIO_16_23 58 +#define IRQ_MV78XX0_GPIO_24_31 59 +#define IRQ_MV78XX0_DB_IN 60 +#define IRQ_MV78XX0_DB_OUT 61 + +/* + * MV78XX0 General Purpose Pins + */ +#define IRQ_MV78XX0_GPIO_START 64 +#define NR_GPIO_IRQS GPIO_MAX + +#define NR_IRQS (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS) + + +#endif diff --git a/include/asm-arm/arch-mv78xx0/memory.h b/include/asm-arm/arch-mv78xx0/memory.h new file mode 100644 index 00000000000..721a6b185b9 --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/memory.h @@ -0,0 +1,14 @@ +/* + * include/asm-arm/arch-mv78xx0/memory.h + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#define PHYS_OFFSET UL(0x00000000) + +#define __virt_to_bus(x) __virt_to_phys(x) +#define __bus_to_virt(x) __phys_to_virt(x) + + +#endif diff --git a/include/asm-arm/arch-mv78xx0/mv78xx0.h b/include/asm-arm/arch-mv78xx0/mv78xx0.h new file mode 100644 index 00000000000..9f5d83c73fa --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/mv78xx0.h @@ -0,0 +1,126 @@ +/* + * include/asm-arm/arch-mv78xx0/mv78xx0.h + * + * Generic definitions for Marvell MV78xx0 SoC flavors: + * MV781x0 and MV782x0. + * + * 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_MV78XX0_H +#define __ASM_ARCH_MV78XX0_H + +/* + * Marvell MV78xx0 address maps. + * + * phys + * c0000000 PCIe Memory space + * f0800000 PCIe #0 I/O space + * f0900000 PCIe #1 I/O space + * f0a00000 PCIe #2 I/O space + * f0b00000 PCIe #3 I/O space + * f0c00000 PCIe #4 I/O space + * f0d00000 PCIe #5 I/O space + * f0e00000 PCIe #6 I/O space + * f0f00000 PCIe #7 I/O space + * f1000000 on-chip peripheral registers + * + * virt phys size + * fe400000 f102x000 16K core-specific peripheral registers + * fe700000 f0800000 1M PCIe #0 I/O space + * fe800000 f0900000 1M PCIe #1 I/O space + * fe900000 f0a00000 1M PCIe #2 I/O space + * fea00000 f0b00000 1M PCIe #3 I/O space + * feb00000 f0c00000 1M PCIe #4 I/O space + * fec00000 f0d00000 1M PCIe #5 I/O space + * fed00000 f0e00000 1M PCIe #6 I/O space + * fee00000 f0f00000 1M PCIe #7 I/O space + * fef00000 f1000000 1M on-chip peripheral registers + */ +#define MV78XX0_CORE0_REGS_PHYS_BASE 0xf1020000 +#define MV78XX0_CORE1_REGS_PHYS_BASE 0xf1024000 +#define MV78XX0_CORE_REGS_VIRT_BASE 0xfe400000 +#define MV78XX0_CORE_REGS_SIZE SZ_16K + +#define MV78XX0_PCIE_IO_PHYS_BASE(i) (0xf0800000 + ((i) << 20)) +#define MV78XX0_PCIE_IO_VIRT_BASE(i) (0xfe700000 + ((i) << 20)) +#define MV78XX0_PCIE_IO_SIZE SZ_1M + +#define MV78XX0_REGS_PHYS_BASE 0xf1000000 +#define MV78XX0_REGS_VIRT_BASE 0xfef00000 +#define MV78XX0_REGS_SIZE SZ_1M + +#define MV78XX0_PCIE_MEM_PHYS_BASE 0xc0000000 +#define MV78XX0_PCIE_MEM_SIZE 0x30000000 + +/* + * Core-specific peripheral registers. + */ +#define BRIDGE_VIRT_BASE (MV78XX0_CORE_REGS_VIRT_BASE) +#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104) +#define L2_WRITETHROUGH 0x00020000 +#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108) +#define SOFT_RESET_OUT_EN 0x00000004 +#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c) +#define SOFT_RESET 0x00000001 +#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE | 0x0110) +#define BRIDGE_MASK (BRIDGE_VIRT_BASE | 0x0114) +#define BRIDGE_INT_TIMER0 0x0002 +#define BRIDGE_INT_TIMER1 0x0004 +#define BRIDGE_INT_TIMER1_CLR (~0x0004) +#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200) +#define IRQ_CAUSE_LOW_OFF 0x0004 +#define IRQ_CAUSE_HIGH_OFF 0x0008 +#define IRQ_MASK_LOW_OFF 0x0010 +#define IRQ_MASK_HIGH_OFF 0x0014 +#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) + +/* + * Register Map + */ +#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x00000) +#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE | 0x1500) +#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE | 0x1700) + +#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x10000) +#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x10000) +#define SAMPLE_AT_RESET_LOW (DEV_BUS_VIRT_BASE | 0x0030) +#define SAMPLE_AT_RESET_HIGH (DEV_BUS_VIRT_BASE | 0x0034) +#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000) +#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000) +#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100) +#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100) +#define UART2_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2200) +#define UART2_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2200) +#define UART3_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2300) +#define UART3_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2300) + +#define GE10_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x30000) +#define GE11_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x34000) + +#define PCIE00_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x40000) +#define PCIE01_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x44000) +#define PCIE02_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x48000) +#define PCIE03_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x4c000) + +#define USB0_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x50000) +#define USB1_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x51000) +#define USB2_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x52000) + +#define GE00_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x70000) +#define GE01_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x74000) + +#define PCIE10_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x80000) +#define PCIE11_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x84000) +#define PCIE12_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x88000) +#define PCIE13_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x8c000) + +#define SATA_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0xa0000) + + +#define GPIO_MAX 32 + + +#endif diff --git a/include/asm-arm/arch-mv78xx0/system.h b/include/asm-arm/arch-mv78xx0/system.h new file mode 100644 index 00000000000..7eb47d376db --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/system.h @@ -0,0 +1,37 @@ +/* + * include/asm-arm/arch-mv78xx0/system.h + * + * 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_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#include +#include + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode) +{ + /* + * Enable soft reset to assert RSTOUTn. + */ + writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK); + + /* + * Assert soft reset. + */ + writel(SOFT_RESET, SYSTEM_SOFT_RESET); + + while (1) + ; +} + + +#endif diff --git a/include/asm-arm/arch-mv78xx0/timex.h b/include/asm-arm/arch-mv78xx0/timex.h new file mode 100644 index 00000000000..a854b1ccbd0 --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/timex.h @@ -0,0 +1,9 @@ +/* + * include/asm-arm/arch-mv78xx0/timex.h + * + * 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. + */ + +#define CLOCK_TICK_RATE (100 * HZ) diff --git a/include/asm-arm/arch-mv78xx0/uncompress.h b/include/asm-arm/arch-mv78xx0/uncompress.h new file mode 100644 index 00000000000..3bfe0a293ef --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/uncompress.h @@ -0,0 +1,47 @@ +/* + * include/asm-arm/arch-mv78xx0/uncompress.h + * + * 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 +#include + +#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE) + +static void putc(const char c) +{ + unsigned char *base = SERIAL_BASE; + int i; + + for (i = 0; i < 0x1000; i++) { + if (base[UART_LSR << 2] & UART_LSR_THRE) + break; + barrier(); + } + + base[UART_TX << 2] = c; +} + +static void flush(void) +{ + unsigned char *base = SERIAL_BASE; + unsigned char mask; + int i; + + mask = UART_LSR_TEMT | UART_LSR_THRE; + + for (i = 0; i < 0x1000; i++) { + if ((base[UART_LSR << 2] & mask) == mask) + break; + barrier(); + } +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-mv78xx0/vmalloc.h b/include/asm-arm/arch-mv78xx0/vmalloc.h new file mode 100644 index 00000000000..f2c51219757 --- /dev/null +++ b/include/asm-arm/arch-mv78xx0/vmalloc.h @@ -0,0 +1,5 @@ +/* + * include/asm-arm/arch-mv78xx0/vmalloc.h + */ + +#define VMALLOC_END 0xfe000000 -- cgit v1.2.3-70-g09d2 From 395a59d0f8e86bb39cd700c3d185d30c670bb958 Mon Sep 17 00:00:00 2001 From: Abhishek Sagar Date: Sat, 21 Jun 2008 23:47:27 +0530 Subject: ftrace: store mcount address in rec->ip Record the address of the mcount call-site. Currently all archs except sparc64 record the address of the instruction following the mcount call-site. Some general cleanups are entailed. Storing mcount addresses in rec->ip enables looking them up in the kprobe hash table later on to check if they're kprobe'd. Signed-off-by: Abhishek Sagar Cc: davem@davemloft.net Cc: Steven Rostedt Signed-off-by: Ingo Molnar --- arch/arm/kernel/armksyms.c | 10 +++++----- arch/arm/kernel/entry-common.S | 4 ++++ arch/arm/kernel/ftrace.c | 16 +++++++--------- arch/powerpc/kernel/entry_32.S | 4 ++++ arch/powerpc/kernel/entry_64.S | 5 ++++- arch/powerpc/kernel/ftrace.c | 21 +++++++-------------- arch/sparc64/kernel/ftrace.c | 10 ++++++---- arch/sparc64/kernel/sparc64_ksyms.c | 2 +- arch/x86/kernel/entry_32.S | 4 ++++ arch/x86/kernel/entry_64.S | 4 ++++ arch/x86/kernel/ftrace.c | 26 +++++++++----------------- arch/x86/kernel/i386_ksyms_32.c | 2 +- arch/x86/kernel/x8664_ksyms_64.c | 2 +- include/asm-arm/ftrace.h | 14 ++++++++++++++ include/asm-powerpc/ftrace.h | 8 ++++++++ include/asm-sparc64/ftrace.h | 14 ++++++++++++++ include/asm-x86/ftrace.h | 14 ++++++++++++++ include/linux/ftrace.h | 3 +-- kernel/trace/ftrace.c | 3 ++- 19 files changed, 110 insertions(+), 56 deletions(-) create mode 100644 include/asm-arm/ftrace.h create mode 100644 include/asm-sparc64/ftrace.h create mode 100644 include/asm-x86/ftrace.h (limited to 'include/asm-arm') diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 3b132215cbf..cc7b246e965 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -18,6 +18,7 @@ #include #include #include +#include /* * libgcc functions - functions that are used internally by the @@ -48,11 +49,6 @@ extern void __aeabi_ulcmp(void); extern void fpundefinstr(void); extern void fp_enter(void); -#ifdef CONFIG_FTRACE -extern void mcount(void); -EXPORT_SYMBOL(mcount); -#endif - /* * This has a special calling convention; it doesn't * modify any of the usual registers, except for LR. @@ -186,3 +182,7 @@ EXPORT_SYMBOL(_find_next_bit_be); #endif EXPORT_SYMBOL(copy_page); + +#ifdef CONFIG_FTRACE +EXPORT_SYMBOL(mcount); +#endif diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 8f79a4789ed..84694e88b42 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -9,6 +9,7 @@ */ #include +#include #include #include "entry-header.S" @@ -104,6 +105,7 @@ ENTRY(ret_from_fork) ENTRY(mcount) stmdb sp!, {r0-r3, lr} mov r0, lr + sub r0, r0, #MCOUNT_INSN_SIZE .globl mcount_call mcount_call: @@ -114,6 +116,7 @@ ENTRY(ftrace_caller) stmdb sp!, {r0-r3, lr} ldr r1, [fp, #-4] mov r0, lr + sub r0, r0, #MCOUNT_INSN_SIZE .globl ftrace_call ftrace_call: @@ -134,6 +137,7 @@ ENTRY(mcount) trace: ldr r1, [fp, #-4] mov r0, lr + sub r0, r0, #MCOUNT_INSN_SIZE mov lr, pc mov pc, r2 ldmia sp!, {r0-r3, pc} diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 22f3d6e309f..76d50e6091b 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c @@ -12,9 +12,10 @@ */ #include + #include +#include -#define INSN_SIZE 4 #define PC_OFFSET 8 #define BL_OPCODE 0xeb000000 #define BL_OFFSET_MASK 0x00ffffff @@ -32,10 +33,10 @@ unsigned char *ftrace_call_replace(unsigned long pc, unsigned long addr) { long offset; - offset = (long)addr - (long)(pc - INSN_SIZE + PC_OFFSET); + offset = (long)addr - (long)(pc + PC_OFFSET); if (unlikely(offset < -33554432 || offset > 33554428)) { /* Can't generate branches that far (from ARM ARM). Ftrace - * doesn't generate branches outside of core kernel text. + * doesn't generate branches outside of kernel text. */ WARN_ON_ONCE(1); return NULL; @@ -52,7 +53,6 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code, old = *(unsigned long *)old_code; new = *(unsigned long *)new_code; - pc -= INSN_SIZE; __asm__ __volatile__ ( "1: ldr %1, [%2] \n" @@ -77,7 +77,7 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code, : "memory"); if (!err && (replaced == old)) - flush_icache_range(pc, pc + INSN_SIZE); + flush_icache_range(pc, pc + MCOUNT_INSN_SIZE); return err; } @@ -89,8 +89,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func) unsigned char *new; pc = (unsigned long)&ftrace_call; - pc += INSN_SIZE; - memcpy(&old, &ftrace_call, INSN_SIZE); + memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(pc, (unsigned long)func); ret = ftrace_modify_code(pc, (unsigned char *)&old, new); return ret; @@ -103,8 +102,7 @@ int ftrace_mcount_set(unsigned long *data) unsigned char *new; pc = (unsigned long)&mcount_call; - pc += INSN_SIZE; - memcpy(&old, &mcount_call, INSN_SIZE); + memcpy(&old, &mcount_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(pc, *addr); *addr = ftrace_modify_code(pc, (unsigned char *)&old, new); return 0; diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 3b1dd29d9f9..7231a708af0 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -30,6 +30,7 @@ #include #include #include +#include #undef SHOW_SYSCALLS #undef SHOW_SYSCALLS_TASK @@ -1053,6 +1054,7 @@ _GLOBAL(_mcount) stw r10,40(r1) stw r3, 44(r1) stw r5, 8(r1) + subi r3, r3, MCOUNT_INSN_SIZE .globl mcount_call mcount_call: bl ftrace_stub @@ -1090,6 +1092,7 @@ _GLOBAL(ftrace_caller) stw r10,40(r1) stw r3, 44(r1) stw r5, 8(r1) + subi r3, r3, MCOUNT_INSN_SIZE .globl ftrace_call ftrace_call: bl ftrace_stub @@ -1128,6 +1131,7 @@ _GLOBAL(_mcount) stw r3, 44(r1) stw r5, 8(r1) + subi r3, r3, MCOUNT_INSN_SIZE LOAD_REG_ADDR(r5, ftrace_trace_function) lwz r5,0(r5) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 2c4d9e056ea..2f511a969d2 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -31,6 +31,7 @@ #include #include #include +#include /* * System calls. @@ -879,6 +880,7 @@ _GLOBAL(_mcount) mflr r3 stdu r1, -112(r1) std r3, 128(r1) + subi r3, r3, MCOUNT_INSN_SIZE .globl mcount_call mcount_call: bl ftrace_stub @@ -895,6 +897,7 @@ _GLOBAL(ftrace_caller) stdu r1, -112(r1) std r3, 128(r1) ld r4, 16(r11) + subi r3, r3, MCOUNT_INSN_SIZE .globl ftrace_call ftrace_call: bl ftrace_stub @@ -916,7 +919,7 @@ _GLOBAL(_mcount) std r3, 128(r1) ld r4, 16(r11) - + subi r3, r3, MCOUNT_INSN_SIZE LOAD_REG_ADDR(r5,ftrace_trace_function) ld r5,0(r5) ld r5,0(r5) diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index e12c593ab9c..3855ceb937b 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -15,8 +15,8 @@ #include #include +#include -#define CALL_BACK 4 static unsigned int ftrace_nop = 0x60000000; @@ -27,9 +27,10 @@ static unsigned int ftrace_nop = 0x60000000; # define GET_ADDR(addr) *(unsigned long *)addr #endif + static unsigned int notrace ftrace_calc_offset(long ip, long addr) { - return (int)((addr + CALL_BACK) - ip); + return (int)(addr - ip); } notrace unsigned char *ftrace_nop_replace(void) @@ -76,9 +77,6 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned new = *(unsigned *)new_code; int faulted = 0; - /* move the IP back to the start of the call */ - ip -= CALL_BACK; - /* * Note: Due to modules and __init, code can * disappear and change, we need to protect against faulting @@ -118,12 +116,10 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, notrace int ftrace_update_ftrace_func(ftrace_func_t func) { unsigned long ip = (unsigned long)(&ftrace_call); - unsigned char old[4], *new; + unsigned char old[MCOUNT_INSN_SIZE], *new; int ret; - ip += CALL_BACK; - - memcpy(old, &ftrace_call, 4); + memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(ip, (unsigned long)func); ret = ftrace_modify_code(ip, old, new); @@ -134,16 +130,13 @@ notrace int ftrace_mcount_set(unsigned long *data) { unsigned long ip = (long)(&mcount_call); unsigned long *addr = data; - unsigned char old[4], *new; - - /* ip is at the location, but modify code will subtact this */ - ip += CALL_BACK; + unsigned char old[MCOUNT_INSN_SIZE], *new; /* * Replace the mcount stub with a pointer to the * ip recorder function. */ - memcpy(old, &mcount_call, 4); + memcpy(old, &mcount_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(ip, *addr); *addr = ftrace_modify_code(ip, old, new); diff --git a/arch/sparc64/kernel/ftrace.c b/arch/sparc64/kernel/ftrace.c index c17373195b1..4298d0aee71 100644 --- a/arch/sparc64/kernel/ftrace.c +++ b/arch/sparc64/kernel/ftrace.c @@ -5,6 +5,8 @@ #include #include +#include + static const u32 ftrace_nop = 0x01000000; notrace unsigned char *ftrace_nop_replace(void) @@ -60,9 +62,9 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, notrace int ftrace_update_ftrace_func(ftrace_func_t func) { unsigned long ip = (unsigned long)(&ftrace_call); - unsigned char old[4], *new; + unsigned char old[MCOUNT_INSN_SIZE], *new; - memcpy(old, &ftrace_call, 4); + memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(ip, (unsigned long)func); return ftrace_modify_code(ip, old, new); } @@ -71,13 +73,13 @@ notrace int ftrace_mcount_set(unsigned long *data) { unsigned long ip = (long)(&mcount_call); unsigned long *addr = data; - unsigned char old[4], *new; + unsigned char old[MCOUNT_INSN_SIZE], *new; /* * Replace the mcount stub with a pointer to the * ip recorder function. */ - memcpy(old, &mcount_call, 4); + memcpy(old, &mcount_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(ip, *addr); *addr = ftrace_modify_code(ip, old, new); diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 8ac0b99f2c5..b80d982a29c 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -53,6 +53,7 @@ #include #include #include +#include struct poll { int fd; @@ -112,7 +113,6 @@ EXPORT_SYMBOL(smp_call_function); #endif /* CONFIG_SMP */ #if defined(CONFIG_MCOUNT) -extern void _mcount(void); EXPORT_SYMBOL(_mcount); #endif diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 04ea83ccb97..95e6bbe3665 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -51,6 +51,7 @@ #include #include #include +#include #include "irq_vectors.h" /* @@ -1118,6 +1119,7 @@ ENTRY(mcount) pushl %ecx pushl %edx movl 0xc(%esp), %eax + subl $MCOUNT_INSN_SIZE, %eax .globl mcount_call mcount_call: @@ -1136,6 +1138,7 @@ ENTRY(ftrace_caller) pushl %edx movl 0xc(%esp), %eax movl 0x4(%ebp), %edx + subl $MCOUNT_INSN_SIZE, %eax .globl ftrace_call ftrace_call: @@ -1166,6 +1169,7 @@ trace: pushl %edx movl 0xc(%esp), %eax movl 0x4(%ebp), %edx + subl $MCOUNT_INSN_SIZE, %eax call *ftrace_trace_function diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index fe25e5febca..b0f7308f78a 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -51,6 +51,7 @@ #include #include #include +#include .code64 @@ -68,6 +69,7 @@ ENTRY(mcount) movq %r9, 48(%rsp) movq 0x38(%rsp), %rdi + subq $MCOUNT_INSN_SIZE, %rdi .globl mcount_call mcount_call: @@ -99,6 +101,7 @@ ENTRY(ftrace_caller) movq 0x38(%rsp), %rdi movq 8(%rbp), %rsi + subq $MCOUNT_INSN_SIZE, %rdi .globl ftrace_call ftrace_call: @@ -139,6 +142,7 @@ trace: movq 0x38(%rsp), %rdi movq 8(%rbp), %rsi + subq $MCOUNT_INSN_SIZE, %rdi call *ftrace_trace_function diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 55828149e01..ab115cd15fd 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -17,20 +17,21 @@ #include #include +#include -#define CALL_BACK 5 /* Long is fine, even if it is only 4 bytes ;-) */ static long *ftrace_nop; union ftrace_code_union { - char code[5]; + char code[MCOUNT_INSN_SIZE]; struct { char e8; int offset; } __attribute__((packed)); }; + static int notrace ftrace_calc_offset(long ip, long addr) { return (int)(addr - ip); @@ -46,7 +47,7 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) static union ftrace_code_union calc; calc.e8 = 0xe8; - calc.offset = ftrace_calc_offset(ip, addr); + calc.offset = ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr); /* * No locking needed, this must be called via kstop_machine @@ -65,9 +66,6 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char newch = new_code[4]; int faulted = 0; - /* move the IP back to the start of the call */ - ip -= CALL_BACK; - /* * Note: Due to modules and __init, code can * disappear and change, we need to protect against faulting @@ -102,12 +100,10 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, notrace int ftrace_update_ftrace_func(ftrace_func_t func) { unsigned long ip = (unsigned long)(&ftrace_call); - unsigned char old[5], *new; + unsigned char old[MCOUNT_INSN_SIZE], *new; int ret; - ip += CALL_BACK; - - memcpy(old, &ftrace_call, 5); + memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(ip, (unsigned long)func); ret = ftrace_modify_code(ip, old, new); @@ -118,16 +114,13 @@ notrace int ftrace_mcount_set(unsigned long *data) { unsigned long ip = (long)(&mcount_call); unsigned long *addr = data; - unsigned char old[5], *new; - - /* ip is at the location, but modify code will subtact this */ - ip += CALL_BACK; + unsigned char old[MCOUNT_INSN_SIZE], *new; /* * Replace the mcount stub with a pointer to the * ip recorder function. */ - memcpy(old, &mcount_call, 5); + memcpy(old, &mcount_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(ip, *addr); *addr = ftrace_modify_code(ip, old, new); @@ -142,8 +135,7 @@ int __init ftrace_dyn_arch_init(void *data) ftrace_mcount_set(data); - ftrace_nop = (unsigned long *)noptable[CALL_BACK]; + ftrace_nop = (unsigned long *)noptable[MCOUNT_INSN_SIZE]; return 0; } - diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index 29999dbb754..dd7ebee446a 100644 --- a/arch/x86/kernel/i386_ksyms_32.c +++ b/arch/x86/kernel/i386_ksyms_32.c @@ -1,9 +1,9 @@ -#include #include #include #include #include +#include #ifdef CONFIG_FTRACE /* mcount is defined in assembly */ diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index 122885bc5f3..16ff4bf418d 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -1,7 +1,6 @@ /* Exports for assembly files. All C exports should go in the respective C files. */ -#include #include #include @@ -11,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_FTRACE /* mcount is defined in assembly */ diff --git a/include/asm-arm/ftrace.h b/include/asm-arm/ftrace.h new file mode 100644 index 00000000000..584ef9a8e5a --- /dev/null +++ b/include/asm-arm/ftrace.h @@ -0,0 +1,14 @@ +#ifndef _ASM_ARM_FTRACE +#define _ASM_ARM_FTRACE + +#ifdef CONFIG_FTRACE +#define MCOUNT_ADDR ((long)(mcount)) +#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ + +#ifndef __ASSEMBLY__ +extern void mcount(void); +#endif + +#endif + +#endif /* _ASM_ARM_FTRACE */ diff --git a/include/asm-powerpc/ftrace.h b/include/asm-powerpc/ftrace.h index b1bfa704b6e..de921326cca 100644 --- a/include/asm-powerpc/ftrace.h +++ b/include/asm-powerpc/ftrace.h @@ -1,6 +1,14 @@ #ifndef _ASM_POWERPC_FTRACE #define _ASM_POWERPC_FTRACE +#ifdef CONFIG_FTRACE +#define MCOUNT_ADDR ((long)(_mcount)) +#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ + +#ifndef __ASSEMBLY__ extern void _mcount(void); +#endif #endif + +#endif /* _ASM_POWERPC_FTRACE */ diff --git a/include/asm-sparc64/ftrace.h b/include/asm-sparc64/ftrace.h new file mode 100644 index 00000000000..f76a40a338b --- /dev/null +++ b/include/asm-sparc64/ftrace.h @@ -0,0 +1,14 @@ +#ifndef _ASM_SPARC64_FTRACE +#define _ASM_SPARC64_FTRACE + +#ifdef CONFIG_FTRACE +#define MCOUNT_ADDR ((long)(_mcount)) +#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ + +#ifndef __ASSEMBLY__ +extern void _mcount(void); +#endif + +#endif + +#endif /* _ASM_SPARC64_FTRACE */ diff --git a/include/asm-x86/ftrace.h b/include/asm-x86/ftrace.h new file mode 100644 index 00000000000..c184441133f --- /dev/null +++ b/include/asm-x86/ftrace.h @@ -0,0 +1,14 @@ +#ifndef _ASM_X86_FTRACE +#define _ASM_SPARC64_FTRACE + +#ifdef CONFIG_FTRACE +#define MCOUNT_ADDR ((long)(mcount)) +#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ + +#ifndef __ASSEMBLY__ +extern void mcount(void); +#endif + +#endif /* CONFIG_FTRACE */ + +#endif /* _ASM_X86_FTRACE */ diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 20e14d0093c..366098d591d 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -31,7 +31,6 @@ int unregister_ftrace_function(struct ftrace_ops *ops); void clear_ftrace_function(void); extern void ftrace_stub(unsigned long a0, unsigned long a1); -extern void mcount(void); #else /* !CONFIG_FTRACE */ # define register_ftrace_function(ops) do { } while (0) @@ -54,7 +53,7 @@ enum { struct dyn_ftrace { struct hlist_node node; - unsigned long ip; + unsigned long ip; /* address of mcount call-site */ unsigned long flags; }; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 0d5bcf69952..f1e9e5c74e6 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -27,6 +27,8 @@ #include #include +#include + #include "trace.h" /* ftrace_enabled is a method to turn ftrace on or off */ @@ -329,7 +331,6 @@ ftrace_record_ip(unsigned long ip) } #define FTRACE_ADDR ((long)(ftrace_caller)) -#define MCOUNT_ADDR ((long)(mcount)) static int __ftrace_replace_code(struct dyn_ftrace *rec, -- cgit v1.2.3-70-g09d2 From f6dd9fa5a75a3dae16c6843e74e56bf75be51c7c Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 10 Jun 2008 20:48:30 +0200 Subject: arm: convert to generic helpers for IPI function calls This converts arm to use the new helpers for smp_call_function() and friends, and adds support for smp_call_function_single(). Fixups and testing done by Catalin Marinas Cc: Russell King Signed-off-by: Jens Axboe --- arch/arm/Kconfig | 1 + arch/arm/kernel/smp.c | 157 +++++--------------------------------------------- include/asm-arm/smp.h | 3 + 3 files changed, 19 insertions(+), 142 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..c72dae633f6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -650,6 +650,7 @@ source "kernel/time/Kconfig" config SMP bool "Symmetric Multi-Processing (EXPERIMENTAL)" depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP) + select USE_GENERIC_SMP_HELPERS help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index eefae1de334..6344466b211 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -68,20 +68,10 @@ enum ipi_msg_type { IPI_TIMER, IPI_RESCHEDULE, IPI_CALL_FUNC, + IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, }; -struct smp_call_struct { - void (*func)(void *info); - void *info; - int wait; - cpumask_t pending; - cpumask_t unfinished; -}; - -static struct smp_call_struct * volatile smp_call_function_data; -static DEFINE_SPINLOCK(smp_call_function_lock); - int __cpuinit __cpu_up(unsigned int cpu) { struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); @@ -366,114 +356,15 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) local_irq_restore(flags); } -/* - * You must not call this function with disabled interrupts, from a - * hardware interrupt handler, nor from a bottom half handler. - */ -static int smp_call_function_on_cpu(void (*func)(void *info), void *info, - int retry, int wait, cpumask_t callmap) -{ - struct smp_call_struct data; - unsigned long timeout; - int ret = 0; - - data.func = func; - data.info = info; - data.wait = wait; - - cpu_clear(smp_processor_id(), callmap); - if (cpus_empty(callmap)) - goto out; - - data.pending = callmap; - if (wait) - data.unfinished = callmap; - - /* - * try to get the mutex on smp_call_function_data - */ - spin_lock(&smp_call_function_lock); - smp_call_function_data = &data; - - send_ipi_message(callmap, IPI_CALL_FUNC); - - timeout = jiffies + HZ; - while (!cpus_empty(data.pending) && time_before(jiffies, timeout)) - barrier(); - - /* - * did we time out? - */ - if (!cpus_empty(data.pending)) { - /* - * this may be causing our panic - report it - */ - printk(KERN_CRIT - "CPU%u: smp_call_function timeout for %p(%p)\n" - " callmap %lx pending %lx, %swait\n", - smp_processor_id(), func, info, *cpus_addr(callmap), - *cpus_addr(data.pending), wait ? "" : "no "); - - /* - * TRACE - */ - timeout = jiffies + (5 * HZ); - while (!cpus_empty(data.pending) && time_before(jiffies, timeout)) - barrier(); - - if (cpus_empty(data.pending)) - printk(KERN_CRIT " RESOLVED\n"); - else - printk(KERN_CRIT " STILL STUCK\n"); - } - - /* - * whatever happened, we're done with the data, so release it - */ - smp_call_function_data = NULL; - spin_unlock(&smp_call_function_lock); - - if (!cpus_empty(data.pending)) { - ret = -ETIMEDOUT; - goto out; - } - - if (wait) - while (!cpus_empty(data.unfinished)) - barrier(); - out: - - return 0; -} - -int smp_call_function(void (*func)(void *info), void *info, int retry, - int wait) +void arch_send_call_function_ipi(cpumask_t mask) { - return smp_call_function_on_cpu(func, info, retry, wait, - cpu_online_map); + send_ipi_message(mask, IPI_CALL_FUNC); } -EXPORT_SYMBOL_GPL(smp_call_function); -int smp_call_function_single(int cpu, void (*func)(void *info), void *info, - int retry, int wait) +void arch_send_call_function_single_ipi(int cpu) { - /* prevent preemption and reschedule on another processor */ - int current_cpu = get_cpu(); - int ret = 0; - - if (cpu == current_cpu) { - local_irq_disable(); - func(info); - local_irq_enable(); - } else - ret = smp_call_function_on_cpu(func, info, retry, wait, - cpumask_of_cpu(cpu)); - - put_cpu(); - - return ret; + send_ipi_message(cpumask_of_cpu(cpu), IPI_CALL_FUNC_SINGLE); } -EXPORT_SYMBOL_GPL(smp_call_function_single); void show_ipi_list(struct seq_file *p) { @@ -521,27 +412,6 @@ asmlinkage void __exception do_local_timer(struct pt_regs *regs) } #endif -/* - * ipi_call_function - handle IPI from smp_call_function() - * - * Note that we copy data out of the cross-call structure and then - * let the caller know that we're here and have done with their data - */ -static void ipi_call_function(unsigned int cpu) -{ - struct smp_call_struct *data = smp_call_function_data; - void (*func)(void *info) = data->func; - void *info = data->info; - int wait = data->wait; - - cpu_clear(cpu, data->pending); - - func(info); - - if (wait) - cpu_clear(cpu, data->unfinished); -} - static DEFINE_SPINLOCK(stop_lock); /* @@ -611,7 +481,11 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs) break; case IPI_CALL_FUNC: - ipi_call_function(cpu); + generic_smp_call_function_interrupt(); + break; + + case IPI_CALL_FUNC_SINGLE: + generic_smp_call_function_single_interrupt(); break; case IPI_CPU_STOP: @@ -662,14 +536,13 @@ int setup_profiling_timer(unsigned int multiplier) } static int -on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait, - cpumask_t mask) +on_each_cpu_mask(void (*func)(void *), void *info, int wait, cpumask_t mask) { int ret = 0; preempt_disable(); - ret = smp_call_function_on_cpu(func, info, retry, wait, mask); + ret = smp_call_function_mask(mask, func, info, wait); if (cpu_isset(smp_processor_id(), mask)) func(info); @@ -738,7 +611,7 @@ void flush_tlb_mm(struct mm_struct *mm) { cpumask_t mask = mm->cpu_vm_mask; - on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask); + on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mask); } void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) @@ -749,7 +622,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) ta.ta_vma = vma; ta.ta_start = uaddr; - on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask); + on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mask); } void flush_tlb_kernel_page(unsigned long kaddr) @@ -771,7 +644,7 @@ void flush_tlb_range(struct vm_area_struct *vma, ta.ta_start = start; ta.ta_end = end; - on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask); + on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mask); } void flush_tlb_kernel_range(unsigned long start, unsigned long end) diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h index af99636db40..7fffa2404b8 100644 --- a/include/asm-arm/smp.h +++ b/include/asm-arm/smp.h @@ -101,6 +101,9 @@ extern void platform_cpu_die(unsigned int cpu); extern int platform_cpu_kill(unsigned int cpu); extern void platform_cpu_enable(unsigned int cpu); +extern void arch_send_call_function_single_ipi(int cpu); +extern void arch_send_call_function_ipi(cpumask_t mask); + /* * Local timer interrupt handling function (can be IPI'ed). */ -- cgit v1.2.3-70-g09d2 From 1338760329c586e0141831099e15f5c336dd9c1d Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Mon, 23 Jun 2008 01:05:08 -1100 Subject: [ARM] Kirkwood: support L2 writeback mode This patch allows booting Kirkwood with the L2 in writeback mode, by reading the WT override bit from the L2 config register and passing that into the Feroceon L2 init routine, instead of assuming that the WT override bit will always be set Signed-off-by: Saeed Bishara Signed-off-by: Lennert Buytenhek --- arch/arm/mach-kirkwood/common.c | 7 ++++++- include/asm-arm/arch-kirkwood/kirkwood.h | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index e73384fbbba..5938a3b33cd 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -313,6 +313,11 @@ static char * __init kirkwood_id(void) return "unknown 88F6000 variant"; } +static int __init is_l2_writethrough(void) +{ + return !!(readl(L2_CONFIG_REG) & L2_WRITETHROUGH); +} + void __init kirkwood_init(void) { printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n", @@ -321,6 +326,6 @@ void __init kirkwood_init(void) kirkwood_setup_cpu_mbus(); #ifdef CONFIG_CACHE_FEROCEON_L2 - feroceon_l2_init(1); + feroceon_l2_init(is_l2_writethrough()); #endif } diff --git a/include/asm-arm/arch-kirkwood/kirkwood.h b/include/asm-arm/arch-kirkwood/kirkwood.h index 520250dbd8a..bb31b315c35 100644 --- a/include/asm-arm/arch-kirkwood/kirkwood.h +++ b/include/asm-arm/arch-kirkwood/kirkwood.h @@ -49,7 +49,6 @@ #define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000) #define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104) #define CPU_RESET 0x00000002 -//#define L2_WRITETHROUGH 0x00020000 #define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108) #define SOFT_RESET_OUT_EN 0x00000004 #define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c) @@ -65,6 +64,8 @@ #define IRQ_CAUSE_HIGH_OFF 0x0010 #define IRQ_MASK_HIGH_OFF 0x0014 #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) +#define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128) +#define L2_WRITETHROUGH 0x00000010 /* * Register Map -- cgit v1.2.3-70-g09d2 From f4db56ffd43a810424866fac6de9a32486415316 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Sun, 4 May 2008 19:25:52 -1100 Subject: [MTD] orion_nand: add chip_delay parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some SoCs need a different chip_delay value. Signed-off-by: Saeed Bishara Acked-by: Jörn Engel Signed-off-by: Lennert Buytenhek Signed-off-by: Nicolas Pitre --- drivers/mtd/nand/orion_nand.c | 3 +++ include/asm-arm/plat-orion/orion_nand.h | 1 + 2 files changed, 4 insertions(+) (limited to 'include/asm-arm') diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 59e05a1c50c..ee2ac3948cd 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -85,6 +85,9 @@ static int __init orion_nand_probe(struct platform_device *pdev) nc->cmd_ctrl = orion_nand_cmd_ctrl; nc->ecc.mode = NAND_ECC_SOFT; + if (board->chip_delay) + nc->chip_delay = board->chip_delay; + if (board->width == 16) nc->options |= NAND_BUSWIDTH_16; diff --git a/include/asm-arm/plat-orion/orion_nand.h b/include/asm-arm/plat-orion/orion_nand.h index ffd3852a0dd..ad4ce94c199 100644 --- a/include/asm-arm/plat-orion/orion_nand.h +++ b/include/asm-arm/plat-orion/orion_nand.h @@ -18,6 +18,7 @@ struct orion_nand_data { u8 ale; /* address line number connected to ALE */ u8 cle; /* address line number connected to CLE */ u8 width; /* buswidth */ + u8 chip_delay; }; -- cgit v1.2.3-70-g09d2 From 3fddd09e59cf49dc339e2de74d31a76c1f7f172f Mon Sep 17 00:00:00 2001 From: Richard Woodruff Date: Thu, 3 Jul 2008 12:24:30 +0300 Subject: ARM: OMAP: DMTimer: Optimize by adding load and start This patch optimizes the timer load and start sequence. By combining the load and start a needless posted wait can be removed from the system timer execution path. * Before patch register writes are taking up .078% @ 500MHz during idle. Address |total |min |max |avr |count|ratio% old\process\default_idle|7.369s |0.0us|999.902ms|14.477ms|509. |62.661% ld\Global\cpu_v7_do_idle|4.265s |0.0us|375.786ms|24.374ms|175. |36.270% (UNKNOWN)|17.503ms|0.us|531.080us|5.119us|3419. |0.148% r\omap_dm_timer_set_load|8.135ms|0.0us|79.887us|15.065us|540. |0.069% <-- \vmlinux-old\Global\_end|2.023ms|0.0us|4.000us|0.560us|3613. |0.017% -old\Global\__raw_readsw|1.962ms|0.0us|108.610us|9.167us|214. |0.016% old\smc91x\smc_interrupt|1.353ms|0.0us|10.212us|2.348us|576. |0.011% s/namei\__link_path_walk|1.161ms|0.0us|4.310us|0.762us| 1524. |0.009% \omap_dm_timer_write_reg|1.085ms|0.0us|126.150us|2.153us|504. |0.009% <-- * After patch timer functions do not show up in top listings for long captures. Signed-off-by: Richard Woodruff Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer-gp.c | 9 +++------ arch/arm/plat-omap/dmtimer.c | 19 ++++++++++++++++++- include/asm-arm/arch-omap/dmtimer.h | 1 + 3 files changed, 22 insertions(+), 7 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index 78d05f203ff..557603f9931 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c @@ -59,8 +59,7 @@ static struct irqaction omap2_gp_timer_irq = { static int omap2_gp_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { - omap_dm_timer_set_load(gptimer, 0, 0xffffffff - cycles); - omap_dm_timer_start(gptimer); + omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles); return 0; } @@ -77,8 +76,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; period -= 1; - omap_dm_timer_set_load(gptimer, 1, 0xffffffff - period); - omap_dm_timer_start(gptimer); + omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period); break; case CLOCK_EVT_MODE_ONESHOT: break; @@ -172,8 +170,7 @@ static void __init omap2_gp_clocksource_init(void) tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt)); tick_period = (tick_rate / HZ) - 1; - omap_dm_timer_set_load(gpt, 1, 0); - omap_dm_timer_start(gpt); + omap_dm_timer_set_load_start(gpt, 1, 0); clocksource_gpt.mult = clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 822b6bb5c74..f22506af0e6 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -546,6 +546,24 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); } +/* Optimized set_load which removes costly spin wait in timer_start */ +void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, + unsigned int load) +{ + u32 l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); + if (autoreload) + l |= OMAP_TIMER_CTRL_AR; + else + l &= ~OMAP_TIMER_CTRL_AR; + l |= OMAP_TIMER_CTRL_ST; + + omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load); + omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); +} + void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match) { @@ -560,7 +578,6 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); } - void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger) { diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h index fefb276ed40..02b29e8437a 100644 --- a/include/asm-arm/arch-omap/dmtimer.h +++ b/include/asm-arm/arch-omap/dmtimer.h @@ -66,6 +66,7 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer); void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source); void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value); +void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value); void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match); void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger); void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler); -- cgit v1.2.3-70-g09d2 From 4a79acdc784c315d9c436ba2315d08f8f53b8adf Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 3 Jul 2008 12:24:31 +0300 Subject: ARM: OMAP: Add OMAP3430 base defines Add symbolic constants for OMAP3430 base addresses; include that file in hardware.h. Signed-off-by: Paul Walmsley Signed-off-by: Tony Lindgren --- include/asm-arm/arch-omap/hardware.h | 1 + include/asm-arm/arch-omap/omap34xx.h | 72 ++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 include/asm-arm/arch-omap/omap34xx.h (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h index 91d85b3417b..45fdfccbd5d 100644 --- a/include/asm-arm/arch-omap/hardware.h +++ b/include/asm-arm/arch-omap/hardware.h @@ -284,6 +284,7 @@ #include "omap1510.h" #include "omap24xx.h" #include "omap16xx.h" +#include "omap34xx.h" #ifndef __ASSEMBLER__ diff --git a/include/asm-arm/arch-omap/omap34xx.h b/include/asm-arm/arch-omap/omap34xx.h new file mode 100644 index 00000000000..aa30c6d10ab --- /dev/null +++ b/include/asm-arm/arch-omap/omap34xx.h @@ -0,0 +1,72 @@ +/* + * include/asm-arm/arch-omap/omap34xx.h + * + * This file contains the processor specific definitions of the TI OMAP34XX. + * + * Copyright (C) 2007 Texas Instruments. + * Copyright (C) 2007 Nokia Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_OMAP34XX_H +#define __ASM_ARCH_OMAP34XX_H + +/* + * Please place only base defines here and put the rest in device + * specific headers. + */ + +#define L4_34XX_BASE 0x48000000 +#define L4_WK_34XX_BASE 0x48300000 +#define L4_WK_OMAP_BASE L4_WK_34XX_BASE +#define L4_PER_34XX_BASE 0x49000000 +#define L4_PER_OMAP_BASE L4_PER_34XX_BASE +#define L4_EMU_34XX_BASE 0x54000000 +#define L4_EMU_BASE L4_EMU_34XX_BASE +#define L3_34XX_BASE 0x68000000 +#define L3_OMAP_BASE L3_34XX_BASE + +#define OMAP3430_32KSYNCT_BASE 0x48320000 +#define OMAP3430_CM_BASE 0x48004800 +#define OMAP3430_PRM_BASE 0x48306800 +#define OMAP343X_SMS_BASE 0x6C000000 +#define OMAP343X_SDRC_BASE 0x6D000000 +#define OMAP34XX_GPMC_BASE 0x6E000000 +#define OMAP343X_SCM_BASE 0x48002000 +#define OMAP343X_CTRL_BASE OMAP343X_SCM_BASE + +#define OMAP34XX_IC_BASE 0x48200000 +#define OMAP34XX_IVA_INTC_BASE 0x40000000 +#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000) +#define OMAP34XX_HSUSB_HOST_BASE (L4_34XX_BASE + 0x64000) +#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000) + + +#if defined(CONFIG_ARCH_OMAP3430) + +#define OMAP2_32KSYNCT_BASE OMAP3430_32KSYNCT_BASE +#define OMAP2_CM_BASE OMAP3430_CM_BASE +#define OMAP2_PRM_BASE OMAP3430_PRM_BASE +#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP34XX_IC_BASE) + +#endif + +#define OMAP34XX_DSP_BASE 0x58000000 +#define OMAP34XX_DSP_MEM_BASE (OMAP34XX_DSP_BASE + 0x0) +#define OMAP34XX_DSP_IPI_BASE (OMAP34XX_DSP_BASE + 0x1000000) +#define OMAP34XX_DSP_MMU_BASE (OMAP34XX_DSP_BASE + 0x2000000) +#endif /* __ASM_ARCH_OMAP34XX_H */ + -- cgit v1.2.3-70-g09d2 From 4d96372e6daae89166fed7883ee092dc8db80b21 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:31 +0300 Subject: ARM: OMAP: DMA: Make channels dynamic for multi-boot Make DMA channels dynamic for multi-boot Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 62 +++++++++++++++++++++++++++-------------- include/asm-arm/arch-omap/dma.h | 7 ++--- 2 files changed, 44 insertions(+), 25 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 39c637b0ffe..02f00a98783 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -72,7 +72,6 @@ struct omap_dma_lch { long flags; }; -#ifndef CONFIG_ARCH_OMAP1 struct dma_link_info { int *linked_dmach_q; int no_of_lchs_linked; @@ -86,7 +85,9 @@ struct dma_link_info { }; -static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT]; +static struct dma_link_info *dma_linked_lch; + +#ifndef CONFIG_ARCH_OMAP1 /* Chain handling macros */ #define OMAP_DMA_CHAIN_QINIT(chain_id) \ @@ -119,12 +120,14 @@ static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT]; dma_linked_lch[chain_id].q_count++; \ } while (0) #endif + +static int dma_lch_count; static int dma_chan_count; static spinlock_t dma_chan_lock; -static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT]; +static struct omap_dma_lch *dma_chan; -static const u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { +static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = { INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, @@ -727,7 +730,7 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio, { u32 w; - if (unlikely((lch < 0 || lch >= OMAP_LOGICAL_DMA_CH_COUNT))) { + if (unlikely((lch < 0 || lch >= dma_lch_count))) { printk(KERN_ERR "Invalid channel id\n"); return -EINVAL; } @@ -775,7 +778,7 @@ void omap_start_dma(int lch) { if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch; - char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; + char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; dma_chan_link_map[lch] = 1; /* Set the link register of the first channel */ @@ -819,7 +822,7 @@ void omap_stop_dma(int lch) { if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch = lch; - char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; + char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); do { @@ -1061,7 +1064,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name, } if (unlikely((no_of_chans < 1 - || no_of_chans > OMAP_LOGICAL_DMA_CH_COUNT))) { + || no_of_chans > dma_lch_count))) { printk(KERN_ERR "Invalid Number of channels requested\n"); return -EINVAL; } @@ -1138,7 +1141,7 @@ int omap_modify_dma_chain_params(int chain_id, /* Check for input params */ if (unlikely((chain_id < 0 - || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1176,7 +1179,7 @@ int omap_free_dma_chain(int chain_id) u32 i; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1216,7 +1219,7 @@ EXPORT_SYMBOL(omap_free_dma_chain); int omap_dma_chain_status(int chain_id) { /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1265,7 +1268,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, /* Check for input params */ if (unlikely((chain_id < 0 - || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1382,7 +1385,7 @@ int omap_start_dma_chain_transfers(int chain_id) int *channels; u32 w, i; - if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1435,7 +1438,7 @@ int omap_stop_dma_chain_transfers(int chain_id) u32 sys_cf; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1497,7 +1500,7 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi) int *channels; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1537,7 +1540,7 @@ int omap_get_dma_chain_dst_pos(int chain_id) int *channels; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1571,7 +1574,7 @@ int omap_get_dma_chain_src_pos(int chain_id) int *channels; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { + if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1724,7 +1727,7 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id) printk(KERN_WARNING "Spurious DMA IRQ\n"); return IRQ_HANDLED; } - for (i = 0; i < OMAP_LOGICAL_DMA_CH_COUNT && val != 0; i++) { + for (i = 0; i < dma_lch_count && val != 0; i++) { if (val & 1) omap2_dma_handle_ch(i); val >>= 1; @@ -2106,6 +2109,25 @@ static int __init omap_init_dma(void) { int ch, r; + if (cpu_class_is_omap1()) + dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; + else + dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; + + dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count, + GFP_KERNEL); + if (!dma_chan) + return -ENOMEM; + + if (cpu_class_is_omap2()) { + dma_linked_lch = kzalloc(sizeof(struct dma_link_info) * + dma_lch_count, GFP_KERNEL); + if (!dma_linked_lch) { + kfree(dma_chan); + return -ENOMEM; + } + } + if (cpu_is_omap15xx()) { printk(KERN_INFO "DMA support for OMAP15xx initialized\n"); dma_chan_count = 9; @@ -2142,16 +2164,14 @@ static int __init omap_init_dma(void) u8 revision = omap_readb(OMAP_DMA4_REVISION); printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", revision >> 4, revision & 0xf); - dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT; + dma_chan_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; } else { dma_chan_count = 0; return 0; } - memset(&lcd_dma, 0, sizeof(lcd_dma)); spin_lock_init(&lcd_dma.lock); spin_lock_init(&dma_chan_lock); - memset(&dma_chan, 0, sizeof(dma_chan)); for (ch = 0; ch < dma_chan_count; ch++) { omap_clear_dma(ch); diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h index 24acf090030..46fe5a40a25 100644 --- a/include/asm-arm/arch-omap/dma.h +++ b/include/asm-arm/arch-omap/dma.h @@ -68,9 +68,10 @@ #define OMAP_DMA4_CAPS_3 (OMAP_DMA4_BASE + 0x70) #define OMAP_DMA4_CAPS_4 (OMAP_DMA4_BASE + 0x74) -#ifdef CONFIG_ARCH_OMAP1 +#define OMAP1_LOGICAL_DMA_CH_COUNT 17 +#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */ -#define OMAP_LOGICAL_DMA_CH_COUNT 17 +#ifdef CONFIG_ARCH_OMAP1 /* Common channel specific registers for omap1 */ #define OMAP_DMA_CSDP_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x00) @@ -89,8 +90,6 @@ #else -#define OMAP_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */ - /* Common channel specific registers for omap2 */ #define OMAP_DMA_CCR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x80) #define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x84) -- cgit v1.2.3-70-g09d2 From 0499bdeb1dec30325aa282a83f9374fa849aa01c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:36 +0300 Subject: ARM: OMAP: DMA: Remove __REG access Remove __REG access in DMA code, use dma_read/write instead: - dynamically set the omap_dma_base based on the omap type - omap_read/write becomes dma_read/write - dma channel registers are read with dma_ch_read/write Cc: David Brownell Cc: linux-usb@vger.kernel.org Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 503 ++++++++++++++++++++++++++-------------- drivers/usb/gadget/omap_udc.c | 42 +--- include/asm-arm/arch-omap/dma.h | 210 ++++++++++------- 3 files changed, 450 insertions(+), 305 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 02f00a98783..18e757a9ec6 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -126,6 +126,7 @@ static int dma_chan_count; static spinlock_t dma_chan_lock; static struct omap_dma_lch *dma_chan; +static void __iomem *omap_dma_base; static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = { INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, @@ -142,6 +143,24 @@ static inline void omap_enable_channel_irq(int lch); #define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \ __func__); +#define dma_read(reg) \ +({ \ + u32 __val; \ + if (cpu_class_is_omap1()) \ + __val = __raw_readw(omap_dma_base + OMAP1_DMA_##reg); \ + else \ + __val = __raw_readl(omap_dma_base + OMAP_DMA4_##reg); \ + __val; \ +}) + +#define dma_write(val, reg) \ +({ \ + if (cpu_class_is_omap1()) \ + __raw_writew((u16)(val), omap_dma_base + OMAP1_DMA_##reg); \ + else \ + __raw_writel((val), omap_dma_base + OMAP_DMA4_##reg); \ +}) + #ifdef CONFIG_ARCH_OMAP15XX /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */ int omap_dma_in_1510_mode(void) @@ -176,13 +195,14 @@ static inline void set_gdma_dev(int req, int dev) #define set_gdma_dev(req, dev) do {} while (0) #endif +/* Omap1 only */ static void clear_lch_regs(int lch) { int i; - u32 lch_base = OMAP_DMA_BASE + lch * 0x40; + void __iomem *lch_base = omap_dma_base + OMAP1_DMA_CH_BASE(lch); for (i = 0; i < 0x2c; i += 2) - omap_writew(0, lch_base + i); + __raw_writew(0, lch_base + i); } void omap_set_dma_priority(int lch, int dst_port, int priority) @@ -215,10 +235,14 @@ void omap_set_dma_priority(int lch, int dst_port, int priority) } if (cpu_class_is_omap2()) { + u32 ccr; + + ccr = dma_read(CCR(lch)); if (priority) - OMAP_DMA_CCR_REG(lch) |= (1 << 6); + ccr |= (1 << 6); else - OMAP_DMA_CCR_REG(lch) &= ~(1 << 6); + ccr &= ~(1 << 6); + dma_write(ccr, CCR(lch)); } } @@ -226,22 +250,33 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, int frame_count, int sync_mode, int dma_trigger, int src_or_dst_synch) { - OMAP_DMA_CSDP_REG(lch) &= ~0x03; - OMAP_DMA_CSDP_REG(lch) |= data_type; + u32 l; + + l = dma_read(CSDP(lch)); + l &= ~0x03; + l |= data_type; + dma_write(l, CSDP(lch)); if (cpu_class_is_omap1()) { - OMAP_DMA_CCR_REG(lch) &= ~(1 << 5); + u16 ccr; + + ccr = dma_read(CCR(lch)); + ccr &= ~(1 << 5); if (sync_mode == OMAP_DMA_SYNC_FRAME) - OMAP_DMA_CCR_REG(lch) |= 1 << 5; + ccr |= 1 << 5; + dma_write(ccr, CCR(lch)); - OMAP1_DMA_CCR2_REG(lch) &= ~(1 << 2); + ccr = dma_read(CCR2(lch)); + ccr &= ~(1 << 2); if (sync_mode == OMAP_DMA_SYNC_BLOCK) - OMAP1_DMA_CCR2_REG(lch) |= 1 << 2; + ccr |= 1 << 2; + dma_write(ccr, CCR2(lch)); } if (cpu_class_is_omap2() && dma_trigger) { - u32 val = OMAP_DMA_CCR_REG(lch); + u32 val; + val = dma_read(CCR(lch)); val &= ~(3 << 19); if (dma_trigger > 63) val |= 1 << 20; @@ -266,11 +301,11 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, else val &= ~(1 << 24); /* dest synch */ - OMAP_DMA_CCR_REG(lch) = val; + dma_write(val, CCR(lch)); } - OMAP_DMA_CEN_REG(lch) = elem_count; - OMAP_DMA_CFN_REG(lch) = frame_count; + dma_write(elem_count, CEN(lch)); + dma_write(frame_count, CFN(lch)); } void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) @@ -284,7 +319,9 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) return; } - w = OMAP1_DMA_CCR2_REG(lch) & ~0x03; + w = dma_read(CCR2(lch)); + w &= ~0x03; + switch (mode) { case OMAP_DMA_CONSTANT_FILL: w |= 0x01; @@ -297,49 +334,81 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) default: BUG(); } - OMAP1_DMA_CCR2_REG(lch) = w; + dma_write(w, CCR2(lch)); - w = OMAP1_DMA_LCH_CTRL_REG(lch) & ~0x0f; + w = dma_read(LCH_CTRL(lch)); + w &= ~0x0f; /* Default is channel type 2D */ if (mode) { - OMAP1_DMA_COLOR_L_REG(lch) = (u16)color; - OMAP1_DMA_COLOR_U_REG(lch) = (u16)(color >> 16); + dma_write((u16)color, COLOR_L(lch)); + dma_write((u16)(color >> 16), COLOR_U(lch)); w |= 1; /* Channel type G */ } - OMAP1_DMA_LCH_CTRL_REG(lch) = w; + dma_write(w, LCH_CTRL(lch)); } void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) { if (cpu_class_is_omap2()) { - OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16); - OMAP_DMA_CSDP_REG(lch) |= (mode << 16); + u32 csdp; + + csdp = dma_read(CSDP(lch)); + csdp &= ~(0x3 << 16); + csdp |= (mode << 16); + dma_write(csdp, CSDP(lch)); } } +void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode) +{ + if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { + u32 l; + + l = dma_read(LCH_CTRL(lch)); + l &= ~0x7; + l |= mode; + dma_write(l, LCH_CTRL(lch)); + } +} +EXPORT_SYMBOL(omap_set_dma_channel_mode); + /* Note that src_port is only for omap1 */ void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start, int src_ei, int src_fi) { if (cpu_class_is_omap1()) { - OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 2); - OMAP_DMA_CSDP_REG(lch) |= src_port << 2; - } + u16 w; - OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 12); - OMAP_DMA_CCR_REG(lch) |= src_amode << 12; + w = dma_read(CSDP(lch)); + w &= ~(0x1f << 2); + w |= src_port << 2; + dma_write(w, CSDP(lch)); - if (cpu_class_is_omap1()) { - OMAP1_DMA_CSSA_U_REG(lch) = src_start >> 16; - OMAP1_DMA_CSSA_L_REG(lch) = src_start; + w = dma_read(CCR(lch)); + w &= ~(0x03 << 12); + w |= src_amode << 12; + dma_write(w, CCR(lch)); + + dma_write(src_start >> 16, CSSA_U(lch)); + dma_write((u16)src_start, CSSA_L(lch)); + + dma_write(src_ei, CSEI(lch)); + dma_write(src_fi, CSFI(lch)); } - if (cpu_class_is_omap2()) - OMAP2_DMA_CSSA_REG(lch) = src_start; + if (cpu_class_is_omap2()) { + u32 l; + + l = dma_read(CCR(lch)); + l &= ~(0x03 << 12); + l |= src_amode << 12; + dma_write(l, CCR(lch)); - OMAP_DMA_CSEI_REG(lch) = src_ei; - OMAP_DMA_CSFI_REG(lch) = src_fi; + dma_write(src_start, CSSA(lch)); + dma_write(src_ei, CSEI(lch)); + dma_write(src_fi, CSFI(lch)); + } } void omap_set_dma_params(int lch, struct omap_dma_channel_params * params) @@ -366,21 +435,28 @@ void omap_set_dma_src_index(int lch, int eidx, int fidx) REVISIT_24XX(); return; } - OMAP_DMA_CSEI_REG(lch) = eidx; - OMAP_DMA_CSFI_REG(lch) = fidx; + dma_write(eidx, CSEI(lch)); + dma_write(fidx, CSFI(lch)); } void omap_set_dma_src_data_pack(int lch, int enable) { - OMAP_DMA_CSDP_REG(lch) &= ~(1 << 6); + u32 l; + + l = dma_read(CSDP(lch)); + l &= ~(1 << 6); if (enable) - OMAP_DMA_CSDP_REG(lch) |= (1 << 6); + l |= (1 << 6); + dma_write(l, CSDP(lch)); } void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) { unsigned int burst = 0; - OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7); + u32 l; + + l = dma_read(CSDP(lch)); + l &= ~(0x03 << 7); switch (burst_mode) { case OMAP_DMA_DATA_BURST_DIS: @@ -411,7 +487,9 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) default: BUG(); } - OMAP_DMA_CSDP_REG(lch) |= (burst << 7); + + l |= (burst << 7); + dma_write(l, CSDP(lch)); } /* Note that dest_port is only for OMAP1 */ @@ -419,24 +497,30 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, unsigned long dest_start, int dst_ei, int dst_fi) { + u32 l; + if (cpu_class_is_omap1()) { - OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 9); - OMAP_DMA_CSDP_REG(lch) |= dest_port << 9; + l = dma_read(CSDP(lch)); + l &= ~(0x1f << 9); + l |= dest_port << 9; + dma_write(l, CSDP(lch)); } - OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 14); - OMAP_DMA_CCR_REG(lch) |= dest_amode << 14; + l = dma_read(CCR(lch)); + l &= ~(0x03 << 14); + l |= dest_amode << 14; + dma_write(l, CCR(lch)); if (cpu_class_is_omap1()) { - OMAP1_DMA_CDSA_U_REG(lch) = dest_start >> 16; - OMAP1_DMA_CDSA_L_REG(lch) = dest_start; + dma_write(dest_start >> 16, CDSA_U(lch)); + dma_write(dest_start, CDSA_L(lch)); } if (cpu_class_is_omap2()) - OMAP2_DMA_CDSA_REG(lch) = dest_start; + dma_write(dest_start, CDSA(lch)); - OMAP_DMA_CDEI_REG(lch) = dst_ei; - OMAP_DMA_CDFI_REG(lch) = dst_fi; + dma_write(dst_ei, CDEI(lch)); + dma_write(dst_fi, CDFI(lch)); } void omap_set_dma_dest_index(int lch, int eidx, int fidx) @@ -445,21 +529,28 @@ void omap_set_dma_dest_index(int lch, int eidx, int fidx) REVISIT_24XX(); return; } - OMAP_DMA_CDEI_REG(lch) = eidx; - OMAP_DMA_CDFI_REG(lch) = fidx; + dma_write(eidx, CDEI(lch)); + dma_write(fidx, CDFI(lch)); } void omap_set_dma_dest_data_pack(int lch, int enable) { - OMAP_DMA_CSDP_REG(lch) &= ~(1 << 13); + u32 l; + + l = dma_read(CSDP(lch)); + l &= ~(1 << 13); if (enable) - OMAP_DMA_CSDP_REG(lch) |= 1 << 13; + l |= 1 << 13; + dma_write(l, CSDP(lch)); } void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) { unsigned int burst = 0; - OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14); + u32 l; + + l = dma_read(CSDP(lch)); + l &= ~(0x03 << 14); switch (burst_mode) { case OMAP_DMA_DATA_BURST_DIS: @@ -489,7 +580,8 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) BUG(); return; } - OMAP_DMA_CSDP_REG(lch) |= (burst << 14); + l |= (burst << 14); + dma_write(l, CSDP(lch)); } static inline void omap_enable_channel_irq(int lch) @@ -498,18 +590,18 @@ static inline void omap_enable_channel_irq(int lch) /* Clear CSR */ if (cpu_class_is_omap1()) - status = OMAP_DMA_CSR_REG(lch); + status = dma_read(CSR(lch)); else if (cpu_class_is_omap2()) - OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK; + dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch)); /* Enable some nice interrupts. */ - OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs; + dma_write(dma_chan[lch].enabled_irqs, CICR(lch)); } static void omap_disable_channel_irq(int lch) { if (cpu_class_is_omap2()) - OMAP_DMA_CICR_REG(lch) = 0; + dma_write(0, CICR(lch)); } void omap_enable_dma_irq(int lch, u16 bits) @@ -524,36 +616,45 @@ void omap_disable_dma_irq(int lch, u16 bits) static inline void enable_lnk(int lch) { + u32 l; + + l = dma_read(CLNK_CTRL(lch)); + if (cpu_class_is_omap1()) - OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 14); + l &= ~(1 << 14); /* Set the ENABLE_LNK bits */ if (dma_chan[lch].next_lch != -1) - OMAP_DMA_CLNK_CTRL_REG(lch) = - dma_chan[lch].next_lch | (1 << 15); + l = dma_chan[lch].next_lch | (1 << 15); #ifndef CONFIG_ARCH_OMAP1 if (dma_chan[lch].next_linked_ch != -1) - OMAP_DMA_CLNK_CTRL_REG(lch) = - dma_chan[lch].next_linked_ch | (1 << 15); + l = dma_chan[lch].next_linked_ch | (1 << 15); #endif + + dma_write(l, CLNK_CTRL(lch)); } static inline void disable_lnk(int lch) { + u32 l; + + l = dma_read(CLNK_CTRL(lch)); + /* Disable interrupts */ if (cpu_class_is_omap1()) { - OMAP_DMA_CICR_REG(lch) = 0; + dma_write(0, CICR(lch)); /* Set the STOP_LNK bit */ - OMAP_DMA_CLNK_CTRL_REG(lch) |= 1 << 14; + l |= 1 << 14; } if (cpu_class_is_omap2()) { omap_disable_channel_irq(lch); /* Clear the ENABLE_LNK bit */ - OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 15); + l &= ~(1 << 15); } + dma_write(l, CLNK_CTRL(lch)); dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; } @@ -564,9 +665,9 @@ static inline void omap2_enable_irq_lch(int lch) if (!cpu_class_is_omap2()) return; - val = omap_readl(OMAP_DMA4_IRQENABLE_L0); + val = dma_read(IRQENABLE_L0); val |= 1 << lch; - omap_writel(val, OMAP_DMA4_IRQENABLE_L0); + dma_write(val, IRQENABLE_L0); } int omap_request_dma(int dev_id, const char *dev_name, @@ -623,9 +724,9 @@ int omap_request_dma(int dev_id, const char *dev_name, } /* Disable the 1510 compatibility mode and set the sync device * id. */ - OMAP_DMA_CCR_REG(free_ch) = dev_id | (1 << 10); + dma_write(dev_id | (1 << 10), CCR(free_ch)); } else if (cpu_is_omap730() || cpu_is_omap15xx()) { - OMAP_DMA_CCR_REG(free_ch) = dev_id; + dma_write(dev_id, CCR(free_ch)); } if (cpu_class_is_omap2()) { @@ -633,8 +734,8 @@ int omap_request_dma(int dev_id, const char *dev_name, omap_enable_channel_irq(free_ch); /* Clear the CSR register and IRQ status register */ - OMAP_DMA_CSR_REG(free_ch) = OMAP2_DMA_CSR_CLEAR_MASK; - omap_writel(1 << free_ch, OMAP_DMA4_IRQSTATUS_L0); + dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(free_ch)); + dma_write(1 << free_ch, IRQSTATUS_L0); } *dma_ch_out = free_ch; @@ -660,27 +761,27 @@ void omap_free_dma(int lch) if (cpu_class_is_omap1()) { /* Disable all DMA interrupts for the channel. */ - OMAP_DMA_CICR_REG(lch) = 0; + dma_write(0, CICR(lch)); /* Make sure the DMA transfer is stopped. */ - OMAP_DMA_CCR_REG(lch) = 0; + dma_write(0, CCR(lch)); } if (cpu_class_is_omap2()) { u32 val; /* Disable interrupts */ - val = omap_readl(OMAP_DMA4_IRQENABLE_L0); + val = dma_read(IRQENABLE_L0); val &= ~(1 << lch); - omap_writel(val, OMAP_DMA4_IRQENABLE_L0); + dma_write(val, IRQENABLE_L0); /* Clear the CSR register and IRQ status register */ - OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK; - omap_writel(1 << lch, OMAP_DMA4_IRQSTATUS_L0); + dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch)); + dma_write(1 << lch, IRQSTATUS_L0); /* Disable all DMA interrupts for the channel. */ - OMAP_DMA_CICR_REG(lch) = 0; + dma_write(0, CICR(lch)); /* Make sure the DMA transfer is stopped. */ - OMAP_DMA_CCR_REG(lch) = 0; + dma_write(0, CCR(lch)); omap_clear_dma(lch); } } @@ -711,7 +812,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams) reg = (arb_rate & 0xff) << 16; reg |= (0xff & max_fifo_depth); - omap_writel(reg, OMAP_DMA4_GCR_REG); + dma_write(reg, GCR); } EXPORT_SYMBOL(omap_dma_set_global_params); @@ -728,20 +829,21 @@ int omap_dma_set_prio_lch(int lch, unsigned char read_prio, unsigned char write_prio) { - u32 w; + u32 l; if (unlikely((lch < 0 || lch >= dma_lch_count))) { printk(KERN_ERR "Invalid channel id\n"); return -EINVAL; } - w = OMAP_DMA_CCR_REG(lch); - w &= ~((1 << 6) | (1 << 26)); + l = dma_read(CCR(lch)); + l &= ~((1 << 6) | (1 << 26)); if (cpu_is_omap2430() || cpu_is_omap34xx()) - w |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26); + l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26); else - w |= ((read_prio & 0x1) << 6); + l |= ((read_prio & 0x1) << 6); + + dma_write(l, CCR(lch)); - OMAP_DMA_CCR_REG(lch) = w; return 0; } EXPORT_SYMBOL(omap_dma_set_prio_lch); @@ -757,18 +859,21 @@ void omap_clear_dma(int lch) local_irq_save(flags); if (cpu_class_is_omap1()) { - int status; - OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN; + u32 l; + + l = dma_read(CCR(lch)); + l &= ~OMAP_DMA_CCR_EN; + dma_write(l, CCR(lch)); /* Clear pending interrupts */ - status = OMAP_DMA_CSR_REG(lch); + l = dma_read(CSR(lch)); } if (cpu_class_is_omap2()) { int i; - u32 lch_base = OMAP_DMA4_BASE + lch * 0x60 + 0x80; + void __iomem *lch_base = omap_dma_base + OMAP_DMA4_CH_BASE(lch); for (i = 0; i < 0x44; i += 4) - omap_writel(0, lch_base + i); + __raw_writel(0, lch_base + i); } local_irq_restore(flags); @@ -776,6 +881,8 @@ void omap_clear_dma(int lch) void omap_start_dma(int lch) { + u32 l; + if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch; char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; @@ -802,24 +909,28 @@ void omap_start_dma(int lch) } while (next_lch != -1); } else if (cpu_class_is_omap2()) { /* Errata: Need to write lch even if not using chaining */ - OMAP_DMA_CLNK_CTRL_REG(lch) = lch; + dma_write(lch, CLNK_CTRL(lch)); } omap_enable_channel_irq(lch); + l = dma_read(CCR(lch)); + /* Errata: On ES2.0 BUFFERING disable must be set. * This will always fail on ES1.0 */ - if (cpu_is_omap24xx()) { - OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN; - } + if (cpu_is_omap24xx()) + l |= OMAP_DMA_CCR_EN; - OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN; + l |= OMAP_DMA_CCR_EN; + dma_write(l, CCR(lch)); dma_chan[lch].flags |= OMAP_DMA_ACTIVE; } void omap_stop_dma(int lch) { + u32 l; + if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch = lch; char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; @@ -843,9 +954,12 @@ void omap_stop_dma(int lch) /* Disable all interrupts on the channel */ if (cpu_class_is_omap1()) - OMAP_DMA_CICR_REG(lch) = 0; + dma_write(0, CICR(lch)); + + l = dma_read(CCR(lch)); + l &= ~OMAP_DMA_CCR_EN; + dma_write(l, CCR(lch)); - OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN; dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; } @@ -887,12 +1001,20 @@ dma_addr_t omap_get_dma_src_pos(int lch) { dma_addr_t offset = 0; - if (cpu_class_is_omap1()) - offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) | - (OMAP1_DMA_CSSA_U_REG(lch) << 16)); + if (cpu_is_omap15xx()) + offset = dma_read(CPC(lch)); + else + offset = dma_read(CSAC(lch)); - if (cpu_class_is_omap2()) - offset = OMAP_DMA_CSAC_REG(lch); + /* + * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is + * read before the DMA controller finished disabling the channel. + */ + if (!cpu_is_omap15xx() && offset == 0) + offset = dma_read(CSAC(lch)); + + if (cpu_class_is_omap1()) + offset |= (dma_read(CSSA_U(lch)) << 16); return offset; } @@ -909,12 +1031,20 @@ dma_addr_t omap_get_dma_dst_pos(int lch) { dma_addr_t offset = 0; - if (cpu_class_is_omap1()) - offset = (dma_addr_t) (OMAP1_DMA_CDSA_L_REG(lch) | - (OMAP1_DMA_CDSA_U_REG(lch) << 16)); + if (cpu_is_omap15xx()) + offset = dma_read(CPC(lch)); + else + offset = dma_read(CDAC(lch)); - if (cpu_class_is_omap2()) - offset = OMAP_DMA_CDAC_REG(lch); + /* + * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is + * read before the DMA controller finished disabling the channel. + */ + if (!cpu_is_omap15xx() && offset == 0) + offset = dma_read(CDAC(lch)); + + if (cpu_class_is_omap1()) + offset |= (dma_read(CDSA_U(lch)) << 16); return offset; } @@ -926,8 +1056,14 @@ dma_addr_t omap_get_dma_dst_pos(int lch) */ int omap_get_dma_src_addr_counter(int lch) { - return (dma_addr_t) OMAP_DMA_CSAC_REG(lch); + return (dma_addr_t)dma_read(CSAC(lch)); +} + +int omap_get_dma_active_status(int lch) +{ + return (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN) != 0; } +EXPORT_SYMBOL(omap_get_dma_active_status); int omap_dma_running(void) { @@ -939,7 +1075,7 @@ int omap_dma_running(void) return 1; for (lch = 0; lch < dma_chan_count; lch++) - if (OMAP_DMA_CCR_REG(lch) & OMAP_DMA_CCR_EN) + if (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN) return 1; return 0; @@ -1001,7 +1137,7 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue) /* Create chain of DMA channesls */ static void create_dma_lch_chain(int lch_head, int lch_queue) { - u32 w; + u32 l; /* Check if this is the first link in chain */ if (dma_chan[lch_head].next_linked_ch == -1) { @@ -1021,15 +1157,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue) lch_queue; } - w = OMAP_DMA_CLNK_CTRL_REG(lch_head); - w &= ~(0x1f); - w |= lch_queue; - OMAP_DMA_CLNK_CTRL_REG(lch_head) = w; + l = dma_read(CLNK_CTRL(lch_head)); + l &= ~(0x1f); + l |= lch_queue; + dma_write(l, CLNK_CTRL(lch_head)); - w = OMAP_DMA_CLNK_CTRL_REG(lch_queue); - w &= ~(0x1f); - w |= (dma_chan[lch_queue].next_linked_ch); - OMAP_DMA_CLNK_CTRL_REG(lch_queue) = w; + l = dma_read(CLNK_CTRL(lch_queue)); + l &= ~(0x1f); + l |= (dma_chan[lch_queue].next_linked_ch); + dma_write(l, CLNK_CTRL(lch_queue)); } /** @@ -1256,7 +1392,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, int elem_count, int frame_count, void *callbk_data) { int *channels; - u32 w, lch; + u32 l, lch; int start_dma = 0; /* if buffer size is less than 1 then there is @@ -1297,13 +1433,13 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, /* Set the params to the free channel */ if (src_start != 0) - OMAP2_DMA_CSSA_REG(lch) = src_start; + dma_write(src_start, CSSA(lch)); if (dest_start != 0) - OMAP2_DMA_CDSA_REG(lch) = dest_start; + dma_write(dest_start, CDSA(lch)); /* Write the buffer size */ - OMAP_DMA_CEN_REG(lch) = elem_count; - OMAP_DMA_CFN_REG(lch) = frame_count; + dma_write(elem_count, CEN(lch)); + dma_write(frame_count, CFN(lch)); /* If the chain is dynamically linked, * then we may have to start the chain if its not active */ @@ -1330,8 +1466,8 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, enable_lnk(dma_chan[lch].prev_linked_ch); dma_chan[lch].state = DMA_CH_QUEUED; start_dma = 0; - if (0 == ((1 << 7) & (OMAP_DMA_CCR_REG - (dma_chan[lch].prev_linked_ch)))) { + if (0 == ((1 << 7) & dma_read( + CCR(dma_chan[lch].prev_linked_ch)))) { disable_lnk(dma_chan[lch]. prev_linked_ch); pr_debug("\n prev ch is stopped\n"); @@ -1347,23 +1483,23 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, } omap_enable_channel_irq(lch); - w = OMAP_DMA_CCR_REG(lch); + l = dma_read(CCR(lch)); - if ((0 == (w & (1 << 24)))) - w &= ~(1 << 25); + if ((0 == (l & (1 << 24)))) + l &= ~(1 << 25); else - w |= (1 << 25); + l |= (1 << 25); if (start_dma == 1) { - if (0 == (w & (1 << 7))) { - w |= (1 << 7); + if (0 == (l & (1 << 7))) { + l |= (1 << 7); dma_chan[lch].state = DMA_CH_STARTED; pr_debug("starting %d\n", lch); - OMAP_DMA_CCR_REG(lch) = w; + dma_write(l, CCR(lch)); } else start_dma = 0; } else { - if (0 == (w & (1 << 7))) - OMAP_DMA_CCR_REG(lch) = w; + if (0 == (l & (1 << 7))) + dma_write(l, CCR(lch)); } dma_chan[lch].flags |= OMAP_DMA_ACTIVE; } @@ -1383,7 +1519,7 @@ EXPORT_SYMBOL(omap_dma_chain_a_transfer); int omap_start_dma_chain_transfers(int chain_id) { int *channels; - u32 w, i; + u32 l, i; if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { printk(KERN_ERR "Invalid chain id\n"); @@ -1407,16 +1543,16 @@ int omap_start_dma_chain_transfers(int chain_id) omap_enable_channel_irq(channels[0]); } - w = OMAP_DMA_CCR_REG(channels[0]); - w |= (1 << 7); + l = dma_read(CCR(channels[0])); + l |= (1 << 7); dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED; dma_chan[channels[0]].state = DMA_CH_STARTED; - if ((0 == (w & (1 << 24)))) - w &= ~(1 << 25); + if ((0 == (l & (1 << 24)))) + l &= ~(1 << 25); else - w |= (1 << 25); - OMAP_DMA_CCR_REG(channels[0]) = w; + l |= (1 << 25); + dma_write(l, CCR(channels[0])); dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE; return 0; @@ -1434,7 +1570,7 @@ EXPORT_SYMBOL(omap_start_dma_chain_transfers); int omap_stop_dma_chain_transfers(int chain_id) { int *channels; - u32 w, i; + u32 l, i; u32 sys_cf; /* Check for input params */ @@ -1453,18 +1589,18 @@ int omap_stop_dma_chain_transfers(int chain_id) /* DMA Errata: * Special programming model needed to disable DMA before end of block */ - sys_cf = omap_readl(OMAP_DMA4_OCP_SYSCONFIG); - w = sys_cf; + sys_cf = dma_read(OCP_SYSCONFIG); + l = sys_cf; /* Middle mode reg set no Standby */ - w &= ~((1 << 12)|(1 << 13)); - omap_writel(w, OMAP_DMA4_OCP_SYSCONFIG); + l &= ~((1 << 12)|(1 << 13)); + dma_write(l, OCP_SYSCONFIG); for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) { /* Stop the Channel transmission */ - w = OMAP_DMA_CCR_REG(channels[i]); - w &= ~(1 << 7); - OMAP_DMA_CCR_REG(channels[i]) = w; + l = dma_read(CCR(channels[i])); + l &= ~(1 << 7); + dma_write(l, CCR(channels[i])); /* Disable the link in all the channels */ disable_lnk(channels[i]); @@ -1477,7 +1613,7 @@ int omap_stop_dma_chain_transfers(int chain_id) OMAP_DMA_CHAIN_QINIT(chain_id); /* Errata - put in the old value */ - omap_writel(sys_cf, OMAP_DMA4_OCP_SYSCONFIG); + dma_write(sys_cf, OCP_SYSCONFIG); return 0; } EXPORT_SYMBOL(omap_stop_dma_chain_transfers); @@ -1518,8 +1654,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi) /* Get the current channel */ lch = channels[dma_linked_lch[chain_id].q_head]; - *ei = OMAP2_DMA_CCEN_REG(lch); - *fi = OMAP2_DMA_CCFN_REG(lch); + *ei = dma_read(CCEN(lch)); + *fi = dma_read(CCFN(lch)); return 0; } @@ -1556,7 +1692,7 @@ int omap_get_dma_chain_dst_pos(int chain_id) /* Get the current channel */ lch = channels[dma_linked_lch[chain_id].q_head]; - return (OMAP_DMA_CDAC_REG(lch)); + return dma_read(CDAC(lch)); } EXPORT_SYMBOL(omap_get_dma_chain_dst_pos); @@ -1590,7 +1726,7 @@ int omap_get_dma_chain_src_pos(int chain_id) /* Get the current channel */ lch = channels[dma_linked_lch[chain_id].q_head]; - return (OMAP_DMA_CSAC_REG(lch)); + return dma_read(CSAC(lch)); } EXPORT_SYMBOL(omap_get_dma_chain_src_pos); #endif @@ -1601,13 +1737,13 @@ EXPORT_SYMBOL(omap_get_dma_chain_src_pos); static int omap1_dma_handle_ch(int ch) { - u16 csr; + u32 csr; if (enable_1510_mode && ch >= 6) { csr = dma_chan[ch].saved_csr; dma_chan[ch].saved_csr = 0; } else - csr = OMAP_DMA_CSR_REG(ch); + csr = dma_read(CSR(ch)); if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) { dma_chan[ch + 6].saved_csr = csr >> 7; csr &= 0x7f; @@ -1659,12 +1795,12 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id) static int omap2_dma_handle_ch(int ch) { - u32 status = OMAP_DMA_CSR_REG(ch); + u32 status = dma_read(CSR(ch)); if (!status) { if (printk_ratelimit()) printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", ch); - omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0); + dma_write(1 << ch, IRQSTATUS_L0); return 0; } if (unlikely(dma_chan[ch].dev_id == -1)) { @@ -1687,14 +1823,14 @@ static int omap2_dma_handle_ch(int ch) printk(KERN_INFO "DMA misaligned error with device %d\n", dma_chan[ch].dev_id); - OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK; - omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0); + dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch)); + dma_write(1 << ch, IRQSTATUS_L0); /* If the ch is not chained then chain_id will be -1 */ if (dma_chan[ch].chain_id != -1) { int chain_id = dma_chan[ch].chain_id; dma_chan[ch].state = DMA_CH_NOTSTARTED; - if (OMAP_DMA_CLNK_CTRL_REG(ch) & (1 << 15)) + if (dma_read(CLNK_CTRL(ch)) & (1 << 15)) dma_chan[dma_chan[ch].next_linked_ch].state = DMA_CH_STARTED; if (dma_linked_lch[chain_id].chain_mode == @@ -1704,13 +1840,13 @@ static int omap2_dma_handle_ch(int ch) if (!OMAP_DMA_CHAIN_QEMPTY(chain_id)) OMAP_DMA_CHAIN_INCQHEAD(chain_id); - status = OMAP_DMA_CSR_REG(ch); + status = dma_read(CSR(ch)); } if (likely(dma_chan[ch].callback != NULL)) dma_chan[ch].callback(ch, status, dma_chan[ch].data); - OMAP_DMA_CSR_REG(ch) = status; + dma_write(status, CSR(ch)); return 0; } @@ -1721,7 +1857,7 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id) u32 val; int i; - val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); + val = dma_read(IRQSTATUS_L0); if (val == 0) { if (printk_ratelimit()) printk(KERN_WARNING "Spurious DMA IRQ\n"); @@ -2109,10 +2245,19 @@ static int __init omap_init_dma(void) { int ch, r; - if (cpu_class_is_omap1()) + if (cpu_class_is_omap1()) { + omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP1_DMA_BASE); dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; - else + } else if (cpu_is_omap24xx()) { + omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP24XX_DMA4_BASE); dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; + } else if (cpu_is_omap34xx()) { + omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP34XX_DMA4_BASE); + dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; + } else { + pr_err("DMA init failed for unsupported omap\n"); + return -ENODEV; + } dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count, GFP_KERNEL); @@ -2134,21 +2279,21 @@ static int __init omap_init_dma(void) enable_1510_mode = 1; } else if (cpu_is_omap16xx() || cpu_is_omap730()) { printk(KERN_INFO "OMAP DMA hardware version %d\n", - omap_readw(OMAP_DMA_HW_ID)); + dma_read(HW_ID)); printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n", - (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | - omap_readw(OMAP_DMA_CAPS_0_L), - (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | - omap_readw(OMAP_DMA_CAPS_1_L), - omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3), - omap_readw(OMAP_DMA_CAPS_4)); + (dma_read(CAPS_0_U) << 16) | + dma_read(CAPS_0_L), + (dma_read(CAPS_1_U) << 16) | + dma_read(CAPS_1_L), + dma_read(CAPS_2), dma_read(CAPS_3), + dma_read(CAPS_4)); if (!enable_1510_mode) { u16 w; /* Disable OMAP 3.0/3.1 compatibility mode. */ - w = omap_readw(OMAP_DMA_GSCR); + w = dma_read(GSCR); w |= 1 << 3; - omap_writew(w, OMAP_DMA_GSCR); + dma_write(w, GSCR); dma_chan_count = 16; } else dma_chan_count = 9; @@ -2161,7 +2306,7 @@ static int __init omap_init_dma(void) omap_writew(w, OMAP1610_DMA_LCD_CTRL); } } else if (cpu_class_is_omap2()) { - u8 revision = omap_readb(OMAP_DMA4_REVISION); + u8 revision = dma_read(REVISION) & 0xff; printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", revision >> 4, revision & 0xf); dma_chan_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 881d74c3d96..86c029a8d99 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -491,32 +491,6 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) /*-------------------------------------------------------------------------*/ -static inline dma_addr_t dma_csac(unsigned lch) -{ - dma_addr_t csac; - - /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is - * read before the DMA controller finished disabling the channel. - */ - csac = OMAP_DMA_CSAC_REG(lch); - if (csac == 0) - csac = OMAP_DMA_CSAC_REG(lch); - return csac; -} - -static inline dma_addr_t dma_cdac(unsigned lch) -{ - dma_addr_t cdac; - - /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is - * read before the DMA controller finished disabling the channel. - */ - cdac = OMAP_DMA_CDAC_REG(lch); - if (cdac == 0) - cdac = OMAP_DMA_CDAC_REG(lch); - return cdac; -} - static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) { dma_addr_t end; @@ -527,7 +501,7 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) if (cpu_is_omap15xx()) return 0; - end = dma_csac(ep->lch); + end = omap_get_dma_src_pos(ep->lch); if (end == ep->dma_counter) return 0; @@ -537,15 +511,11 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) return end - start; } -#define DMA_DEST_LAST(x) (cpu_is_omap15xx() \ - ? OMAP_DMA_CSAC_REG(x) /* really: CPC */ \ - : dma_cdac(x)) - static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) { dma_addr_t end; - end = DMA_DEST_LAST(ep->lch); + end = omap_get_dma_dst_pos(ep->lch); if (end == ep->dma_counter) return 0; @@ -596,7 +566,7 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) 0, 0); omap_start_dma(ep->lch); - ep->dma_counter = dma_csac(ep->lch); + ep->dma_counter = omap_get_dma_src_pos(ep->lch); UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel); UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl; req->dma_bytes = length; @@ -654,7 +624,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, 0, 0); - ep->dma_counter = DMA_DEST_LAST(ep->lch); + ep->dma_counter = omap_get_dma_dst_pos(ep->lch); UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel); @@ -834,7 +804,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) /* channel type P: hw synch (fifo) */ if (cpu_class_is_omap1() && !cpu_is_omap15xx()) - OMAP1_DMA_LCH_CTRL_REG(ep->lch) = 2; + omap_set_dma_channel_mode(ep->lch, OMAP_DMA_LCH_P); } just_restart: @@ -881,7 +851,7 @@ static void dma_channel_release(struct omap_ep *ep) else req = NULL; - active = ((1 << 7) & OMAP_DMA_CCR_REG(ep->lch)) != 0; + active = omap_get_dma_active_status(ep->lch); DBG("%s release %s %cxdma%d %p\n", ep->ep.name, active ? "active" : "idle", diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h index 46fe5a40a25..d188100f8f4 100644 --- a/include/asm-arm/arch-omap/dma.h +++ b/include/asm-arm/arch-omap/dma.h @@ -22,107 +22,128 @@ #define __ASM_ARCH_DMA_H /* Hardware registers for omap1 */ -#define OMAP_DMA_BASE (0xfffed800) -#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400) -#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404) -#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408) -#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442) -#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444) -#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446) -#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448) -#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a) -#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c) -#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e) -#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450) -#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452) -#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454) -#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456) -#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458) -#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a) -#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460) -#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480) -#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482) -#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0) - -/* Hardware registers for omap2 */ -#if defined(CONFIG_ARCH_OMAP3) -#define OMAP_DMA4_BASE (L4_34XX_BASE + 0x56000) -#else /* CONFIG_ARCH_OMAP2 */ -#define OMAP_DMA4_BASE (L4_24XX_BASE + 0x56000) -#endif - -#define OMAP_DMA4_REVISION (OMAP_DMA4_BASE + 0x00) -#define OMAP_DMA4_GCR_REG (OMAP_DMA4_BASE + 0x78) -#define OMAP_DMA4_IRQSTATUS_L0 (OMAP_DMA4_BASE + 0x08) -#define OMAP_DMA4_IRQSTATUS_L1 (OMAP_DMA4_BASE + 0x0c) -#define OMAP_DMA4_IRQSTATUS_L2 (OMAP_DMA4_BASE + 0x10) -#define OMAP_DMA4_IRQSTATUS_L3 (OMAP_DMA4_BASE + 0x14) -#define OMAP_DMA4_IRQENABLE_L0 (OMAP_DMA4_BASE + 0x18) -#define OMAP_DMA4_IRQENABLE_L1 (OMAP_DMA4_BASE + 0x1c) -#define OMAP_DMA4_IRQENABLE_L2 (OMAP_DMA4_BASE + 0x20) -#define OMAP_DMA4_IRQENABLE_L3 (OMAP_DMA4_BASE + 0x24) -#define OMAP_DMA4_SYSSTATUS (OMAP_DMA4_BASE + 0x28) -#define OMAP_DMA4_OCP_SYSCONFIG (OMAP_DMA4_BASE + 0x2c) -#define OMAP_DMA4_CAPS_0 (OMAP_DMA4_BASE + 0x64) -#define OMAP_DMA4_CAPS_2 (OMAP_DMA4_BASE + 0x6c) -#define OMAP_DMA4_CAPS_3 (OMAP_DMA4_BASE + 0x70) -#define OMAP_DMA4_CAPS_4 (OMAP_DMA4_BASE + 0x74) +#define OMAP1_DMA_BASE (0xfffed800) + +#define OMAP1_DMA_GCR 0x400 +#define OMAP1_DMA_GSCR 0x404 +#define OMAP1_DMA_GRST 0x408 +#define OMAP1_DMA_HW_ID 0x442 +#define OMAP1_DMA_PCH2_ID 0x444 +#define OMAP1_DMA_PCH0_ID 0x446 +#define OMAP1_DMA_PCH1_ID 0x448 +#define OMAP1_DMA_PCHG_ID 0x44a +#define OMAP1_DMA_PCHD_ID 0x44c +#define OMAP1_DMA_CAPS_0_U 0x44e +#define OMAP1_DMA_CAPS_0_L 0x450 +#define OMAP1_DMA_CAPS_1_U 0x452 +#define OMAP1_DMA_CAPS_1_L 0x454 +#define OMAP1_DMA_CAPS_2 0x456 +#define OMAP1_DMA_CAPS_3 0x458 +#define OMAP1_DMA_CAPS_4 0x45a +#define OMAP1_DMA_PCH2_SR 0x460 +#define OMAP1_DMA_PCH0_SR 0x480 +#define OMAP1_DMA_PCH1_SR 0x482 +#define OMAP1_DMA_PCHD_SR 0x4c0 + +/* Hardware registers for omap2 and omap3 */ +#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000) +#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000) + +#define OMAP_DMA4_REVISION 0x00 +#define OMAP_DMA4_GCR 0x78 +#define OMAP_DMA4_IRQSTATUS_L0 0x08 +#define OMAP_DMA4_IRQSTATUS_L1 0x0c +#define OMAP_DMA4_IRQSTATUS_L2 0x10 +#define OMAP_DMA4_IRQSTATUS_L3 0x14 +#define OMAP_DMA4_IRQENABLE_L0 0x18 +#define OMAP_DMA4_IRQENABLE_L1 0x1c +#define OMAP_DMA4_IRQENABLE_L2 0x20 +#define OMAP_DMA4_IRQENABLE_L3 0x24 +#define OMAP_DMA4_SYSSTATUS 0x28 +#define OMAP_DMA4_OCP_SYSCONFIG 0x2c +#define OMAP_DMA4_CAPS_0 0x64 +#define OMAP_DMA4_CAPS_2 0x6c +#define OMAP_DMA4_CAPS_3 0x70 +#define OMAP_DMA4_CAPS_4 0x74 #define OMAP1_LOGICAL_DMA_CH_COUNT 17 #define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */ -#ifdef CONFIG_ARCH_OMAP1 - /* Common channel specific registers for omap1 */ -#define OMAP_DMA_CSDP_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x00) -#define OMAP_DMA_CCR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x02) -#define OMAP_DMA_CICR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x04) -#define OMAP_DMA_CSR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x06) -#define OMAP_DMA_CEN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x10) -#define OMAP_DMA_CFN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x12) -#define OMAP_DMA_CSFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x14) -#define OMAP_DMA_CSEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x16) -#define OMAP_DMA_CSAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x18) -#define OMAP_DMA_CDAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1a) -#define OMAP_DMA_CDEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1c) -#define OMAP_DMA_CDFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1e) -#define OMAP_DMA_CLNK_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x28) - -#else +#define OMAP1_DMA_CH_BASE(n) (0x40 * (n) + 0x00) +#define OMAP1_DMA_CSDP(n) (0x40 * (n) + 0x00) +#define OMAP1_DMA_CCR(n) (0x40 * (n) + 0x02) +#define OMAP1_DMA_CICR(n) (0x40 * (n) + 0x04) +#define OMAP1_DMA_CSR(n) (0x40 * (n) + 0x06) +#define OMAP1_DMA_CEN(n) (0x40 * (n) + 0x10) +#define OMAP1_DMA_CFN(n) (0x40 * (n) + 0x12) +#define OMAP1_DMA_CSFI(n) (0x40 * (n) + 0x14) +#define OMAP1_DMA_CSEI(n) (0x40 * (n) + 0x16) +#define OMAP1_DMA_CPC(n) (0x40 * (n) + 0x18) /* 15xx only */ +#define OMAP1_DMA_CSAC(n) (0x40 * (n) + 0x18) +#define OMAP1_DMA_CDAC(n) (0x40 * (n) + 0x1a) +#define OMAP1_DMA_CDEI(n) (0x40 * (n) + 0x1c) +#define OMAP1_DMA_CDFI(n) (0x40 * (n) + 0x1e) +#define OMAP1_DMA_CLNK_CTRL(n) (0x40 * (n) + 0x28) /* Common channel specific registers for omap2 */ -#define OMAP_DMA_CCR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x80) -#define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x84) -#define OMAP_DMA_CICR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x88) -#define OMAP_DMA_CSR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x8c) -#define OMAP_DMA_CSDP_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x90) -#define OMAP_DMA_CEN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x94) -#define OMAP_DMA_CFN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x98) -#define OMAP_DMA_CSEI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa4) -#define OMAP_DMA_CSFI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa8) -#define OMAP_DMA_CDEI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xac) -#define OMAP_DMA_CDFI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb0) -#define OMAP_DMA_CSAC_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb4) -#define OMAP_DMA_CDAC_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb8) - -#endif +#define OMAP_DMA4_CH_BASE(n) (0x60 * (n) + 0x80) +#define OMAP_DMA4_CCR(n) (0x60 * (n) + 0x80) +#define OMAP_DMA4_CLNK_CTRL(n) (0x60 * (n) + 0x84) +#define OMAP_DMA4_CICR(n) (0x60 * (n) + 0x88) +#define OMAP_DMA4_CSR(n) (0x60 * (n) + 0x8c) +#define OMAP_DMA4_CSDP(n) (0x60 * (n) + 0x90) +#define OMAP_DMA4_CEN(n) (0x60 * (n) + 0x94) +#define OMAP_DMA4_CFN(n) (0x60 * (n) + 0x98) +#define OMAP_DMA4_CSEI(n) (0x60 * (n) + 0xa4) +#define OMAP_DMA4_CSFI(n) (0x60 * (n) + 0xa8) +#define OMAP_DMA4_CDEI(n) (0x60 * (n) + 0xac) +#define OMAP_DMA4_CDFI(n) (0x60 * (n) + 0xb0) +#define OMAP_DMA4_CSAC(n) (0x60 * (n) + 0xb4) +#define OMAP_DMA4_CDAC(n) (0x60 * (n) + 0xb8) /* Channel specific registers only on omap1 */ -#define OMAP1_DMA_CSSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x08) -#define OMAP1_DMA_CSSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0a) -#define OMAP1_DMA_CDSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0c) -#define OMAP1_DMA_CDSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0e) -#define OMAP1_DMA_COLOR_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x20) -#define OMAP1_DMA_CCR2_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x24) -#define OMAP1_DMA_COLOR_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x22) -#define OMAP1_DMA_LCH_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x2a) +#define OMAP1_DMA_CSSA_L(n) (0x40 * (n) + 0x08) +#define OMAP1_DMA_CSSA_U(n) (0x40 * (n) + 0x0a) +#define OMAP1_DMA_CDSA_L(n) (0x40 * (n) + 0x0c) +#define OMAP1_DMA_CDSA_U(n) (0x40 * (n) + 0x0e) +#define OMAP1_DMA_COLOR_L(n) (0x40 * (n) + 0x20) +#define OMAP1_DMA_COLOR_U(n) (0x40 * (n) + 0x22) +#define OMAP1_DMA_CCR2(n) (0x40 * (n) + 0x24) +#define OMAP1_DMA_LCH_CTRL(n) (0x40 * (n) + 0x2a) /* not on 15xx */ +#define OMAP1_DMA_CCEN(n) 0 +#define OMAP1_DMA_CCFN(n) 0 /* Channel specific registers only on omap2 */ -#define OMAP2_DMA_CSSA_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x9c) -#define OMAP2_DMA_CDSA_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa0) -#define OMAP2_DMA_CCEN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xbc) -#define OMAP2_DMA_CCFN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xc0) -#define OMAP2_DMA_COLOR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xc4) +#define OMAP_DMA4_CSSA(n) (0x60 * (n) + 0x9c) +#define OMAP_DMA4_CDSA(n) (0x60 * (n) + 0xa0) +#define OMAP_DMA4_CCEN(n) (0x60 * (n) + 0xbc) +#define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0) +#define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4) + +/* Dummy defines to keep multi-omap compiles happy */ +#define OMAP1_DMA_REVISION 0 +#define OMAP1_DMA_IRQSTATUS_L0 0 +#define OMAP1_DMA_IRQENABLE_L0 0 +#define OMAP1_DMA_OCP_SYSCONFIG 0 +#define OMAP_DMA4_HW_ID 0 +#define OMAP_DMA4_CAPS_0_L 0 +#define OMAP_DMA4_CAPS_0_U 0 +#define OMAP_DMA4_CAPS_1_L 0 +#define OMAP_DMA4_CAPS_1_U 0 +#define OMAP_DMA4_GSCR 0 +#define OMAP_DMA4_CPC(n) 0 + +#define OMAP_DMA4_LCH_CTRL(n) 0 +#define OMAP_DMA4_COLOR_L(n) 0 +#define OMAP_DMA4_COLOR_U(n) 0 +#define OMAP_DMA4_CCR2(n) 0 +#define OMAP1_DMA_CSSA(n) 0 +#define OMAP1_DMA_CDSA(n) 0 +#define OMAP_DMA4_CSSA_L(n) 0 +#define OMAP_DMA4_CSSA_U(n) 0 +#define OMAP_DMA4_CDSA_L(n) 0 +#define OMAP_DMA4_CDSA_U(n) 0 /*----------------------------------------------------------------------------*/ @@ -369,6 +390,13 @@ enum omap_dma_write_mode { OMAP_DMA_WRITE_LAST_NON_POSTED }; +enum omap_dma_channel_mode { + OMAP_DMA_LCH_2D = 0, + OMAP_DMA_LCH_G, + OMAP_DMA_LCH_P, + OMAP_DMA_LCH_PD +}; + struct omap_dma_channel_params { int data_type; /* data type 8,16,32 */ int elem_count; /* number of elements in a frame */ @@ -417,6 +445,7 @@ extern void omap_set_dma_transfer_params(int lch, int data_type, extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color); extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode); +extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode); extern void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start, @@ -447,6 +476,7 @@ extern dma_addr_t omap_get_dma_src_pos(int lch); extern dma_addr_t omap_get_dma_dst_pos(int lch); extern int omap_get_dma_src_addr_counter(int lch); extern void omap_clear_dma(int lch); +extern int omap_get_dma_active_status(int lch); extern int omap_dma_running(void); extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams); -- cgit v1.2.3-70-g09d2 From 97b7f715589fb997e430c6aa824abbd9fd5ed42d Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:37 +0300 Subject: ARM: OMAP: DMA: Clean-up code DMA clean-up, mostly checkpatch.pl fixes. Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 255 +++++++++++++++++++++------------------- include/asm-arm/arch-omap/dma.h | 161 ++++++++++++++++--------- 2 files changed, 235 insertions(+), 181 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 18e757a9ec6..fac8e994f58 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/plat-omap/dma.c * - * Copyright (C) 2003 Nokia Corporation + * Copyright (C) 2003 - 2008 Nokia Corporation * Author: Juha Yrjölä * DMA channel linking for 1610 by Samuel Ortiz * Graphics DMA and LCD DMA graphics tranformations @@ -25,11 +25,11 @@ #include #include #include +#include #include #include #include -#include #include @@ -43,13 +43,13 @@ enum { DMA_CH_ALLOC_DONE, DMA_CH_PARAMS_SET_DONE, DMA_CH_STARTED, enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED }; #endif -#define OMAP_DMA_ACTIVE 0x01 -#define OMAP_DMA_CCR_EN (1 << 7) +#define OMAP_DMA_ACTIVE 0x01 +#define OMAP_DMA_CCR_EN (1 << 7) #define OMAP2_DMA_CSR_CLEAR_MASK 0xffe -#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) +#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) -static int enable_1510_mode = 0; +static int enable_1510_mode; struct omap_dma_lch { int next_lch; @@ -57,7 +57,7 @@ struct omap_dma_lch { u16 saved_csr; u16 enabled_irqs; const char *dev_name; - void (* callback)(int lch, u16 ch_status, void *data); + void (*callback)(int lch, u16 ch_status, void *data); void *data; #ifndef CONFIG_ARCH_OMAP1 @@ -245,6 +245,7 @@ void omap_set_dma_priority(int lch, int dst_port, int priority) dma_write(ccr, CCR(lch)); } } +EXPORT_SYMBOL(omap_set_dma_priority); void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, int frame_count, int sync_mode, @@ -307,6 +308,7 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, dma_write(elem_count, CEN(lch)); dma_write(frame_count, CFN(lch)); } +EXPORT_SYMBOL(omap_set_dma_transfer_params); void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) { @@ -346,6 +348,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) } dma_write(w, LCH_CTRL(lch)); } +EXPORT_SYMBOL(omap_set_dma_color_mode); void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) { @@ -358,6 +361,7 @@ void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) dma_write(csdp, CSDP(lch)); } } +EXPORT_SYMBOL(omap_set_dma_write_mode); void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode) { @@ -377,6 +381,8 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start, int src_ei, int src_fi) { + u32 l; + if (cpu_class_is_omap1()) { u16 w; @@ -384,34 +390,27 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode, w &= ~(0x1f << 2); w |= src_port << 2; dma_write(w, CSDP(lch)); + } - w = dma_read(CCR(lch)); - w &= ~(0x03 << 12); - w |= src_amode << 12; - dma_write(w, CCR(lch)); + l = dma_read(CCR(lch)); + l &= ~(0x03 << 12); + l |= src_amode << 12; + dma_write(l, CCR(lch)); + if (cpu_class_is_omap1()) { dma_write(src_start >> 16, CSSA_U(lch)); dma_write((u16)src_start, CSSA_L(lch)); - - dma_write(src_ei, CSEI(lch)); - dma_write(src_fi, CSFI(lch)); } - if (cpu_class_is_omap2()) { - u32 l; - - l = dma_read(CCR(lch)); - l &= ~(0x03 << 12); - l |= src_amode << 12; - dma_write(l, CCR(lch)); - + if (cpu_class_is_omap2()) dma_write(src_start, CSSA(lch)); - dma_write(src_ei, CSEI(lch)); - dma_write(src_fi, CSFI(lch)); - } + + dma_write(src_ei, CSEI(lch)); + dma_write(src_fi, CSFI(lch)); } +EXPORT_SYMBOL(omap_set_dma_src_params); -void omap_set_dma_params(int lch, struct omap_dma_channel_params * params) +void omap_set_dma_params(int lch, struct omap_dma_channel_params *params) { omap_set_dma_transfer_params(lch, params->data_type, params->elem_count, params->frame_count, @@ -428,16 +427,17 @@ void omap_set_dma_params(int lch, struct omap_dma_channel_params * params) omap_dma_set_prio_lch(lch, params->read_prio, params->write_prio); } +EXPORT_SYMBOL(omap_set_dma_params); void omap_set_dma_src_index(int lch, int eidx, int fidx) { - if (cpu_class_is_omap2()) { - REVISIT_24XX(); + if (cpu_class_is_omap2()) return; - } + dma_write(eidx, CSEI(lch)); dma_write(fidx, CSFI(lch)); } +EXPORT_SYMBOL(omap_set_dma_src_index); void omap_set_dma_src_data_pack(int lch, int enable) { @@ -449,6 +449,7 @@ void omap_set_dma_src_data_pack(int lch, int enable) l |= (1 << 6); dma_write(l, CSDP(lch)); } +EXPORT_SYMBOL(omap_set_dma_src_data_pack); void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) { @@ -491,6 +492,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) l |= (burst << 7); dma_write(l, CSDP(lch)); } +EXPORT_SYMBOL(omap_set_dma_src_burst_mode); /* Note that dest_port is only for OMAP1 */ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, @@ -522,16 +524,17 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, dma_write(dst_ei, CDEI(lch)); dma_write(dst_fi, CDFI(lch)); } +EXPORT_SYMBOL(omap_set_dma_dest_params); void omap_set_dma_dest_index(int lch, int eidx, int fidx) { - if (cpu_class_is_omap2()) { - REVISIT_24XX(); + if (cpu_class_is_omap2()) return; - } + dma_write(eidx, CDEI(lch)); dma_write(fidx, CDFI(lch)); } +EXPORT_SYMBOL(omap_set_dma_dest_index); void omap_set_dma_dest_data_pack(int lch, int enable) { @@ -543,6 +546,7 @@ void omap_set_dma_dest_data_pack(int lch, int enable) l |= 1 << 13; dma_write(l, CSDP(lch)); } +EXPORT_SYMBOL(omap_set_dma_dest_data_pack); void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) { @@ -583,6 +587,7 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) l |= (burst << 14); dma_write(l, CSDP(lch)); } +EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); static inline void omap_enable_channel_irq(int lch) { @@ -608,11 +613,13 @@ void omap_enable_dma_irq(int lch, u16 bits) { dma_chan[lch].enabled_irqs |= bits; } +EXPORT_SYMBOL(omap_enable_dma_irq); void omap_disable_dma_irq(int lch, u16 bits) { dma_chan[lch].enabled_irqs &= ~bits; } +EXPORT_SYMBOL(omap_disable_dma_irq); static inline void enable_lnk(int lch) { @@ -628,8 +635,9 @@ static inline void enable_lnk(int lch) l = dma_chan[lch].next_lch | (1 << 15); #ifndef CONFIG_ARCH_OMAP1 - if (dma_chan[lch].next_linked_ch != -1) - l = dma_chan[lch].next_linked_ch | (1 << 15); + if (cpu_class_is_omap2()) + if (dma_chan[lch].next_linked_ch != -1) + l = dma_chan[lch].next_linked_ch | (1 << 15); #endif dma_write(l, CLNK_CTRL(lch)); @@ -671,7 +679,7 @@ static inline void omap2_enable_irq_lch(int lch) } int omap_request_dma(int dev_id, const char *dev_name, - void (* callback)(int lch, u16 ch_status, void *data), + void (*callback)(int lch, u16 ch_status, void *data), void *data, int *dma_ch_out) { int ch, free_ch = -1; @@ -704,10 +712,14 @@ int omap_request_dma(int dev_id, const char *dev_name, chan->dev_name = dev_name; chan->callback = callback; chan->data = data; + #ifndef CONFIG_ARCH_OMAP1 - chan->chain_id = -1; - chan->next_linked_ch = -1; + if (cpu_class_is_omap2()) { + chan->chain_id = -1; + chan->next_linked_ch = -1; + } #endif + chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ; if (cpu_class_is_omap1()) @@ -722,8 +734,10 @@ int omap_request_dma(int dev_id, const char *dev_name, set_gdma_dev(free_ch + 1, dev_id); dev_id = free_ch + 1; } - /* Disable the 1510 compatibility mode and set the sync device - * id. */ + /* + * Disable the 1510 compatibility mode and set the sync device + * id. + */ dma_write(dev_id | (1 << 10), CCR(free_ch)); } else if (cpu_is_omap730() || cpu_is_omap15xx()) { dma_write(dev_id, CCR(free_ch)); @@ -731,7 +745,6 @@ int omap_request_dma(int dev_id, const char *dev_name, if (cpu_class_is_omap2()) { omap2_enable_irq_lch(free_ch); - omap_enable_channel_irq(free_ch); /* Clear the CSR register and IRQ status register */ dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(free_ch)); @@ -742,6 +755,7 @@ int omap_request_dma(int dev_id, const char *dev_name, return 0; } +EXPORT_SYMBOL(omap_request_dma); void omap_free_dma(int lch) { @@ -749,11 +763,12 @@ void omap_free_dma(int lch) spin_lock_irqsave(&dma_chan_lock, flags); if (dma_chan[lch].dev_id == -1) { - printk("omap_dma: trying to free nonallocated DMA channel %d\n", + pr_err("omap_dma: trying to free unallocated DMA channel %d\n", lch); spin_unlock_irqrestore(&dma_chan_lock, flags); return; } + dma_chan[lch].dev_id = -1; dma_chan[lch].next_lch = -1; dma_chan[lch].callback = NULL; @@ -785,6 +800,7 @@ void omap_free_dma(int lch) omap_clear_dma(lch); } } +EXPORT_SYMBOL(omap_free_dma); /** * @brief omap_dma_set_global_params : Set global priority settings for dma @@ -878,6 +894,7 @@ void omap_clear_dma(int lch) local_irq_restore(flags); } +EXPORT_SYMBOL(omap_clear_dma); void omap_start_dma(int lch) { @@ -916,8 +933,10 @@ void omap_start_dma(int lch) l = dma_read(CCR(lch)); - /* Errata: On ES2.0 BUFFERING disable must be set. - * This will always fail on ES1.0 */ + /* + * Errata: On ES2.0 BUFFERING disable must be set. + * This will always fail on ES1.0 + */ if (cpu_is_omap24xx()) l |= OMAP_DMA_CCR_EN; @@ -926,6 +945,7 @@ void omap_start_dma(int lch) dma_chan[lch].flags |= OMAP_DMA_ACTIVE; } +EXPORT_SYMBOL(omap_start_dma); void omap_stop_dma(int lch) { @@ -962,13 +982,14 @@ void omap_stop_dma(int lch) dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; } +EXPORT_SYMBOL(omap_stop_dma); /* * Allows changing the DMA callback function or data. This may be needed if * the driver shares a single DMA channel for multiple dma triggers. */ int omap_set_dma_callback(int lch, - void (* callback)(int lch, u16 ch_status, void *data), + void (*callback)(int lch, u16 ch_status, void *data), void *data) { unsigned long flags; @@ -988,6 +1009,7 @@ int omap_set_dma_callback(int lch, return 0; } +EXPORT_SYMBOL(omap_set_dma_callback); /* * Returns current physical source address for the given DMA channel. @@ -1018,6 +1040,7 @@ dma_addr_t omap_get_dma_src_pos(int lch) return offset; } +EXPORT_SYMBOL(omap_get_dma_src_pos); /* * Returns current physical destination address for the given DMA channel. @@ -1048,16 +1071,7 @@ dma_addr_t omap_get_dma_dst_pos(int lch) return offset; } - -/* - * Returns current source transfer counting for the given DMA channel. - * Can be used to monitor the progress of a transfer inside a block. - * It must be called with disabled interrupts. - */ -int omap_get_dma_src_addr_counter(int lch) -{ - return (dma_addr_t)dma_read(CSAC(lch)); -} +EXPORT_SYMBOL(omap_get_dma_dst_pos); int omap_get_dma_active_status(int lch) { @@ -1086,7 +1100,7 @@ int omap_dma_running(void) * For this DMA link to start, you still need to start (see omap_start_dma) * the first one. That will fire up the entire queue. */ -void omap_dma_link_lch (int lch_head, int lch_queue) +void omap_dma_link_lch(int lch_head, int lch_queue) { if (omap_dma_in_1510_mode()) { printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); @@ -1103,11 +1117,12 @@ void omap_dma_link_lch (int lch_head, int lch_queue) dma_chan[lch_head].next_lch = lch_queue; } +EXPORT_SYMBOL(omap_dma_link_lch); /* * Once the DMA queue is stopped, we can destroy it. */ -void omap_dma_unlink_lch (int lch_head, int lch_queue) +void omap_dma_unlink_lch(int lch_head, int lch_queue) { if (omap_dma_in_1510_mode()) { printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); @@ -1122,7 +1137,6 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue) dump_stack(); } - if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) || (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) { printk(KERN_ERR "omap_dma: You need to stop the DMA channels " @@ -1132,6 +1146,9 @@ void omap_dma_unlink_lch (int lch_head, int lch_queue) dma_chan[lch_head].next_lch = -1; } +EXPORT_SYMBOL(omap_dma_unlink_lch); + +/*----------------------------------------------------------------------------*/ #ifndef CONFIG_ARCH_OMAP1 /* Create chain of DMA channesls */ @@ -1255,6 +1272,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name, for (i = 0; i < (no_of_chans - 1); i++) create_dma_lch_chain(channels[i], channels[i + 1]); } + return 0; } EXPORT_SYMBOL(omap_request_dma_chain); @@ -1297,6 +1315,7 @@ int omap_modify_dma_chain_params(int chain_id, */ omap_set_dma_params(channels[i], ¶ms); } + return 0; } EXPORT_SYMBOL(omap_modify_dma_chain_params); @@ -1340,6 +1359,7 @@ int omap_free_dma_chain(int chain_id) dma_linked_lch[chain_id].linked_dmach_q = NULL; dma_linked_lch[chain_id].chain_mode = -1; dma_linked_lch[chain_id].chain_state = -1; + return (0); } EXPORT_SYMBOL(omap_free_dma_chain); @@ -1370,6 +1390,7 @@ int omap_dma_chain_status(int chain_id) if (OMAP_DMA_CHAIN_QEMPTY(chain_id)) return OMAP_DMA_CHAIN_INACTIVE; + return OMAP_DMA_CHAIN_ACTIVE; } EXPORT_SYMBOL(omap_dma_chain_status); @@ -1395,8 +1416,10 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, u32 l, lch; int start_dma = 0; - /* if buffer size is less than 1 then there is - * no use of starting the chain */ + /* + * if buffer size is less than 1 then there is + * no use of starting the chain + */ if (elem_count < 1) { printk(KERN_ERR "Invalid buffer size\n"); return -EINVAL; @@ -1441,12 +1464,16 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, dma_write(elem_count, CEN(lch)); dma_write(frame_count, CFN(lch)); - /* If the chain is dynamically linked, - * then we may have to start the chain if its not active */ + /* + * If the chain is dynamically linked, + * then we may have to start the chain if its not active + */ if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_DYNAMIC_CHAIN) { - /* In Dynamic chain, if the chain is not started, - * queue the channel */ + /* + * In Dynamic chain, if the chain is not started, + * queue the channel + */ if (dma_linked_lch[chain_id].chain_state == DMA_CHAIN_NOTSTARTED) { /* Enable the link in previous channel */ @@ -1456,8 +1483,10 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, dma_chan[lch].state = DMA_CH_QUEUED; } - /* Chain is already started, make sure its active, - * if not then start the chain */ + /* + * Chain is already started, make sure its active, + * if not then start the chain + */ else { start_dma = 1; @@ -1504,6 +1533,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, dma_chan[lch].flags |= OMAP_DMA_ACTIVE; } } + return 0; } EXPORT_SYMBOL(omap_dma_chain_a_transfer); @@ -1555,6 +1585,7 @@ int omap_start_dma_chain_transfers(int chain_id) dma_write(l, CCR(channels[0])); dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE; + return 0; } EXPORT_SYMBOL(omap_start_dma_chain_transfers); @@ -1586,7 +1617,8 @@ int omap_stop_dma_chain_transfers(int chain_id) } channels = dma_linked_lch[chain_id].linked_dmach_q; - /* DMA Errata: + /* + * DMA Errata: * Special programming model needed to disable DMA before end of block */ sys_cf = dma_read(OCP_SYSCONFIG); @@ -1614,6 +1646,7 @@ int omap_stop_dma_chain_transfers(int chain_id) /* Errata - put in the old value */ dma_write(sys_cf, OCP_SYSCONFIG); + return 0; } EXPORT_SYMBOL(omap_stop_dma_chain_transfers); @@ -1729,7 +1762,7 @@ int omap_get_dma_chain_src_pos(int chain_id) return dma_read(CSAC(lch)); } EXPORT_SYMBOL(omap_get_dma_chain_src_pos); -#endif +#endif /* ifndef CONFIG_ARCH_OMAP1 */ /*----------------------------------------------------------------------------*/ @@ -1765,6 +1798,7 @@ static int omap1_dma_handle_ch(int ch) dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE; if (likely(dma_chan[ch].callback != NULL)) dma_chan[ch].callback(ch, csr, dma_chan[ch].data); + return 1; } @@ -1799,7 +1833,8 @@ static int omap2_dma_handle_ch(int ch) if (!status) { if (printk_ratelimit()) - printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", ch); + printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", + ch); dma_write(1 << ch, IRQSTATUS_L0); return 0; } @@ -1887,7 +1922,7 @@ static struct irqaction omap24xx_dma_irq; static struct lcd_dma_info { spinlock_t lock; int reserved; - void (* callback)(u16 status, void *data); + void (*callback)(u16 status, void *data); void *cb_data; int active; @@ -1909,6 +1944,7 @@ void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres, lcd_dma.xres = fb_xres; lcd_dma.yres = fb_yres; } +EXPORT_SYMBOL(omap_set_lcd_dma_b1); void omap_set_lcd_dma_src_port(int port) { @@ -1919,12 +1955,13 @@ void omap_set_lcd_dma_ext_controller(int external) { lcd_dma.ext_ctrl = external; } +EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); void omap_set_lcd_dma_single_transfer(int single) { lcd_dma.single_transfer = single; } - +EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); void omap_set_lcd_dma_b1_rotation(int rotate) { @@ -1935,6 +1972,7 @@ void omap_set_lcd_dma_b1_rotation(int rotate) } lcd_dma.rotate = rotate; } +EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation); void omap_set_lcd_dma_b1_mirror(int mirror) { @@ -1944,6 +1982,7 @@ void omap_set_lcd_dma_b1_mirror(int mirror) } lcd_dma.mirror = mirror; } +EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror); void omap_set_lcd_dma_b1_vxres(unsigned long vxres) { @@ -1954,6 +1993,7 @@ void omap_set_lcd_dma_b1_vxres(unsigned long vxres) } lcd_dma.vxres = vxres; } +EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres); void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale) { @@ -1964,6 +2004,7 @@ void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale) lcd_dma.xscale = xscale; lcd_dma.yscale = yscale; } +EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale); static void set_b1_regs(void) { @@ -1994,8 +2035,11 @@ static void set_b1_regs(void) xscale = lcd_dma.xscale ? lcd_dma.xscale : 1; yscale = lcd_dma.yscale ? lcd_dma.yscale : 1; BUG_ON(vxres < lcd_dma.xres); -#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es) + +#define PIXADDR(x, y) (lcd_dma.addr + \ + ((y) * vxres * yscale + (x) * xscale) * es) #define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1) + switch (lcd_dma.rotate) { case 0: if (!lcd_dma.mirror) { @@ -2004,8 +2048,8 @@ static void set_b1_regs(void) /* 1510 DMA requires the bottom address to be 2 more * than the actual last memory access location. */ if (omap_dma_in_1510_mode() && - lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32) - bottom += 2; + lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32) + bottom += 2; ei = PIXSTEP(0, 0, 1, 0); fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1); } else { @@ -2132,7 +2176,7 @@ static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -int omap_request_lcd_dma(void (* callback)(u16 status, void *data), +int omap_request_lcd_dma(void (*callback)(u16 status, void *data), void *data) { spin_lock_irq(&lcd_dma.lock); @@ -2158,6 +2202,7 @@ int omap_request_lcd_dma(void (* callback)(u16 status, void *data), return 0; } +EXPORT_SYMBOL(omap_request_lcd_dma); void omap_free_lcd_dma(void) { @@ -2174,12 +2219,14 @@ void omap_free_lcd_dma(void) lcd_dma.reserved = 0; spin_unlock(&lcd_dma.lock); } +EXPORT_SYMBOL(omap_free_lcd_dma); void omap_enable_lcd_dma(void) { u16 w; - /* Set the Enable bit only if an external controller is + /* + * Set the Enable bit only if an external controller is * connected. Otherwise the OMAP internal controller will * start the transfer when it gets enabled. */ @@ -2196,6 +2243,7 @@ void omap_enable_lcd_dma(void) w |= 1 << 7; omap_writew(w, OMAP1610_DMA_LCD_CCR); } +EXPORT_SYMBOL(omap_enable_lcd_dma); void omap_setup_lcd_dma(void) { @@ -2211,16 +2259,18 @@ void omap_setup_lcd_dma(void) u16 w; w = omap_readw(OMAP1610_DMA_LCD_CCR); - /* If DMA was already active set the end_prog bit to have + /* + * If DMA was already active set the end_prog bit to have * the programmed register set loaded into the active * register set. */ w |= 1 << 11; /* End_prog */ if (!lcd_dma.single_transfer) - w |= (3 << 8); /* Auto_init, repeat */ + w |= (3 << 8); /* Auto_init, repeat */ omap_writew(w, OMAP1610_DMA_LCD_CCR); } } +EXPORT_SYMBOL(omap_setup_lcd_dma); void omap_stop_lcd_dma(void) { @@ -2238,6 +2288,7 @@ void omap_stop_lcd_dma(void) w &= ~(1 << 8); omap_writew(w, OMAP1610_DMA_LCD_CTRL); } +EXPORT_SYMBOL(omap_stop_lcd_dma); /*----------------------------------------------------------------------------*/ @@ -2327,8 +2378,10 @@ static int __init omap_init_dma(void) continue; if (cpu_class_is_omap1()) { - /* request_irq() doesn't like dev_id (ie. ch) being - * zero, so we have to kludge around this. */ + /* + * request_irq() doesn't like dev_id (ie. ch) being + * zero, so we have to kludge around this. + */ r = request_irq(omap1_dma_irq[ch], omap1_dma_irq_handler, 0, "DMA", (void *) (ch + 1)); @@ -2373,48 +2426,4 @@ static int __init omap_init_dma(void) arch_initcall(omap_init_dma); -EXPORT_SYMBOL(omap_get_dma_src_pos); -EXPORT_SYMBOL(omap_get_dma_dst_pos); -EXPORT_SYMBOL(omap_get_dma_src_addr_counter); -EXPORT_SYMBOL(omap_clear_dma); -EXPORT_SYMBOL(omap_set_dma_priority); -EXPORT_SYMBOL(omap_request_dma); -EXPORT_SYMBOL(omap_free_dma); -EXPORT_SYMBOL(omap_start_dma); -EXPORT_SYMBOL(omap_stop_dma); -EXPORT_SYMBOL(omap_set_dma_callback); -EXPORT_SYMBOL(omap_enable_dma_irq); -EXPORT_SYMBOL(omap_disable_dma_irq); - -EXPORT_SYMBOL(omap_set_dma_transfer_params); -EXPORT_SYMBOL(omap_set_dma_color_mode); -EXPORT_SYMBOL(omap_set_dma_write_mode); - -EXPORT_SYMBOL(omap_set_dma_src_params); -EXPORT_SYMBOL(omap_set_dma_src_index); -EXPORT_SYMBOL(omap_set_dma_src_data_pack); -EXPORT_SYMBOL(omap_set_dma_src_burst_mode); - -EXPORT_SYMBOL(omap_set_dma_dest_params); -EXPORT_SYMBOL(omap_set_dma_dest_index); -EXPORT_SYMBOL(omap_set_dma_dest_data_pack); -EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); - -EXPORT_SYMBOL(omap_set_dma_params); - -EXPORT_SYMBOL(omap_dma_link_lch); -EXPORT_SYMBOL(omap_dma_unlink_lch); - -EXPORT_SYMBOL(omap_request_lcd_dma); -EXPORT_SYMBOL(omap_free_lcd_dma); -EXPORT_SYMBOL(omap_enable_lcd_dma); -EXPORT_SYMBOL(omap_setup_lcd_dma); -EXPORT_SYMBOL(omap_stop_lcd_dma); -EXPORT_SYMBOL(omap_set_lcd_dma_b1); -EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); -EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); -EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation); -EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres); -EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale); -EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror); diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h index d188100f8f4..f4dcb958786 100644 --- a/include/asm-arm/arch-omap/dma.h +++ b/include/asm-arm/arch-omap/dma.h @@ -216,63 +216,98 @@ #define OMAP24XX_DMA_GPMC 4 /* S_DMA_3 */ #define OMAP24XX_DMA_GFX 5 /* S_DMA_4 */ #define OMAP24XX_DMA_DSS 6 /* S_DMA_5 */ -#define OMAP24XX_DMA_VLYNQ_TX 7 /* S_DMA_6 */ +#define OMAP242X_DMA_VLYNQ_TX 7 /* S_DMA_6 */ +#define OMAP24XX_DMA_EXT_DMAREQ2 7 /* S_DMA_6 */ #define OMAP24XX_DMA_CWT 8 /* S_DMA_7 */ #define OMAP24XX_DMA_AES_TX 9 /* S_DMA_8 */ #define OMAP24XX_DMA_AES_RX 10 /* S_DMA_9 */ #define OMAP24XX_DMA_DES_TX 11 /* S_DMA_10 */ #define OMAP24XX_DMA_DES_RX 12 /* S_DMA_11 */ #define OMAP24XX_DMA_SHA1MD5_RX 13 /* S_DMA_12 */ -#define OMAP24XX_DMA_EXT_DMAREQ2 14 /* S_DMA_13 */ -#define OMAP24XX_DMA_EXT_DMAREQ3 15 /* S_DMA_14 */ -#define OMAP24XX_DMA_EXT_DMAREQ4 16 /* S_DMA_15 */ -#define OMAP24XX_DMA_EAC_AC_RD 17 /* S_DMA_16 */ -#define OMAP24XX_DMA_EAC_AC_WR 18 /* S_DMA_17 */ -#define OMAP24XX_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */ -#define OMAP24XX_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */ -#define OMAP24XX_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */ -#define OMAP24XX_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */ -#define OMAP24XX_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */ -#define OMAP24XX_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */ -#define OMAP24XX_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */ -#define OMAP24XX_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */ +#define OMAP34XX_DMA_SHA2MD5_RX 13 /* S_DMA_12 */ +#define OMAP242X_DMA_EXT_DMAREQ2 14 /* S_DMA_13 */ +#define OMAP242X_DMA_EXT_DMAREQ3 15 /* S_DMA_14 */ +#define OMAP242X_DMA_EXT_DMAREQ4 16 /* S_DMA_15 */ +#define OMAP242X_DMA_EAC_AC_RD 17 /* S_DMA_16 */ +#define OMAP242X_DMA_EAC_AC_WR 18 /* S_DMA_17 */ +#define OMAP242X_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */ +#define OMAP242X_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */ +#define OMAP242X_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */ +#define OMAP242X_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */ +#define OMAP242X_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */ +#define OMAP242X_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */ +#define OMAP242X_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */ +#define OMAP242X_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */ +#define OMAP243X_DMA_EXT_DMAREQ3 14 /* S_DMA_13 */ +#define OMAP24XX_DMA_SPI3_TX0 15 /* S_DMA_14 */ +#define OMAP24XX_DMA_SPI3_RX0 16 /* S_DMA_15 */ +#define OMAP24XX_DMA_MCBSP3_TX 17 /* S_DMA_16 */ +#define OMAP24XX_DMA_MCBSP3_RX 18 /* S_DMA_17 */ +#define OMAP24XX_DMA_MCBSP4_TX 19 /* S_DMA_18 */ +#define OMAP24XX_DMA_MCBSP4_RX 20 /* S_DMA_19 */ +#define OMAP24XX_DMA_MCBSP5_TX 21 /* S_DMA_20 */ +#define OMAP24XX_DMA_MCBSP5_RX 22 /* S_DMA_21 */ +#define OMAP24XX_DMA_SPI3_TX1 23 /* S_DMA_22 */ +#define OMAP24XX_DMA_SPI3_RX1 24 /* S_DMA_23 */ +#define OMAP243X_DMA_EXT_DMAREQ4 25 /* S_DMA_24 */ +#define OMAP243X_DMA_EXT_DMAREQ5 26 /* S_DMA_25 */ +#define OMAP34XX_DMA_I2C3_TX 25 /* S_DMA_24 */ +#define OMAP34XX_DMA_I2C3_RX 26 /* S_DMA_25 */ #define OMAP24XX_DMA_I2C1_TX 27 /* S_DMA_26 */ #define OMAP24XX_DMA_I2C1_RX 28 /* S_DMA_27 */ #define OMAP24XX_DMA_I2C2_TX 29 /* S_DMA_28 */ #define OMAP24XX_DMA_I2C2_RX 30 /* S_DMA_29 */ -#define OMAP24XX_DMA_MCBSP1_TX 31 /* SDMA_30 */ -#define OMAP24XX_DMA_MCBSP1_RX 32 /* SDMA_31 */ -#define OMAP24XX_DMA_MCBSP2_TX 33 /* SDMA_32 */ -#define OMAP24XX_DMA_MCBSP2_RX 34 /* SDMA_33 */ -#define OMAP24XX_DMA_SPI1_TX0 35 /* SDMA_34 */ -#define OMAP24XX_DMA_SPI1_RX0 36 /* SDMA_35 */ -#define OMAP24XX_DMA_SPI1_TX1 37 /* SDMA_36 */ -#define OMAP24XX_DMA_SPI1_RX1 38 /* SDMA_37 */ -#define OMAP24XX_DMA_SPI1_TX2 39 /* SDMA_38 */ -#define OMAP24XX_DMA_SPI1_RX2 40 /* SDMA_39 */ -#define OMAP24XX_DMA_SPI1_TX3 41 /* SDMA_40 */ -#define OMAP24XX_DMA_SPI1_RX3 42 /* SDMA_41 */ -#define OMAP24XX_DMA_SPI2_TX0 43 /* SDMA_42 */ -#define OMAP24XX_DMA_SPI2_RX0 44 /* SDMA_43 */ -#define OMAP24XX_DMA_SPI2_TX1 45 /* SDMA_44 */ -#define OMAP24XX_DMA_SPI2_RX1 46 /* SDMA_45 */ - -#define OMAP24XX_DMA_UART1_TX 49 /* SDMA_48 */ -#define OMAP24XX_DMA_UART1_RX 50 /* SDMA_49 */ -#define OMAP24XX_DMA_UART2_TX 51 /* SDMA_50 */ -#define OMAP24XX_DMA_UART2_RX 52 /* SDMA_51 */ -#define OMAP24XX_DMA_UART3_TX 53 /* SDMA_52 */ -#define OMAP24XX_DMA_UART3_RX 54 /* SDMA_53 */ -#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* SDMA_54 */ -#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* SDMA_55 */ -#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* SDMA_56 */ -#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* SDMA_57 */ -#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* SDMA_58 */ -#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* SDMA_59 */ -#define OMAP24XX_DMA_MMC1_TX 61 /* SDMA_60 */ -#define OMAP24XX_DMA_MMC1_RX 62 /* SDMA_61 */ -#define OMAP24XX_DMA_MS 63 /* SDMA_62 */ -#define OMAP24XX_DMA_EXT_DMAREQ5 64 /* S_DMA_63 */ +#define OMAP24XX_DMA_MCBSP1_TX 31 /* S_DMA_30 */ +#define OMAP24XX_DMA_MCBSP1_RX 32 /* S_DMA_31 */ +#define OMAP24XX_DMA_MCBSP2_TX 33 /* S_DMA_32 */ +#define OMAP24XX_DMA_MCBSP2_RX 34 /* S_DMA_33 */ +#define OMAP24XX_DMA_SPI1_TX0 35 /* S_DMA_34 */ +#define OMAP24XX_DMA_SPI1_RX0 36 /* S_DMA_35 */ +#define OMAP24XX_DMA_SPI1_TX1 37 /* S_DMA_36 */ +#define OMAP24XX_DMA_SPI1_RX1 38 /* S_DMA_37 */ +#define OMAP24XX_DMA_SPI1_TX2 39 /* S_DMA_38 */ +#define OMAP24XX_DMA_SPI1_RX2 40 /* S_DMA_39 */ +#define OMAP24XX_DMA_SPI1_TX3 41 /* S_DMA_40 */ +#define OMAP24XX_DMA_SPI1_RX3 42 /* S_DMA_41 */ +#define OMAP24XX_DMA_SPI2_TX0 43 /* S_DMA_42 */ +#define OMAP24XX_DMA_SPI2_RX0 44 /* S_DMA_43 */ +#define OMAP24XX_DMA_SPI2_TX1 45 /* S_DMA_44 */ +#define OMAP24XX_DMA_SPI2_RX1 46 /* S_DMA_45 */ +#define OMAP24XX_DMA_MMC2_TX 47 /* S_DMA_46 */ +#define OMAP24XX_DMA_MMC2_RX 48 /* S_DMA_47 */ +#define OMAP24XX_DMA_UART1_TX 49 /* S_DMA_48 */ +#define OMAP24XX_DMA_UART1_RX 50 /* S_DMA_49 */ +#define OMAP24XX_DMA_UART2_TX 51 /* S_DMA_50 */ +#define OMAP24XX_DMA_UART2_RX 52 /* S_DMA_51 */ +#define OMAP24XX_DMA_UART3_TX 53 /* S_DMA_52 */ +#define OMAP24XX_DMA_UART3_RX 54 /* S_DMA_53 */ +#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* S_DMA_54 */ +#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* S_DMA_55 */ +#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* S_DMA_56 */ +#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* S_DMA_57 */ +#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* S_DMA_58 */ +#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* S_DMA_59 */ +#define OMAP24XX_DMA_MMC1_TX 61 /* S_DMA_60 */ +#define OMAP24XX_DMA_MMC1_RX 62 /* S_DMA_61 */ +#define OMAP24XX_DMA_MS 63 /* S_DMA_62 */ +#define OMAP242X_DMA_EXT_DMAREQ5 64 /* S_DMA_63 */ +#define OMAP243X_DMA_EXT_DMAREQ6 64 /* S_DMA_63 */ +#define OMAP34XX_DMA_EXT_DMAREQ3 64 /* S_DMA_63 */ +#define OMAP34XX_DMA_AES2_TX 65 /* S_DMA_64 */ +#define OMAP34XX_DMA_AES2_RX 66 /* S_DMA_65 */ +#define OMAP34XX_DMA_DES2_TX 67 /* S_DMA_66 */ +#define OMAP34XX_DMA_DES2_RX 68 /* S_DMA_67 */ +#define OMAP34XX_DMA_SHA1MD5_RX 69 /* S_DMA_68 */ +#define OMAP34XX_DMA_SPI4_TX0 70 /* S_DMA_69 */ +#define OMAP34XX_DMA_SPI4_RX0 71 /* S_DMA_70 */ +#define OMAP34XX_DSS_DMA0 72 /* S_DMA_71 */ +#define OMAP34XX_DSS_DMA1 73 /* S_DMA_72 */ +#define OMAP34XX_DSS_DMA2 74 /* S_DMA_73 */ +#define OMAP34XX_DSS_DMA3 75 /* S_DMA_74 */ +#define OMAP34XX_DMA_MMC3_TX 77 /* S_DMA_76 */ +#define OMAP34XX_DMA_MMC3_RX 78 /* S_DMA_77 */ +#define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */ +#define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */ /*----------------------------------------------------------------------------*/ @@ -378,6 +413,11 @@ enum omap_dma_burst_mode { OMAP_DMA_DATA_BURST_16, }; +enum end_type { + OMAP_DMA_LITTLE_ENDIAN = 0, + OMAP_DMA_BIG_ENDIAN +}; + enum omap_dma_color_mode { OMAP_DMA_COLOR_DIS = 0, OMAP_DMA_CONSTANT_FILL, @@ -403,18 +443,21 @@ struct omap_dma_channel_params { int frame_count; /* number of frames in a element */ int src_port; /* Only on OMAP1 REVISIT: Is this needed? */ - int src_amode; /* constant , post increment, indexed , double indexed */ + int src_amode; /* constant, post increment, indexed, + double indexed */ unsigned long src_start; /* source address : physical */ int src_ei; /* source element index */ int src_fi; /* source frame index */ int dst_port; /* Only on OMAP1 REVISIT: Is this needed? */ - int dst_amode; /* constant , post increment, indexed , double indexed */ + int dst_amode; /* constant, post increment, indexed, + double indexed */ unsigned long dst_start; /* source address : physical */ int dst_ei; /* source element index */ int dst_fi; /* source frame index */ - int trigger; /* trigger attached if the channel is synchronized */ + int trigger; /* trigger attached if the channel is + synchronized */ int sync_mode; /* sycn on element, frame , block or packet */ int src_or_dst_synch; /* source synch(1) or destination synch(0) */ @@ -431,8 +474,8 @@ struct omap_dma_channel_params { extern void omap_set_dma_priority(int lch, int dst_port, int priority); extern int omap_request_dma(int dev_id, const char *dev_name, - void (* callback)(int lch, u16 ch_status, void *data), - void *data, int *dma_ch); + void (*callback)(int lch, u16 ch_status, void *data), + void *data, int *dma_ch); extern void omap_enable_dma_irq(int ch, u16 irq_bits); extern void omap_disable_dma_irq(int ch, u16 irq_bits); extern void omap_free_dma(int ch); @@ -464,17 +507,16 @@ extern void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode); extern void omap_set_dma_params(int lch, - struct omap_dma_channel_params * params); + struct omap_dma_channel_params *params); -extern void omap_dma_link_lch (int lch_head, int lch_queue); -extern void omap_dma_unlink_lch (int lch_head, int lch_queue); +extern void omap_dma_link_lch(int lch_head, int lch_queue); +extern void omap_dma_unlink_lch(int lch_head, int lch_queue); extern int omap_set_dma_callback(int lch, - void (* callback)(int lch, u16 ch_status, void *data), + void (*callback)(int lch, u16 ch_status, void *data), void *data); extern dma_addr_t omap_get_dma_src_pos(int lch); extern dma_addr_t omap_get_dma_dst_pos(int lch); -extern int omap_get_dma_src_addr_counter(int lch); extern void omap_clear_dma(int lch); extern int omap_get_dma_active_status(int lch); extern int omap_dma_running(void); @@ -482,6 +524,9 @@ extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams); extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio, unsigned char write_prio); +extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype); +extern void omap_set_dma_src_endian_type(int lch, enum end_type etype); +extern int omap_get_dma_index(int lch, int *ei, int *fi); /* Chaining APIs */ #ifndef CONFIG_ARCH_OMAP1 @@ -507,7 +552,7 @@ extern int omap_dma_chain_status(int chain_id); #endif /* LCD DMA functions */ -extern int omap_request_lcd_dma(void (* callback)(u16 status, void *data), +extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data), void *data); extern void omap_free_lcd_dma(void); extern void omap_setup_lcd_dma(void); -- cgit v1.2.3-70-g09d2 From c2d43e39c7c303db53facd0bea44b66f263e3f35 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:38 +0300 Subject: ARM: OMAP: SRAM: Split sram24xx.S into sram242x.S and sram243x.S Split sram24xx.S into sram242x.S and sram243x.S Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/sram.S | 6 +- arch/arm/mach-omap2/Makefile | 6 +- arch/arm/mach-omap2/clock.c | 3 +- arch/arm/mach-omap2/prcm-common.h | 1 + arch/arm/mach-omap2/prm.h | 18 ++- arch/arm/mach-omap2/sram242x.S | 105 ++++++------- arch/arm/mach-omap2/sram243x.S | 321 ++++++++++++++++++++++++++++++++++++++ arch/arm/plat-omap/sram.c | 211 ++++++++++++++++++++----- include/asm-arm/arch-omap/sram.h | 37 +++-- 9 files changed, 604 insertions(+), 104 deletions(-) create mode 100644 arch/arm/mach-omap2/sram243x.S (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap1/sram.S b/arch/arm/mach-omap1/sram.S index 9e1813c77e0..126d252062d 100644 --- a/arch/arm/mach-omap1/sram.S +++ b/arch/arm/mach-omap1/sram.S @@ -18,7 +18,7 @@ /* * Reprograms ULPD and CKCTL. */ -ENTRY(sram_reprogram_clock) +ENTRY(omap1_sram_reprogram_clock) stmfd sp!, {r0 - r12, lr} @ save registers on stack mov r2, #IO_ADDRESS(DPLL_CTL) & 0xff000000 @@ -53,5 +53,5 @@ lock: ldrh r4, [r2], #0 @ read back dpll value out: ldmfd sp!, {r0 - r12, pc} @ restore regs and return -ENTRY(sram_reprogram_clock_sz) - .word . - sram_reprogram_clock +ENTRY(omap1_sram_reprogram_clock_sz) + .word . - omap1_sram_reprogram_clock diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 6c59b267105..c2477428e35 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -3,9 +3,13 @@ # # Common support -obj-y := irq.o id.o io.o sram242x.o memory.o control.o prcm.o clock.o mux.o \ +obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ devices.o serial.o gpmc.o timer-gp.o +# Functions loaded to SRAM +obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o +obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o + # Power Management obj-$(CONFIG_PM) += pm.o sleep.o diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index ab9fc57d25f..0243480e8bf 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -603,7 +603,8 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) clk->rate = clk->parent->rate / new_div; if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { - __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL); + prm_write_mod_reg(OMAP24XX_VALID_CONFIG, + OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET); wmb(); } diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index cacb34086e3..54c32f48213 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -32,6 +32,7 @@ /* Chip-specific module offsets */ +#define OMAP24XX_GR_MOD OCP_MOD #define OMAP24XX_DSP_MOD 0x800 #define OMAP2430_MDM_MOD 0xc00 diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 618f8111658..dcdb35bfa0c 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -38,13 +38,29 @@ * */ +/* Global 24xx registers in GR_MOD (Same as OCP_MOD for 24xx) */ +#define OMAP24XX_PRCM_VOLTCTRL_OFFSET 0x0050 +#define OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET 0x0080 + +/* 242x GR_MOD registers, use these only for assembly code */ +#define OMAP242X_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ + OMAP24XX_PRCM_VOLTCTRL_OFFSET) +#define OMAP242X_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ + OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) + +/* 243x GR_MOD registers, use these only for assembly code */ +#define OMAP243X_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ + OMAP24XX_PRCM_VOLTCTRL_OFFSET) +#define OMAP243X_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ + OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) + +/* These will disappear */ #define OMAP24XX_PRCM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0000) #define OMAP24XX_PRCM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0010) #define OMAP24XX_PRCM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) #define OMAP24XX_PRCM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) -#define OMAP24XX_PRCM_VOLTCTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0050) #define OMAP24XX_PRCM_VOLTST OMAP_PRM_REGADDR(OCP_MOD, 0x0054) #define OMAP24XX_PRCM_CLKSRC_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0060) #define OMAP24XX_PRCM_CLKOUT_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0070) diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S index 4a9e4914071..4c274510f3e 100644 --- a/arch/arm/mach-omap2/sram242x.S +++ b/arch/arm/mach-omap2/sram242x.S @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap2/sram-fn.S + * linux/arch/arm/mach-omap2/sram242x.S * * Omap2 specific functions that need to be run in internal SRAM * @@ -27,22 +27,20 @@ #include #include -#include "sdrc.h" #include "prm.h" #include "cm.h" - -#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) +#include "sdrc.h" .text -ENTRY(sram_ddr_init) +ENTRY(omap242x_sram_ddr_init) stmfd sp!, {r0 - r12, lr} @ save registers on stack mov r12, r2 @ capture CS1 vs CS0 mov r8, r3 @ capture force parameter /* frequency shift down */ - ldr r2, cm_clksel2_pll @ get address of dpllout reg + ldr r2, omap242x_sdi_cm_clksel2_pll @ get address of dpllout reg mov r3, #0x1 @ value for 1x operation str r3, [r2] @ go to L1-freq operation @@ -51,7 +49,7 @@ ENTRY(sram_ddr_init) bl voltage_shift @ go drop voltage /* dll lock mode */ - ldr r11, sdrc_dlla_ctrl @ addr of dlla ctrl + ldr r11, omap242x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl ldr r10, [r11] @ get current val cmp r12, #0x1 @ cs1 base (2422 es2.05/1) addeq r11, r11, #0x8 @ if cs1 base, move to DLLB @@ -102,7 +100,7 @@ i_dll_delay: * wait for it to finish, use 32k sync counter, 1tick=31uS. */ voltage_shift: - ldr r4, prcm_voltctrl @ get addr of volt ctrl. + ldr r4, omap242x_sdi_prcm_voltctrl @ get addr of volt ctrl. ldr r5, [r4] @ get value. ldr r6, prcm_mask_val @ get value of mask and r5, r5, r6 @ apply mask to clear bits @@ -112,7 +110,7 @@ voltage_shift: orr r5, r5, r3 @ build value for force str r5, [r4] @ Force transition to L1 - ldr r3, timer_32ksynct_cr @ get addr of counter + ldr r3, omap242x_sdi_timer_32ksynct_cr @ get addr of counter ldr r5, [r3] @ get value add r5, r5, #0x3 @ give it at most 93uS volt_delay: @@ -121,32 +119,31 @@ volt_delay: bhi volt_delay @ not yet->branch mov pc, lr @ back to caller. -/* relative load constants */ -cm_clksel2_pll: +omap242x_sdi_cm_clksel2_pll: .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) -sdrc_dlla_ctrl: +omap242x_sdi_sdrc_dlla_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) -prcm_voltctrl: - .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x50) +omap242x_sdi_prcm_voltctrl: + .word OMAP242X_PRCM_VOLTCTRL prcm_mask_val: .word 0xFFFF3FFC -timer_32ksynct_cr: - .word TIMER_32KSYNCT_CR_V -ENTRY(sram_ddr_init_sz) - .word . - sram_ddr_init +omap242x_sdi_timer_32ksynct_cr: + .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) +ENTRY(omap242x_sram_ddr_init_sz) + .word . - omap242x_sram_ddr_init /* * Reprograms memory timings. * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 */ -ENTRY(sram_reprogram_sdrc) +ENTRY(omap242x_sram_reprogram_sdrc) stmfd sp!, {r0 - r10, lr} @ save registers on stack mov r3, #0x0 @ clear for mrc call mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR nop nop - ldr r6, ddr_sdrc_rfr_ctrl @ get addr of refresh reg + ldr r6, omap242x_srs_sdrc_rfr_ctrl @ get addr of refresh reg ldr r5, [r6] @ get value mov r5, r5, lsr #8 @ isolate rfr field and drop burst @@ -160,7 +157,7 @@ ENTRY(sram_reprogram_sdrc) movne r5, r5, lsl #1 @ mult by 2 if to full mov r5, r5, lsl #8 @ put rfr field back into place add r5, r5, #0x1 @ turn on burst of 1 - ldr r4, ddr_cm_clksel2_pll @ get address of out reg + ldr r4, omap242x_srs_cm_clksel2_pll @ get address of out reg ldr r3, [r4] @ get curr value orr r3, r3, #0x3 bic r3, r3, #0x3 @ clear lower bits @@ -181,7 +178,7 @@ ENTRY(sram_reprogram_sdrc) bne freq_out @ leave if SDR, no DLL function /* With DDR, we need to take care of the DLL for the frequency change */ - ldr r2, ddr_sdrc_dlla_ctrl @ addr of dlla ctrl + ldr r2, omap242x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl str r1, [r2] @ write out new SDRC_DLLA_CTRL add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL str r1, [r2] @ commit to SDRC_DLLB_CTRL @@ -197,7 +194,7 @@ freq_out: * wait for it to finish, use 32k sync counter, 1tick=31uS. */ voltage_shift_c: - ldr r10, ddr_prcm_voltctrl @ get addr of volt ctrl + ldr r10, omap242x_srs_prcm_voltctrl @ get addr of volt ctrl ldr r8, [r10] @ get value ldr r7, ddr_prcm_mask_val @ get value of mask and r8, r8, r7 @ apply mask to clear bits @@ -207,7 +204,7 @@ voltage_shift_c: orr r8, r8, r7 @ build value for force str r8, [r10] @ Force transition to L1 - ldr r10, ddr_timer_32ksynct @ get addr of counter + ldr r10, omap242x_srs_timer_32ksynct @ get addr of counter ldr r8, [r10] @ get value add r8, r8, #0x2 @ give it at most 62uS (min 31+) volt_delay_c: @@ -216,39 +213,39 @@ volt_delay_c: bhi volt_delay_c @ not yet->branch mov pc, lr @ back to caller -ddr_cm_clksel2_pll: +omap242x_srs_cm_clksel2_pll: .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) -ddr_sdrc_dlla_ctrl: +omap242x_srs_sdrc_dlla_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) -ddr_sdrc_rfr_ctrl: +omap242x_srs_sdrc_rfr_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) -ddr_prcm_voltctrl: - .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x50) +omap242x_srs_prcm_voltctrl: + .word OMAP242X_PRCM_VOLTCTRL ddr_prcm_mask_val: .word 0xFFFF3FFC -ddr_timer_32ksynct: - .word TIMER_32KSYNCT_CR_V +omap242x_srs_timer_32ksynct: + .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) -ENTRY(sram_reprogram_sdrc_sz) - .word . - sram_reprogram_sdrc +ENTRY(omap242x_sram_reprogram_sdrc_sz) + .word . - omap242x_sram_reprogram_sdrc /* * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. */ -ENTRY(sram_set_prcm) +ENTRY(omap242x_sram_set_prcm) stmfd sp!, {r0-r12, lr} @ regs to stack adr r4, pbegin @ addr of preload start adr r8, pend @ addr of preload end mcrr p15, 1, r8, r4, c12 @ preload into icache pbegin: /* move into fast relock bypass */ - ldr r8, pll_ctl @ get addr + ldr r8, omap242x_ssp_pll_ctl @ get addr ldr r5, [r8] @ get val mvn r6, #0x3 @ clear mask and r5, r5, r6 @ clear field orr r7, r5, #0x2 @ fast relock val str r7, [r8] @ go to fast relock - ldr r4, pll_stat @ addr of stat + ldr r4, omap242x_ssp_pll_stat @ addr of stat block: /* wait for bypass */ ldr r8, [r4] @ stat value @@ -257,10 +254,10 @@ block: bne block @ loop if not /* set new dpll dividers _after_ in bypass */ - ldr r4, pll_div @ get addr + ldr r4, omap242x_ssp_pll_div @ get addr str r0, [r4] @ set dpll ctrl val - ldr r4, set_config @ get addr + ldr r4, omap242x_ssp_set_config @ get addr mov r8, #1 @ valid cfg msk str r8, [r4] @ make dividers take @@ -274,8 +271,8 @@ wait_a_bit: beq pend @ jump over dpll relock /* relock DPLL with new vals */ - ldr r5, pll_stat @ get addr - ldr r4, pll_ctl @ get addr + ldr r5, omap242x_ssp_pll_stat @ get addr + ldr r4, omap242x_ssp_pll_ctl @ get addr orr r8, r7, #0x3 @ val for lock dpll str r8, [r4] @ set val mov r0, #1000 @ dead spin a bit @@ -289,9 +286,9 @@ wait_lock: bne wait_lock @ wait if not pend: /* update memory timings & briefly lock dll */ - ldr r4, sdrc_rfr @ get addr + ldr r4, omap242x_ssp_sdrc_rfr @ get addr str r1, [r4] @ update refresh timing - ldr r11, dlla_ctrl @ get addr of DLLA ctrl + ldr r11, omap242x_ssp_dlla_ctrl @ get addr of DLLA ctrl ldr r10, [r11] @ get current val mvn r9, #0x4 @ mask to get clear bit2 and r10, r10, r9 @ clear bit2 for lock mode @@ -307,18 +304,18 @@ wait_dll_lock: nop ldmfd sp!, {r0-r12, pc} @ restore regs and return -set_config: - .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x80) -pll_ctl: - .word OMAP2420_CM_REGADDR(PLL_MOD, CM_FCLKEN1) -pll_stat: - .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST1) -pll_div: - .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL) -sdrc_rfr: +omap242x_ssp_set_config: + .word OMAP242X_PRCM_CLKCFG_CTRL +omap242x_ssp_pll_ctl: + .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN) +omap242x_ssp_pll_stat: + .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST) +omap242x_ssp_pll_div: + .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL1) +omap242x_ssp_sdrc_rfr: .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) -dlla_ctrl: +omap242x_ssp_dlla_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) -ENTRY(sram_set_prcm_sz) - .word . - sram_set_prcm +ENTRY(omap242x_sram_set_prcm_sz) + .word . - omap242x_sram_set_prcm diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S new file mode 100644 index 00000000000..a3fa48dc08c --- /dev/null +++ b/arch/arm/mach-omap2/sram243x.S @@ -0,0 +1,321 @@ +/* + * linux/arch/arm/mach-omap2/sram243x.S + * + * Omap2 specific functions that need to be run in internal SRAM + * + * (C) Copyright 2004 + * Texas Instruments, + * Richard Woodruff + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include + +#include "prm.h" +#include "cm.h" +#include "sdrc.h" + + .text + +ENTRY(omap243x_sram_ddr_init) + stmfd sp!, {r0 - r12, lr} @ save registers on stack + + mov r12, r2 @ capture CS1 vs CS0 + mov r8, r3 @ capture force parameter + + /* frequency shift down */ + ldr r2, omap243x_sdi_cm_clksel2_pll @ get address of dpllout reg + mov r3, #0x1 @ value for 1x operation + str r3, [r2] @ go to L1-freq operation + + /* voltage shift down */ + mov r9, #0x1 @ set up for L1 voltage call + bl voltage_shift @ go drop voltage + + /* dll lock mode */ + ldr r11, omap243x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl + ldr r10, [r11] @ get current val + cmp r12, #0x1 @ cs1 base (2422 es2.05/1) + addeq r11, r11, #0x8 @ if cs1 base, move to DLLB + mvn r9, #0x4 @ mask to get clear bit2 + and r10, r10, r9 @ clear bit2 for lock mode. + orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) + orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz + str r10, [r11] @ commit to DLLA_CTRL + bl i_dll_wait @ wait for dll to lock + + /* get dll value */ + add r11, r11, #0x4 @ get addr of status reg + ldr r10, [r11] @ get locked value + + /* voltage shift up */ + mov r9, #0x0 @ shift back to L0-voltage + bl voltage_shift @ go raise voltage + + /* frequency shift up */ + mov r3, #0x2 @ value for 2x operation + str r3, [r2] @ go to L0-freq operation + + /* reset entry mode for dllctrl */ + sub r11, r11, #0x4 @ move from status to ctrl + cmp r12, #0x1 @ normalize if cs1 based + subeq r11, r11, #0x8 @ possibly back to DLLA + cmp r8, #0x1 @ if forced unlock exit + orreq r1, r1, #0x4 @ make sure exit with unlocked value + str r1, [r11] @ restore DLLA_CTRL high value + add r11, r11, #0x8 @ move to DLLB_CTRL addr + str r1, [r11] @ set value DLLB_CTRL + bl i_dll_wait @ wait for possible lock + + /* set up for return, DDR should be good */ + str r10, [r0] @ write dll_status and return counter + ldmfd sp!, {r0 - r12, pc} @ restore regs and return + + /* ensure the DLL has relocked */ +i_dll_wait: + mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks +i_dll_delay: + subs r4, r4, #0x1 + bne i_dll_delay + mov pc, lr + + /* + * shift up or down voltage, use R9 as input to tell level. + * wait for it to finish, use 32k sync counter, 1tick=31uS. + */ +voltage_shift: + ldr r4, omap243x_sdi_prcm_voltctrl @ get addr of volt ctrl. + ldr r5, [r4] @ get value. + ldr r6, prcm_mask_val @ get value of mask + and r5, r5, r6 @ apply mask to clear bits + orr r5, r5, r9 @ bulld value for L0/L1-volt operation. + str r5, [r4] @ set up for change. + mov r3, #0x4000 @ get val for force + orr r5, r5, r3 @ build value for force + str r5, [r4] @ Force transition to L1 + + ldr r3, omap243x_sdi_timer_32ksynct_cr @ get addr of counter + ldr r5, [r3] @ get value + add r5, r5, #0x3 @ give it at most 93uS +volt_delay: + ldr r7, [r3] @ get timer value + cmp r5, r7 @ time up? + bhi volt_delay @ not yet->branch + mov pc, lr @ back to caller. + +omap243x_sdi_cm_clksel2_pll: + .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) +omap243x_sdi_sdrc_dlla_ctrl: + .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) +omap243x_sdi_prcm_voltctrl: + .word OMAP243X_PRCM_VOLTCTRL +prcm_mask_val: + .word 0xFFFF3FFC +omap243x_sdi_timer_32ksynct_cr: + .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) +ENTRY(omap243x_sram_ddr_init_sz) + .word . - omap243x_sram_ddr_init + +/* + * Reprograms memory timings. + * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] + * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 + */ +ENTRY(omap243x_sram_reprogram_sdrc) + stmfd sp!, {r0 - r10, lr} @ save registers on stack + mov r3, #0x0 @ clear for mrc call + mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR + nop + nop + ldr r6, omap243x_srs_sdrc_rfr_ctrl @ get addr of refresh reg + ldr r5, [r6] @ get value + mov r5, r5, lsr #8 @ isolate rfr field and drop burst + + cmp r0, #0x1 @ going to half speed? + movne r9, #0x0 @ if up set flag up for pre up, hi volt + + blne voltage_shift_c @ adjust voltage + + cmp r0, #0x1 @ going to half speed (post branch link) + moveq r5, r5, lsr #1 @ divide by 2 if to half + movne r5, r5, lsl #1 @ mult by 2 if to full + mov r5, r5, lsl #8 @ put rfr field back into place + add r5, r5, #0x1 @ turn on burst of 1 + ldr r4, omap243x_srs_cm_clksel2_pll @ get address of out reg + ldr r3, [r4] @ get curr value + orr r3, r3, #0x3 + bic r3, r3, #0x3 @ clear lower bits + orr r3, r3, r0 @ new state value + str r3, [r4] @ set new state (pll/x, x=1 or 2) + nop + nop + + moveq r9, #0x1 @ if speed down, post down, drop volt + bleq voltage_shift_c + + mcr p15, 0, r3, c7, c10, 4 @ memory barrier + str r5, [r6] @ set new RFR_1 value + add r6, r6, #0x30 @ get RFR_2 addr + str r5, [r6] @ set RFR_2 + nop + cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL + bne freq_out @ leave if SDR, no DLL function + + /* With DDR, we need to take care of the DLL for the frequency change */ + ldr r2, omap243x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl + str r1, [r2] @ write out new SDRC_DLLA_CTRL + add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL + str r1, [r2] @ commit to SDRC_DLLB_CTRL + mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks +dll_wait: + subs r1, r1, #0x1 + bne dll_wait +freq_out: + ldmfd sp!, {r0 - r10, pc} @ restore regs and return + + /* + * shift up or down voltage, use R9 as input to tell level. + * wait for it to finish, use 32k sync counter, 1tick=31uS. + */ +voltage_shift_c: + ldr r10, omap243x_srs_prcm_voltctrl @ get addr of volt ctrl + ldr r8, [r10] @ get value + ldr r7, ddr_prcm_mask_val @ get value of mask + and r8, r8, r7 @ apply mask to clear bits + orr r8, r8, r9 @ bulld value for L0/L1-volt operation. + str r8, [r10] @ set up for change. + mov r7, #0x4000 @ get val for force + orr r8, r8, r7 @ build value for force + str r8, [r10] @ Force transition to L1 + + ldr r10, omap243x_srs_timer_32ksynct @ get addr of counter + ldr r8, [r10] @ get value + add r8, r8, #0x2 @ give it at most 62uS (min 31+) +volt_delay_c: + ldr r7, [r10] @ get timer value + cmp r8, r7 @ time up? + bhi volt_delay_c @ not yet->branch + mov pc, lr @ back to caller + +omap243x_srs_cm_clksel2_pll: + .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) +omap243x_srs_sdrc_dlla_ctrl: + .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) +omap243x_srs_sdrc_rfr_ctrl: + .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) +omap243x_srs_prcm_voltctrl: + .word OMAP243X_PRCM_VOLTCTRL +ddr_prcm_mask_val: + .word 0xFFFF3FFC +omap243x_srs_timer_32ksynct: + .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) + +ENTRY(omap243x_sram_reprogram_sdrc_sz) + .word . - omap243x_sram_reprogram_sdrc + +/* + * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. + */ +ENTRY(omap243x_sram_set_prcm) + stmfd sp!, {r0-r12, lr} @ regs to stack + adr r4, pbegin @ addr of preload start + adr r8, pend @ addr of preload end + mcrr p15, 1, r8, r4, c12 @ preload into icache +pbegin: + /* move into fast relock bypass */ + ldr r8, omap243x_ssp_pll_ctl @ get addr + ldr r5, [r8] @ get val + mvn r6, #0x3 @ clear mask + and r5, r5, r6 @ clear field + orr r7, r5, #0x2 @ fast relock val + str r7, [r8] @ go to fast relock + ldr r4, omap243x_ssp_pll_stat @ addr of stat +block: + /* wait for bypass */ + ldr r8, [r4] @ stat value + and r8, r8, #0x3 @ mask for stat + cmp r8, #0x1 @ there yet + bne block @ loop if not + + /* set new dpll dividers _after_ in bypass */ + ldr r4, omap243x_ssp_pll_div @ get addr + str r0, [r4] @ set dpll ctrl val + + ldr r4, omap243x_ssp_set_config @ get addr + mov r8, #1 @ valid cfg msk + str r8, [r4] @ make dividers take + + mov r4, #100 @ dead spin a bit +wait_a_bit: + subs r4, r4, #1 @ dec loop + bne wait_a_bit @ delay done? + + /* check if staying in bypass */ + cmp r2, #0x1 @ stay in bypass? + beq pend @ jump over dpll relock + + /* relock DPLL with new vals */ + ldr r5, omap243x_ssp_pll_stat @ get addr + ldr r4, omap243x_ssp_pll_ctl @ get addr + orr r8, r7, #0x3 @ val for lock dpll + str r8, [r4] @ set val + mov r0, #1000 @ dead spin a bit +wait_more: + subs r0, r0, #1 @ dec loop + bne wait_more @ delay done? +wait_lock: + ldr r8, [r5] @ get lock val + and r8, r8, #3 @ isolate field + cmp r8, #2 @ locked? + bne wait_lock @ wait if not +pend: + /* update memory timings & briefly lock dll */ + ldr r4, omap243x_ssp_sdrc_rfr @ get addr + str r1, [r4] @ update refresh timing + ldr r11, omap243x_ssp_dlla_ctrl @ get addr of DLLA ctrl + ldr r10, [r11] @ get current val + mvn r9, #0x4 @ mask to get clear bit2 + and r10, r10, r9 @ clear bit2 for lock mode + orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) + str r10, [r11] @ commit to DLLA_CTRL + add r11, r11, #0x8 @ move to dllb + str r10, [r11] @ hit DLLB also + + mov r4, #0x800 @ relock time (min 0x400 L3 clocks) +wait_dll_lock: + subs r4, r4, #0x1 + bne wait_dll_lock + nop + ldmfd sp!, {r0-r12, pc} @ restore regs and return + +omap243x_ssp_set_config: + .word OMAP243X_PRCM_CLKCFG_CTRL +omap243x_ssp_pll_ctl: + .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN) +omap243x_ssp_pll_stat: + .word OMAP2430_CM_REGADDR(PLL_MOD, CM_IDLEST) +omap243x_ssp_pll_div: + .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL1) +omap243x_ssp_sdrc_rfr: + .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) +omap243x_ssp_dlla_ctrl: + .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) + +ENTRY(omap243x_sram_set_prcm_sz) + .word . - omap243x_sram_set_prcm diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 1f23f0459e5..554ee58e129 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -10,6 +10,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#undef DEBUG #include #include @@ -24,25 +25,43 @@ #include #include +#include + +#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) +# include "../mach-omap2/prm.h" +# include "../mach-omap2/cm.h" +# include "../mach-omap2/sdrc.h" +#endif + #define OMAP1_SRAM_PA 0x20000000 -#define OMAP1_SRAM_VA 0xd0000000 +#define OMAP1_SRAM_VA VMALLOC_END #define OMAP2_SRAM_PA 0x40200000 #define OMAP2_SRAM_PUB_PA 0x4020f800 -#define OMAP2_SRAM_VA 0xd0000000 -#define OMAP2_SRAM_PUB_VA 0xd0000800 - -#if defined(CONFIG_ARCH_OMAP24XX) +#define OMAP2_SRAM_VA VMALLOC_END +#define OMAP2_SRAM_PUB_VA (VMALLOC_END + 0x800) +#define OMAP3_SRAM_PA 0x40200000 +#define OMAP3_SRAM_VA 0xd7000000 +#define OMAP3_SRAM_PUB_PA 0x40208000 +#define OMAP3_SRAM_PUB_VA 0xd7008000 + +#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) #define SRAM_BOOTLOADER_SZ 0x00 #else #define SRAM_BOOTLOADER_SZ 0x80 #endif -#define VA_REQINFOPERM0 IO_ADDRESS(0x68005048) -#define VA_READPERM0 IO_ADDRESS(0x68005050) -#define VA_WRITEPERM0 IO_ADDRESS(0x68005058) -#define VA_CONTROL_STAT IO_ADDRESS(0x480002F8) +#define OMAP24XX_VA_REQINFOPERM0 IO_ADDRESS(0x68005048) +#define OMAP24XX_VA_READPERM0 IO_ADDRESS(0x68005050) +#define OMAP24XX_VA_WRITEPERM0 IO_ADDRESS(0x68005058) + +#define OMAP34XX_VA_REQINFOPERM0 IO_ADDRESS(0x68012848) +#define OMAP34XX_VA_READPERM0 IO_ADDRESS(0x68012850) +#define OMAP34XX_VA_WRITEPERM0 IO_ADDRESS(0x68012858) +#define OMAP34XX_VA_ADDR_MATCH2 IO_ADDRESS(0x68012880) +#define OMAP34XX_VA_SMS_RG_ATT0 IO_ADDRESS(0x6C000048) +#define OMAP34XX_VA_CONTROL_STAT IO_ADDRESS(0x480022F0) + #define GP_DEVICE 0x300 -#define TYPE_MASK 0x700 #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) @@ -68,14 +87,21 @@ static int is_sram_locked(void) int type = 0; if (cpu_is_omap242x()) - type = __raw_readl(VA_CONTROL_STAT) & TYPE_MASK; + type = system_rev & OMAP2_DEVICETYPE_MASK; if (type == GP_DEVICE) { /* RAMFW: R/W access to all initiators for all qualifier sets */ if (cpu_is_omap242x()) { - __raw_writel(0xFF, VA_REQINFOPERM0); /* all q-vects */ - __raw_writel(0xCFDE, VA_READPERM0); /* all i-read */ - __raw_writel(0xCFDE, VA_WRITEPERM0); /* all i-write */ + __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */ + __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */ + __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */ + } + if (cpu_is_omap34xx()) { + __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */ + __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */ + __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */ + __raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2); + __raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0); } return 0; } else @@ -92,18 +118,30 @@ void __init omap_detect_sram(void) { unsigned long reserved; - if (cpu_is_omap24xx()) { + if (cpu_class_is_omap2()) { if (is_sram_locked()) { - omap_sram_base = OMAP2_SRAM_PUB_VA; - omap_sram_start = OMAP2_SRAM_PUB_PA; - omap_sram_size = 0x800; /* 2K */ + if (cpu_is_omap34xx()) { + omap_sram_base = OMAP3_SRAM_PUB_VA; + omap_sram_start = OMAP3_SRAM_PUB_PA; + omap_sram_size = 0x8000; /* 32K */ + } else { + omap_sram_base = OMAP2_SRAM_PUB_VA; + omap_sram_start = OMAP2_SRAM_PUB_PA; + omap_sram_size = 0x800; /* 2K */ + } } else { - omap_sram_base = OMAP2_SRAM_VA; - omap_sram_start = OMAP2_SRAM_PA; - if (cpu_is_omap242x()) - omap_sram_size = 0xa0000; /* 640K */ - else if (cpu_is_omap243x()) + if (cpu_is_omap34xx()) { + omap_sram_base = OMAP3_SRAM_VA; + omap_sram_start = OMAP3_SRAM_PA; omap_sram_size = 0x10000; /* 64K */ + } else { + omap_sram_base = OMAP2_SRAM_VA; + omap_sram_start = OMAP2_SRAM_PA; + if (cpu_is_omap242x()) + omap_sram_size = 0xa0000; /* 640K */ + else if (cpu_is_omap243x()) + omap_sram_size = 0x10000; /* 64K */ + } } } else { omap_sram_base = OMAP1_SRAM_VA; @@ -157,6 +195,13 @@ void __init omap_map_sram(void) omap_sram_io_desc[0].pfn = __phys_to_pfn(base); } + if (cpu_is_omap34xx()) { + omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA; + base = OMAP3_SRAM_PA; + base = ROUND_DOWN(base, PAGE_SIZE); + omap_sram_io_desc[0].pfn = __phys_to_pfn(base); + } + omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */ iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); @@ -191,6 +236,7 @@ void * omap_sram_push(void * start, unsigned long size) omap_sram_ceil -= size; omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *)); memcpy((void *)omap_sram_ceil, start, size); + flush_icache_range((unsigned long)start, (unsigned long)(start + size)); return (void *)omap_sram_ceil; } @@ -214,8 +260,9 @@ void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) int __init omap1_sram_init(void) { - _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock, - sram_reprogram_clock_sz); + _omap_sram_reprogram_clock = + omap_sram_push(omap1_sram_reprogram_clock, + omap1_sram_reprogram_clock_sz); return 0; } @@ -224,7 +271,7 @@ int __init omap1_sram_init(void) #define omap1_sram_init() do {} while (0) #endif -#ifdef CONFIG_ARCH_OMAP2 +#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, u32 base_cs, u32 force_unlock); @@ -259,19 +306,109 @@ u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass) return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass); } +#endif + +#ifdef CONFIG_ARCH_OMAP2420 +int __init omap242x_sram_init(void) +{ + _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init, + omap242x_sram_ddr_init_sz); + + _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc, + omap242x_sram_reprogram_sdrc_sz); + + _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm, + omap242x_sram_set_prcm_sz); + + return 0; +} +#else +static inline int omap242x_sram_init(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_ARCH_OMAP2430 +int __init omap243x_sram_init(void) +{ + _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init, + omap243x_sram_ddr_init_sz); + + _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc, + omap243x_sram_reprogram_sdrc_sz); + + _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm, + omap243x_sram_set_prcm_sz); + + return 0; +} +#else +static inline int omap243x_sram_init(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_ARCH_OMAP3 + +static u32 (*_omap2_sram_reprogram_gpmc)(u32 perf_level); +u32 omap2_sram_reprogram_gpmc(u32 perf_level) +{ + if (!_omap2_sram_reprogram_gpmc) + omap_sram_error(); + + return _omap2_sram_reprogram_gpmc(perf_level); +} + +static u32 (*_omap2_sram_configure_core_dpll)(u32 m, u32 n, + u32 freqsel, u32 m2); +u32 omap2_sram_configure_core_dpll(u32 m, u32 n, u32 freqsel, u32 m2) +{ + if (!_omap2_sram_configure_core_dpll) + omap_sram_error(); + + return _omap2_sram_configure_core_dpll(m, n, freqsel, m2); +} -int __init omap2_sram_init(void) +/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */ +void restore_sram_functions(void) { - _omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz); + omap_sram_ceil = omap_sram_base + omap_sram_size; - _omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc, - sram_reprogram_sdrc_sz); - _omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz); + _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc, + omap34xx_sram_reprogram_gpmc_sz); + + _omap2_sram_configure_core_dpll = + omap_sram_push(omap34xx_sram_configure_core_dpll, + omap34xx_sram_configure_core_dpll_sz); +} + +int __init omap34xx_sram_init(void) +{ + _omap2_sram_ddr_init = omap_sram_push(omap34xx_sram_ddr_init, + omap34xx_sram_ddr_init_sz); + + _omap2_sram_reprogram_sdrc = omap_sram_push(omap34xx_sram_reprogram_sdrc, + omap34xx_sram_reprogram_sdrc_sz); + + _omap2_set_prcm = omap_sram_push(omap34xx_sram_set_prcm, + omap34xx_sram_set_prcm_sz); + + _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc, + omap34xx_sram_reprogram_gpmc_sz); + + _omap2_sram_configure_core_dpll = + omap_sram_push(omap34xx_sram_configure_core_dpll, + omap34xx_sram_configure_core_dpll_sz); return 0; } #else -#define omap2_sram_init() do {} while (0) +static inline int omap34xx_sram_init(void) +{ + return 0; +} #endif int __init omap_sram_init(void) @@ -279,10 +416,14 @@ int __init omap_sram_init(void) omap_detect_sram(); omap_map_sram(); - if (!cpu_is_omap24xx()) + if (!(cpu_class_is_omap2())) omap1_sram_init(); - else - omap2_sram_init(); + else if (cpu_is_omap242x()) + omap242x_sram_init(); + else if (cpu_is_omap2430()) + omap243x_sram_init(); + else if (cpu_is_omap34xx()) + omap34xx_sram_init(); return 0; } diff --git a/include/asm-arm/arch-omap/sram.h b/include/asm-arm/arch-omap/sram.h index bb9bb3fd532..be59f4a9828 100644 --- a/include/asm-arm/arch-omap/sram.h +++ b/include/asm-arm/arch-omap/sram.h @@ -11,6 +11,7 @@ #ifndef __ARCH_ARM_OMAP_SRAM_H #define __ARCH_ARM_OMAP_SRAM_H +extern int __init omap_sram_init(void); extern void * omap_sram_push(void * start, unsigned long size); extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); @@ -21,17 +22,35 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); /* Do not use these */ -extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl); -extern unsigned long sram_reprogram_clock_sz; +extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl); +extern unsigned long omap1_sram_reprogram_clock_sz; -extern void sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, - u32 base_cs, u32 force_unlock); -extern unsigned long sram_ddr_init_sz; +extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl); +extern unsigned long omap24xx_sram_reprogram_clock_sz; -extern u32 sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); -extern unsigned long sram_set_prcm_sz; +extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, + u32 base_cs, u32 force_unlock); +extern unsigned long omap242x_sram_ddr_init_sz; -extern void sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type); -extern unsigned long sram_reprogram_sdrc_sz; +extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, + int bypass); +extern unsigned long omap242x_sram_set_prcm_sz; + +extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, + u32 mem_type); +extern unsigned long omap242x_sram_reprogram_sdrc_sz; + + +extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, + u32 base_cs, u32 force_unlock); +extern unsigned long omap243x_sram_ddr_init_sz; + +extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, + int bypass); +extern unsigned long omap243x_sram_set_prcm_sz; + +extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, + u32 mem_type); +extern unsigned long omap243x_sram_reprogram_sdrc_sz; #endif -- cgit v1.2.3-70-g09d2 From bc5d0c89c88df67f92d5d5882c27437379e9e8af Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Thu, 3 Jul 2008 12:24:39 +0300 Subject: ARM: OMAP: McBSP: Prepare for splitting into omap1 and omap2 code This patch transform mcbsp code to use platform data from arch/arm/plat-omap/devices.c It also gets ride of ifdefs on mcbsp.c code. To do it, a platform data structure was defined. Signed-off-by: Eduardo Valentin Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/devices.c | 48 +++ arch/arm/plat-omap/mcbsp.c | 662 +++++++++++++++----------------------- include/asm-arm/arch-omap/mcbsp.h | 62 +++- 3 files changed, 361 insertions(+), 411 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 4a53f9ba6c4..81002b722da 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -24,6 +24,7 @@ #include #include #include +#include #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) @@ -144,6 +145,53 @@ static void omap_init_kp(void) static inline void omap_init_kp(void) {} #endif +/*-------------------------------------------------------------------------*/ +#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE) + +static struct platform_device **omap_mcbsp_devices; + +void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, + int size) +{ + int i; + + if (size > OMAP_MAX_MCBSP_COUNT) { + printk(KERN_WARNING "Registered too many McBSPs platform_data." + " Using maximum (%d) available.\n", + OMAP_MAX_MCBSP_COUNT); + size = OMAP_MAX_MCBSP_COUNT; + } + + omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *), + GFP_KERNEL); + if (!omap_mcbsp_devices) { + printk(KERN_ERR "Could not register McBSP devices\n"); + return; + } + + for (i = 0; i < size; i++) { + struct platform_device *new_mcbsp; + int ret; + + new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1); + if (!new_mcbsp) + continue; + new_mcbsp->dev.platform_data = &config[i]; + ret = platform_device_add(new_mcbsp); + if (ret) { + platform_device_put(new_mcbsp); + continue; + } + omap_mcbsp_devices[i] = new_mcbsp; + } +} + +#else +void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, + int size) +{ } +#endif + /*-------------------------------------------------------------------------*/ #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index c0018b1b667..c7f74064696 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -24,83 +25,53 @@ #include #include -#include -#include -#include #include -#ifdef CONFIG_MCBSP_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) do { } while (0) -#endif - -struct omap_mcbsp { - u32 io_base; - u8 id; - u8 free; - omap_mcbsp_word_length rx_word_length; - omap_mcbsp_word_length tx_word_length; - - omap_mcbsp_io_type_t io_type; /* IRQ or poll */ - /* IRQ based TX/RX */ - int rx_irq; - int tx_irq; - - /* DMA stuff */ - u8 dma_rx_sync; - short dma_rx_lch; - u8 dma_tx_sync; - short dma_tx_lch; - - /* Completion queues */ - struct completion tx_irq_completion; - struct completion rx_irq_completion; - struct completion tx_dma_completion; - struct completion rx_dma_completion; - - /* Protect the field .free, while checking if the mcbsp is in use */ - spinlock_t lock; -}; - static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; -#ifdef CONFIG_ARCH_OMAP1 -static struct clk *mcbsp_dsp_ck; -static struct clk *mcbsp_api_ck; -static struct clk *mcbsp_dspxor_ck; -#endif -#ifdef CONFIG_ARCH_OMAP2 -static struct clk *mcbsp1_ick; -static struct clk *mcbsp1_fck; -static struct clk *mcbsp2_ick; -static struct clk *mcbsp2_fck; -#endif + +#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \ + mcbsp[id].pdata->ops && \ + mcbsp[id].pdata->ops->check && \ + (mcbsp[id].pdata->ops->check(id) == 0)) static void omap_mcbsp_dump_reg(u8 id) { - DBG("**** MCBSP%d regs ****\n", mcbsp[id].id); - DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); - DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); - DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); - DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); - DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); - DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); - DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); - DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); - DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); - DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); - DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); - DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); - DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); - DBG("***********************\n"); + dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id); + dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); + dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); + dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); + dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); + dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); + dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); + dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); + dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); + dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); + dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); + dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); + dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); + dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n", + OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); + dev_dbg(mcbsp[id].dev, "***********************\n"); } static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) { struct omap_mcbsp *mcbsp_tx = dev_id; - DBG("TX IRQ callback : 0x%x\n", - OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); + dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", + OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); complete(&mcbsp_tx->tx_irq_completion); @@ -111,8 +82,8 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) { struct omap_mcbsp *mcbsp_rx = dev_id; - DBG("RX IRQ callback : 0x%x\n", - OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); + dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", + OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); complete(&mcbsp_rx->rx_irq_completion); @@ -123,8 +94,8 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) { struct omap_mcbsp *mcbsp_dma_tx = data; - DBG("TX DMA callback : 0x%x\n", - OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); + dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n", + OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); /* We can free the channels */ omap_free_dma(mcbsp_dma_tx->dma_tx_lch); @@ -137,8 +108,8 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) { struct omap_mcbsp *mcbsp_dma_rx = data; - DBG("RX DMA callback : 0x%x\n", - OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); + dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n", + OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); /* We can free the channels */ omap_free_dma(mcbsp_dma_rx->dma_rx_lch); @@ -155,9 +126,16 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) */ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) { - u32 io_base = mcbsp[id].io_base; + u32 io_base; - DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id + 1, io_base); + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return; + } + + io_base = mcbsp[id].io_base; + dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n", + mcbsp[id].id, io_base); /* We write the given config */ OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); @@ -174,97 +152,22 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) } EXPORT_SYMBOL(omap_mcbsp_config); -static int omap_mcbsp_check(unsigned int id) -{ - if (cpu_is_omap730()) { - if (id > OMAP_MAX_MCBSP_COUNT - 1) { - printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", - id + 1); - return -1; - } - return 0; - } - - if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { - if (id > OMAP_MAX_MCBSP_COUNT) { - printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", - id + 1); - return -1; - } - return 0; - } - - return -1; -} - -#ifdef CONFIG_ARCH_OMAP1 -static void omap_mcbsp_dsp_request(void) -{ - if (cpu_is_omap15xx() || cpu_is_omap16xx()) { - int ret; - - ret = omap_dsp_request_mem(); - if (ret < 0) { - printk(KERN_ERR "Could not get dsp memory: %i\n", ret); - return; - } - - clk_enable(mcbsp_dsp_ck); - clk_enable(mcbsp_api_ck); - - /* enable 12MHz clock to mcbsp 1 & 3 */ - clk_enable(mcbsp_dspxor_ck); - - /* - * DSP external peripheral reset - * FIXME: This should be moved to dsp code - */ - __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1, - DSP_RSTCT2); - } -} - -static void omap_mcbsp_dsp_free(void) -{ - if (cpu_is_omap15xx() || cpu_is_omap16xx()) { - omap_dsp_release_mem(); - clk_disable(mcbsp_dspxor_ck); - clk_disable(mcbsp_dsp_ck); - clk_disable(mcbsp_api_ck); - } -} -#endif - -#ifdef CONFIG_ARCH_OMAP2 -static void omap2_mcbsp2_mux_setup(void) -{ - if (cpu_is_omap2420()) { - omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); - omap_cfg_reg(R14_24XX_MCBSP2_FSX); - omap_cfg_reg(W15_24XX_MCBSP2_DR); - omap_cfg_reg(V15_24XX_MCBSP2_DX); - omap_cfg_reg(V14_24XX_GPIO117); - } - /* - * Need to add MUX settings for OMAP 2430 SDP - */ -} -#endif - /* * We can choose between IRQ based or polled IO. * This needs to be called before omap_mcbsp_request(). */ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) { - if (omap_mcbsp_check(id) < 0) - return -EINVAL; + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } spin_lock(&mcbsp[id].lock); if (!mcbsp[id].free) { - printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", - id + 1); + dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", + mcbsp[id].id); spin_unlock(&mcbsp[id].lock); return -EINVAL; } @@ -281,34 +184,20 @@ int omap_mcbsp_request(unsigned int id) { int err; - if (omap_mcbsp_check(id) < 0) - return -EINVAL; - -#ifdef CONFIG_ARCH_OMAP1 - /* - * On 1510, 1610 and 1710, McBSP1 and McBSP3 - * are DSP public peripherals. - */ - if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) - omap_mcbsp_dsp_request(); -#endif - -#ifdef CONFIG_ARCH_OMAP2 - if (cpu_is_omap24xx()) { - if (id == OMAP_MCBSP1) { - clk_enable(mcbsp1_ick); - clk_enable(mcbsp1_fck); - } else { - clk_enable(mcbsp2_ick); - clk_enable(mcbsp2_fck); - } + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; } -#endif + + if (mcbsp[id].pdata->ops->request) + mcbsp[id].pdata->ops->request(id); + + clk_enable(mcbsp[id].clk); spin_lock(&mcbsp[id].lock); if (!mcbsp[id].free) { - printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", - id + 1); + dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", + mcbsp[id].id); spin_unlock(&mcbsp[id].lock); return -1; } @@ -321,9 +210,9 @@ int omap_mcbsp_request(unsigned int id) err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, "McBSP", (void *) (&mcbsp[id])); if (err != 0) { - printk(KERN_ERR "OMAP-McBSP: Unable to " - "request TX IRQ %d for McBSP%d\n", - mcbsp[id].tx_irq, mcbsp[id].id); + dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d " + "for McBSP%d\n", mcbsp[id].tx_irq, + mcbsp[id].id); return err; } @@ -332,9 +221,9 @@ int omap_mcbsp_request(unsigned int id) err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, "McBSP", (void *) (&mcbsp[id])); if (err != 0) { - printk(KERN_ERR "OMAP-McBSP: Unable to " - "request RX IRQ %d for McBSP%d\n", - mcbsp[id].rx_irq, mcbsp[id].id); + dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d " + "for McBSP%d\n", mcbsp[id].rx_irq, + mcbsp[id].id); free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); return err; } @@ -348,32 +237,20 @@ EXPORT_SYMBOL(omap_mcbsp_request); void omap_mcbsp_free(unsigned int id) { - if (omap_mcbsp_check(id) < 0) + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; - -#ifdef CONFIG_ARCH_OMAP1 - if (cpu_class_is_omap1()) { - if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) - omap_mcbsp_dsp_free(); } -#endif - -#ifdef CONFIG_ARCH_OMAP2 - if (cpu_is_omap24xx()) { - if (id == OMAP_MCBSP1) { - clk_disable(mcbsp1_ick); - clk_disable(mcbsp1_fck); - } else { - clk_disable(mcbsp2_ick); - clk_disable(mcbsp2_fck); - } - } -#endif + + if (mcbsp[id].pdata->ops->free) + mcbsp[id].pdata->ops->free(id); + + clk_disable(mcbsp[id].clk); spin_lock(&mcbsp[id].lock); if (mcbsp[id].free) { - printk(KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", - id + 1); + dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n", + mcbsp[id].id); spin_unlock(&mcbsp[id].lock); return; } @@ -399,8 +276,10 @@ void omap_mcbsp_start(unsigned int id) u32 io_base; u16 w; - if (omap_mcbsp_check(id) < 0) + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; + } io_base = mcbsp[id].io_base; @@ -434,8 +313,10 @@ void omap_mcbsp_stop(unsigned int id) u32 io_base; u16 w; - if (omap_mcbsp_check(id) < 0) + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; + } io_base = mcbsp[id].io_base; @@ -456,7 +337,14 @@ EXPORT_SYMBOL(omap_mcbsp_stop); /* polled mcbsp i/o operations */ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) { - u32 base = mcbsp[id].io_base; + u32 base; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + base = mcbsp[id].io_base; writew(buf, base + OMAP_MCBSP_REG_DXR1); /* if frame sync error - clear the error */ if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { @@ -478,8 +366,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) (XRST), base + OMAP_MCBSP_REG_SPCR2); udelay(10); - printk(KERN_ERR - " Could not write to McBSP Register\n"); + dev_err(mcbsp[id].dev, "Could not write to" + " McBSP%d Register\n", mcbsp[id].id); return -2; } } @@ -491,7 +379,14 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite); int omap_mcbsp_pollread(unsigned int id, u16 *buf) { - u32 base = mcbsp[id].io_base; + u32 base; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + base = mcbsp[id].io_base; /* if frame sync error - clear the error */ if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { /* clear error */ @@ -512,8 +407,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf) (RRST), base + OMAP_MCBSP_REG_SPCR1); udelay(10); - printk(KERN_ERR - " Could not read from McBSP Register\n"); + dev_err(mcbsp[id].dev, "Could not read from" + " McBSP%d Register\n", mcbsp[id].id); return -2; } } @@ -530,12 +425,15 @@ EXPORT_SYMBOL(omap_mcbsp_pollread); void omap_mcbsp_xmit_word(unsigned int id, u32 word) { u32 io_base; - omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length; + omap_mcbsp_word_length word_length; - if (omap_mcbsp_check(id) < 0) + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; + } io_base = mcbsp[id].io_base; + word_length = mcbsp[id].tx_word_length; wait_for_completion(&(mcbsp[id].tx_irq_completion)); @@ -549,11 +447,14 @@ u32 omap_mcbsp_recv_word(unsigned int id) { u32 io_base; u16 word_lsb, word_msb = 0; - omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length; + omap_mcbsp_word_length word_length; - if (omap_mcbsp_check(id) < 0) - return -EINVAL; + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + word_length = mcbsp[id].rx_word_length; io_base = mcbsp[id].io_base; wait_for_completion(&(mcbsp[id].rx_irq_completion)); @@ -568,11 +469,20 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word); int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) { - u32 io_base = mcbsp[id].io_base; - omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; - omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; + u32 io_base; + omap_mcbsp_word_length tx_word_length; + omap_mcbsp_word_length rx_word_length; u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + io_base = mcbsp[id].io_base; + tx_word_length = mcbsp[id].tx_word_length; + rx_word_length = mcbsp[id].rx_word_length; + if (tx_word_length != rx_word_length) return -EINVAL; @@ -586,7 +496,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); udelay(10); - printk(KERN_ERR "McBSP transmitter not ready\n"); + dev_err(mcbsp[id].dev, "McBSP%d transmitter not " + "ready\n", mcbsp[id].id); return -EAGAIN; } } @@ -606,7 +517,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); udelay(10); - printk(KERN_ERR "McBSP receiver not ready\n"); + dev_err(mcbsp[id].dev, "McBSP%d receiver not " + "ready\n", mcbsp[id].id); return -EAGAIN; } } @@ -622,11 +534,20 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) { - u32 io_base = mcbsp[id].io_base, clock_word = 0; - omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; - omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; + u32 io_base, clock_word = 0; + omap_mcbsp_word_length tx_word_length; + omap_mcbsp_word_length rx_word_length; u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + io_base = mcbsp[id].io_base; + tx_word_length = mcbsp[id].tx_word_length; + rx_word_length = mcbsp[id].rx_word_length; + if (tx_word_length != rx_word_length) return -EINVAL; @@ -640,7 +561,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); udelay(10); - printk(KERN_ERR "McBSP transmitter not ready\n"); + dev_err(mcbsp[id].dev, "McBSP%d transmitter not " + "ready\n", mcbsp[id].id); return -EAGAIN; } } @@ -660,7 +582,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); udelay(10); - printk(KERN_ERR "McBSP receiver not ready\n"); + dev_err(mcbsp[id].dev, "McBSP%d receiver not " + "ready\n", mcbsp[id].id); return -EAGAIN; } } @@ -691,20 +614,24 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, int dest_port = 0; int sync_dev = 0; - if (omap_mcbsp_check(id) < 0) - return -EINVAL; + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback, &mcbsp[id], &dma_tx_ch)) { - printk(KERN_ERR "OMAP-McBSP: Unable to request DMA channel for" - " McBSP%d TX. Trying IRQ based TX\n", id + 1); + dev_err(mcbsp[id].dev, " Unable to request DMA channel for " + "McBSP%d TX. Trying IRQ based TX\n", + mcbsp[id].id); return -EAGAIN; } mcbsp[id].dma_tx_lch = dma_tx_ch; - DBG("TX DMA on channel %d\n", dma_tx_ch); + dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id, + dma_tx_ch); init_completion(&(mcbsp[id].tx_dma_completion)); @@ -712,7 +639,7 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, src_port = OMAP_DMA_PORT_TIPB; dest_port = OMAP_DMA_PORT_EMIFF; } - if (cpu_is_omap24xx()) + if (cpu_class_is_omap2()) sync_dev = mcbsp[id].dma_tx_sync; omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, @@ -748,20 +675,24 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, int dest_port = 0; int sync_dev = 0; - if (omap_mcbsp_check(id) < 0) - return -EINVAL; + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback, &mcbsp[id], &dma_rx_ch)) { - printk(KERN_ERR "Unable to request DMA channel for McBSP%d RX." - " Trying IRQ based RX\n", id + 1); + dev_err(mcbsp[id].dev, "Unable to request DMA channel for " + "McBSP%d RX. Trying IRQ based RX\n", + mcbsp[id].id); return -EAGAIN; } mcbsp[id].dma_rx_lch = dma_rx_ch; - DBG("RX DMA on channel %d\n", dma_rx_ch); + dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id, + dma_rx_ch); init_completion(&(mcbsp[id].rx_dma_completion)); @@ -769,7 +700,7 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, src_port = OMAP_DMA_PORT_TIPB; dest_port = OMAP_DMA_PORT_EMIFF; } - if (cpu_is_omap24xx()) + if (cpu_class_is_omap2()) sync_dev = mcbsp[id].dma_rx_sync; omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, @@ -808,8 +739,10 @@ void omap_mcbsp_set_spi_mode(unsigned int id, { struct omap_mcbsp_reg_cfg mcbsp_cfg; - if (omap_mcbsp_check(id) < 0) + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); return; + } memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); @@ -870,182 +803,93 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. * 730 has only 2 McBSP, and both of them are MPU peripherals. */ -struct omap_mcbsp_info { - u32 virt_base; - u8 dma_rx_sync, dma_tx_sync; - u16 rx_irq, tx_irq; -}; +static int __init omap_mcbsp_probe(struct platform_device *pdev) +{ + struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; + int id = pdev->id - 1; + int ret = 0; -#ifdef CONFIG_ARCH_OMAP730 -static const struct omap_mcbsp_info mcbsp_730[] = { - [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE), - .dma_rx_sync = OMAP_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP_DMA_MCBSP1_TX, - .rx_irq = INT_730_McBSP1RX, - .tx_irq = INT_730_McBSP1TX }, - [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE), - .dma_rx_sync = OMAP_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP_DMA_MCBSP3_TX, - .rx_irq = INT_730_McBSP2RX, - .tx_irq = INT_730_McBSP2TX }, -}; -#endif - -#ifdef CONFIG_ARCH_OMAP15XX -static const struct omap_mcbsp_info mcbsp_1510[] = { - [0] = { .virt_base = OMAP1510_MCBSP1_BASE, - .dma_rx_sync = OMAP_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP_DMA_MCBSP1_TX, - .rx_irq = INT_McBSP1RX, - .tx_irq = INT_McBSP1TX }, - [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE), - .dma_rx_sync = OMAP_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP_DMA_MCBSP2_TX, - .rx_irq = INT_1510_SPI_RX, - .tx_irq = INT_1510_SPI_TX }, - [2] = { .virt_base = OMAP1510_MCBSP3_BASE, - .dma_rx_sync = OMAP_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP_DMA_MCBSP3_TX, - .rx_irq = INT_McBSP3RX, - .tx_irq = INT_McBSP3TX }, -}; -#endif - -#if defined(CONFIG_ARCH_OMAP16XX) -static const struct omap_mcbsp_info mcbsp_1610[] = { - [0] = { .virt_base = OMAP1610_MCBSP1_BASE, - .dma_rx_sync = OMAP_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP_DMA_MCBSP1_TX, - .rx_irq = INT_McBSP1RX, - .tx_irq = INT_McBSP1TX }, - [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE), - .dma_rx_sync = OMAP_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP_DMA_MCBSP2_TX, - .rx_irq = INT_1610_McBSP2_RX, - .tx_irq = INT_1610_McBSP2_TX }, - [2] = { .virt_base = OMAP1610_MCBSP3_BASE, - .dma_rx_sync = OMAP_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP_DMA_MCBSP3_TX, - .rx_irq = INT_McBSP3RX, - .tx_irq = INT_McBSP3TX }, -}; -#endif - -#if defined(CONFIG_ARCH_OMAP24XX) -static const struct omap_mcbsp_info mcbsp_24xx[] = { - [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), - .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, - }, - [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), - .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, - }, -}; -#endif + if (!pdata) { + dev_err(&pdev->dev, "McBSP device initialized without" + "platform data\n"); + ret = -EINVAL; + goto exit; + } + + dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id); + + if (id >= OMAP_MAX_MCBSP_COUNT) { + dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id); + ret = -EINVAL; + goto exit; + } + + spin_lock_init(&mcbsp[id].lock); + mcbsp[id].id = id + 1; + mcbsp[id].free = 1; + mcbsp[id].dma_tx_lch = -1; + mcbsp[id].dma_rx_lch = -1; + + mcbsp[id].io_base = pdata->virt_base; + /* Default I/O is IRQ based */ + mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO; + mcbsp[id].tx_irq = pdata->tx_irq; + mcbsp[id].rx_irq = pdata->rx_irq; + mcbsp[id].dma_rx_sync = pdata->dma_rx_sync; + mcbsp[id].dma_tx_sync = pdata->dma_tx_sync; + + if (pdata->clk_name) + mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name); + if (IS_ERR(mcbsp[id].clk)) { + mcbsp[id].free = 0; + dev_err(&pdev->dev, + "Invalid clock configuration for McBSP%d.\n", + mcbsp[id].id); + ret = -EINVAL; + goto exit; + } + + mcbsp[id].pdata = pdata; + mcbsp[id].dev = &pdev->dev; + platform_set_drvdata(pdev, &mcbsp[id]); + +exit: + return ret; +} -static int __init omap_mcbsp_init(void) +static int omap_mcbsp_remove(struct platform_device *pdev) { - int mcbsp_count = 0, i; - static const struct omap_mcbsp_info *mcbsp_info; + struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); - printk(KERN_INFO "Initializing OMAP McBSP system\n"); + platform_set_drvdata(pdev, NULL); + if (mcbsp) { -#ifdef CONFIG_ARCH_OMAP1 - mcbsp_dsp_ck = clk_get(0, "dsp_ck"); - if (IS_ERR(mcbsp_dsp_ck)) { - printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); - return PTR_ERR(mcbsp_dsp_ck); - } - mcbsp_api_ck = clk_get(0, "api_ck"); - if (IS_ERR(mcbsp_api_ck)) { - printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n"); - return PTR_ERR(mcbsp_api_ck); - } - mcbsp_dspxor_ck = clk_get(0, "dspxor_ck"); - if (IS_ERR(mcbsp_dspxor_ck)) { - printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); - return PTR_ERR(mcbsp_dspxor_ck); - } -#endif -#ifdef CONFIG_ARCH_OMAP2 - mcbsp1_ick = clk_get(0, "mcbsp1_ick"); - if (IS_ERR(mcbsp1_ick)) { - printk(KERN_ERR "mcbsp: could not acquire " - "mcbsp1_ick handle.\n"); - return PTR_ERR(mcbsp1_ick); - } - mcbsp1_fck = clk_get(0, "mcbsp1_fck"); - if (IS_ERR(mcbsp1_fck)) { - printk(KERN_ERR "mcbsp: could not acquire " - "mcbsp1_fck handle.\n"); - return PTR_ERR(mcbsp1_fck); - } - mcbsp2_ick = clk_get(0, "mcbsp2_ick"); - if (IS_ERR(mcbsp2_ick)) { - printk(KERN_ERR "mcbsp: could not acquire " - "mcbsp2_ick handle.\n"); - return PTR_ERR(mcbsp2_ick); - } - mcbsp2_fck = clk_get(0, "mcbsp2_fck"); - if (IS_ERR(mcbsp2_fck)) { - printk(KERN_ERR "mcbsp: could not acquire " - "mcbsp2_fck handle.\n"); - return PTR_ERR(mcbsp2_fck); - } -#endif + if (mcbsp->pdata && mcbsp->pdata->ops && + mcbsp->pdata->ops->free) + mcbsp->pdata->ops->free(mcbsp->id); -#ifdef CONFIG_ARCH_OMAP730 - if (cpu_is_omap730()) { - mcbsp_info = mcbsp_730; - mcbsp_count = ARRAY_SIZE(mcbsp_730); - } -#endif -#ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap15xx()) { - mcbsp_info = mcbsp_1510; - mcbsp_count = ARRAY_SIZE(mcbsp_1510); - } -#endif -#if defined(CONFIG_ARCH_OMAP16XX) - if (cpu_is_omap16xx()) { - mcbsp_info = mcbsp_1610; - mcbsp_count = ARRAY_SIZE(mcbsp_1610); - } -#endif -#if defined(CONFIG_ARCH_OMAP24XX) - if (cpu_is_omap24xx()) { - mcbsp_info = mcbsp_24xx; - mcbsp_count = ARRAY_SIZE(mcbsp_24xx); - omap2_mcbsp2_mux_setup(); - } -#endif - for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { - if (i >= mcbsp_count) { - mcbsp[i].io_base = 0; - mcbsp[i].free = 0; - continue; - } - mcbsp[i].id = i + 1; - mcbsp[i].free = 1; - mcbsp[i].dma_tx_lch = -1; - mcbsp[i].dma_rx_lch = -1; - - mcbsp[i].io_base = mcbsp_info[i].virt_base; - /* Default I/O is IRQ based */ - mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; - mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; - mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; - mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; - mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync; - spin_lock_init(&mcbsp[i].lock); + clk_disable(mcbsp->clk); + clk_put(mcbsp->clk); + + mcbsp->clk = NULL; + mcbsp->free = 0; + mcbsp->dev = NULL; } return 0; } -arch_initcall(omap_mcbsp_init); +static struct platform_driver omap_mcbsp_driver = { + .probe = omap_mcbsp_probe, + .remove = omap_mcbsp_remove, + .driver = { + .name = "omap-mcbsp", + }, +}; + +int __init omap_mcbsp_init(void) +{ + /* Register the McBSP driver */ + return platform_driver_register(&omap_mcbsp_driver); +} + diff --git a/include/asm-arm/arch-omap/mcbsp.h b/include/asm-arm/arch-omap/mcbsp.h index c7a0cc1c4e9..26c78f67dc8 100644 --- a/include/asm-arm/arch-omap/mcbsp.h +++ b/include/asm-arm/arch-omap/mcbsp.h @@ -24,7 +24,11 @@ #ifndef __ASM_ARCH_OMAP_MCBSP_H #define __ASM_ARCH_OMAP_MCBSP_H +#include +#include + #include +#include #define OMAP730_MCBSP1_BASE 0xfffb1000 #define OMAP730_MCBSP2_BASE 0xfffb1800 @@ -40,6 +44,9 @@ #define OMAP24XX_MCBSP1_BASE 0x48074000 #define OMAP24XX_MCBSP2_BASE 0x48076000 +#define OMAP34XX_MCBSP1_BASE 0x48074000 +#define OMAP34XX_MCBSP2_BASE 0x49022000 + #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) #define OMAP_MCBSP_REG_DRR2 0x00 @@ -74,7 +81,8 @@ #define OMAP_MCBSP_REG_XCERG 0x3A #define OMAP_MCBSP_REG_XCERH 0x3C -#define OMAP_MAX_MCBSP_COUNT 3 +#define OMAP_MAX_MCBSP_COUNT 3 +#define MAX_MCBSP_CLOCKS 3 #define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1) #define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1) @@ -117,7 +125,8 @@ #define OMAP_MCBSP_REG_XCERG 0x74 #define OMAP_MCBSP_REG_XCERH 0x78 -#define OMAP_MAX_MCBSP_COUNT 2 +#define OMAP_MAX_MCBSP_COUNT 2 +#define MAX_MCBSP_CLOCKS 2 #define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1) #define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1) @@ -298,6 +307,55 @@ struct omap_mcbsp_spi_cfg { omap_mcbsp_word_length word_length; }; +/* Platform specific configuration */ +struct omap_mcbsp_ops { + void (*request)(unsigned int); + void (*free)(unsigned int); + int (*check)(unsigned int); +}; + +struct omap_mcbsp_platform_data { + u32 virt_base; + u8 dma_rx_sync, dma_tx_sync; + u16 rx_irq, tx_irq; + struct omap_mcbsp_ops *ops; + char const *clk_name; +}; + +struct omap_mcbsp { + struct device *dev; + u32 io_base; + u8 id; + u8 free; + omap_mcbsp_word_length rx_word_length; + omap_mcbsp_word_length tx_word_length; + + omap_mcbsp_io_type_t io_type; /* IRQ or poll */ + /* IRQ based TX/RX */ + int rx_irq; + int tx_irq; + + /* DMA stuff */ + u8 dma_rx_sync; + short dma_rx_lch; + u8 dma_tx_sync; + short dma_tx_lch; + + /* Completion queues */ + struct completion tx_irq_completion; + struct completion rx_irq_completion; + struct completion tx_dma_completion; + struct completion rx_dma_completion; + + /* Protect the field .free, while checking if the mcbsp is in use */ + spinlock_t lock; + struct omap_mcbsp_platform_data *pdata; + struct clk *clk; +}; + +int omap_mcbsp_init(void); +void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, + int size); void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); int omap_mcbsp_request(unsigned int id); void omap_mcbsp_free(unsigned int id); -- cgit v1.2.3-70-g09d2 From 44f78f43b349d19d378a996c4a2d9fcdff771b1e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:41 +0300 Subject: ARM: OMAP: Clean up interrupt lines to fix warnings for multi-omap If boards with different NR_IRQS are compiled together, tons of compiler warnings are emitted about redefining NR_IRQS. This patch fixes the problem by adding up NR_IRQS in a common place. Patch also removes quite a bit of now unnecessary code. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/fpga.c | 10 +++--- include/asm-arm/arch-omap/board-2430sdp.h | 5 --- include/asm-arm/arch-omap/board-h3.h | 6 ---- include/asm-arm/arch-omap/board-innovator.h | 3 -- include/asm-arm/arch-omap/board-perseus2.h | 6 ---- include/asm-arm/arch-omap/fpga.h | 49 ++++++++++++++--------------- include/asm-arm/arch-omap/irqs.h | 44 ++++++++++++++++++++------ 7 files changed, 64 insertions(+), 59 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c index 30e18810904..0cf62ef5ecb 100644 --- a/arch/arm/mach-omap1/fpga.c +++ b/arch/arm/mach-omap1/fpga.c @@ -32,7 +32,7 @@ static void fpga_mask_irq(unsigned int irq) { - irq -= OMAP1510_IH_FPGA_BASE; + irq -= OMAP_FPGA_IRQ_BASE; if (irq < 8) __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) @@ -65,7 +65,7 @@ static void fpga_ack_irq(unsigned int irq) static void fpga_unmask_irq(unsigned int irq) { - irq -= OMAP1510_IH_FPGA_BASE; + irq -= OMAP_FPGA_IRQ_BASE; if (irq < 8) __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)), @@ -95,8 +95,8 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc) if (!stat) return; - for (fpga_irq = OMAP1510_IH_FPGA_BASE; - (fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat; + for (fpga_irq = OMAP_FPGA_IRQ_BASE; + (fpga_irq < OMAP_FPGA_IRQ_END) && stat; fpga_irq++, stat >>= 1) { if (stat & 1) { d = irq_desc + fpga_irq; @@ -151,7 +151,7 @@ void omap1510_fpga_init_irq(void) __raw_writeb(0, OMAP1510_FPGA_IMR_HI); __raw_writeb(0, INNOVATOR_FPGA_IMR2); - for (i = OMAP1510_IH_FPGA_BASE; i < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS); i++) { + for (i = OMAP_FPGA_IRQ_BASE; i < OMAP_FPGA_IRQ_END; i++) { if (i == OMAP1510_INT_FPGA_TS) { /* diff --git a/include/asm-arm/arch-omap/board-2430sdp.h b/include/asm-arm/arch-omap/board-2430sdp.h index e9c65ce3cb1..c7db9004ec3 100644 --- a/include/asm-arm/arch-omap/board-2430sdp.h +++ b/include/asm-arm/arch-omap/board-2430sdp.h @@ -36,9 +36,4 @@ #define TWL4030_IRQNUM INT_24XX_SYS_NIRQ -/* TWL4030 Primary Interrupt Handler (PIH) interrupts */ -#define IH_TWL4030_BASE IH_BOARD_BASE -#define IH_TWL4030_END (IH_TWL4030_BASE+8) -#define NR_IRQS (IH_TWL4030_END) - #endif /* __ASM_ARCH_OMAP_2430SDP_H */ diff --git a/include/asm-arm/arch-omap/board-h3.h b/include/asm-arm/arch-omap/board-h3.h index 0f6404435ea..c5d0f32a40a 100644 --- a/include/asm-arm/arch-omap/board-h3.h +++ b/include/asm-arm/arch-omap/board-h3.h @@ -30,12 +30,6 @@ /* In OMAP1710 H3 the Ethernet is directly connected to CS1 */ #define OMAP1710_ETHR_START 0x04000300 -#define MAXIRQNUM (IH_BOARD_BASE) -#define MAXFIQNUM MAXIRQNUM -#define MAXSWINUM MAXIRQNUM - -#define NR_IRQS (MAXIRQNUM + 1) - extern void h3_mmc_init(void); extern void h3_mmc_slot_cover_handler(void *arg, int state); diff --git a/include/asm-arm/arch-omap/board-innovator.h b/include/asm-arm/arch-omap/board-innovator.h index 56d2c98e143..9ca03dec9d3 100644 --- a/include/asm-arm/arch-omap/board-innovator.h +++ b/include/asm-arm/arch-omap/board-innovator.h @@ -36,9 +36,6 @@ #define OMAP1510P1_EMIFS_PRI_VALUE 0x00 #define OMAP1510P1_EMIFF_PRI_VALUE 0x00 -#define NR_FPGA_IRQS 24 -#define NR_IRQS (IH_BOARD_BASE + NR_FPGA_IRQS) - #ifndef __ASSEMBLY__ void fpga_write(unsigned char val, int reg); unsigned char fpga_read(int reg); diff --git a/include/asm-arm/arch-omap/board-perseus2.h b/include/asm-arm/arch-omap/board-perseus2.h index eb74420cb43..d7429cb0f72 100644 --- a/include/asm-arm/arch-omap/board-perseus2.h +++ b/include/asm-arm/arch-omap/board-perseus2.h @@ -36,10 +36,4 @@ #define OMAP_SDRAM_DEVICE D256M_1X16_4B #endif -#define MAXIRQNUM IH_BOARD_BASE -#define MAXFIQNUM MAXIRQNUM -#define MAXSWINUM MAXIRQNUM - -#define NR_IRQS (MAXIRQNUM + 1) - #endif diff --git a/include/asm-arm/arch-omap/fpga.h b/include/asm-arm/arch-omap/fpga.h index 6a883e0bdbb..f420881d2a3 100644 --- a/include/asm-arm/arch-omap/fpga.h +++ b/include/asm-arm/arch-omap/fpga.h @@ -169,30 +169,29 @@ struct h2p2_dbg_fpga { #define OMAP1510_INT_FPGA (IH_GPIO_BASE + 13) /* IRQ Numbers for interrupts muxed through the FPGA */ -#define OMAP1510_IH_FPGA_BASE IH_BOARD_BASE -#define OMAP1510_INT_FPGA_ATN (OMAP1510_IH_FPGA_BASE + 0) -#define OMAP1510_INT_FPGA_ACK (OMAP1510_IH_FPGA_BASE + 1) -#define OMAP1510_INT_FPGA2 (OMAP1510_IH_FPGA_BASE + 2) -#define OMAP1510_INT_FPGA3 (OMAP1510_IH_FPGA_BASE + 3) -#define OMAP1510_INT_FPGA4 (OMAP1510_IH_FPGA_BASE + 4) -#define OMAP1510_INT_FPGA5 (OMAP1510_IH_FPGA_BASE + 5) -#define OMAP1510_INT_FPGA6 (OMAP1510_IH_FPGA_BASE + 6) -#define OMAP1510_INT_FPGA7 (OMAP1510_IH_FPGA_BASE + 7) -#define OMAP1510_INT_FPGA8 (OMAP1510_IH_FPGA_BASE + 8) -#define OMAP1510_INT_FPGA9 (OMAP1510_IH_FPGA_BASE + 9) -#define OMAP1510_INT_FPGA10 (OMAP1510_IH_FPGA_BASE + 10) -#define OMAP1510_INT_FPGA11 (OMAP1510_IH_FPGA_BASE + 11) -#define OMAP1510_INT_FPGA12 (OMAP1510_IH_FPGA_BASE + 12) -#define OMAP1510_INT_ETHER (OMAP1510_IH_FPGA_BASE + 13) -#define OMAP1510_INT_FPGAUART1 (OMAP1510_IH_FPGA_BASE + 14) -#define OMAP1510_INT_FPGAUART2 (OMAP1510_IH_FPGA_BASE + 15) -#define OMAP1510_INT_FPGA_TS (OMAP1510_IH_FPGA_BASE + 16) -#define OMAP1510_INT_FPGA17 (OMAP1510_IH_FPGA_BASE + 17) -#define OMAP1510_INT_FPGA_CAM (OMAP1510_IH_FPGA_BASE + 18) -#define OMAP1510_INT_FPGA_RTC_A (OMAP1510_IH_FPGA_BASE + 19) -#define OMAP1510_INT_FPGA_RTC_B (OMAP1510_IH_FPGA_BASE + 20) -#define OMAP1510_INT_FPGA_CD (OMAP1510_IH_FPGA_BASE + 21) -#define OMAP1510_INT_FPGA22 (OMAP1510_IH_FPGA_BASE + 22) -#define OMAP1510_INT_FPGA23 (OMAP1510_IH_FPGA_BASE + 23) +#define OMAP1510_INT_FPGA_ATN (OMAP_FPGA_IRQ_BASE + 0) +#define OMAP1510_INT_FPGA_ACK (OMAP_FPGA_IRQ_BASE + 1) +#define OMAP1510_INT_FPGA2 (OMAP_FPGA_IRQ_BASE + 2) +#define OMAP1510_INT_FPGA3 (OMAP_FPGA_IRQ_BASE + 3) +#define OMAP1510_INT_FPGA4 (OMAP_FPGA_IRQ_BASE + 4) +#define OMAP1510_INT_FPGA5 (OMAP_FPGA_IRQ_BASE + 5) +#define OMAP1510_INT_FPGA6 (OMAP_FPGA_IRQ_BASE + 6) +#define OMAP1510_INT_FPGA7 (OMAP_FPGA_IRQ_BASE + 7) +#define OMAP1510_INT_FPGA8 (OMAP_FPGA_IRQ_BASE + 8) +#define OMAP1510_INT_FPGA9 (OMAP_FPGA_IRQ_BASE + 9) +#define OMAP1510_INT_FPGA10 (OMAP_FPGA_IRQ_BASE + 10) +#define OMAP1510_INT_FPGA11 (OMAP_FPGA_IRQ_BASE + 11) +#define OMAP1510_INT_FPGA12 (OMAP_FPGA_IRQ_BASE + 12) +#define OMAP1510_INT_ETHER (OMAP_FPGA_IRQ_BASE + 13) +#define OMAP1510_INT_FPGAUART1 (OMAP_FPGA_IRQ_BASE + 14) +#define OMAP1510_INT_FPGAUART2 (OMAP_FPGA_IRQ_BASE + 15) +#define OMAP1510_INT_FPGA_TS (OMAP_FPGA_IRQ_BASE + 16) +#define OMAP1510_INT_FPGA17 (OMAP_FPGA_IRQ_BASE + 17) +#define OMAP1510_INT_FPGA_CAM (OMAP_FPGA_IRQ_BASE + 18) +#define OMAP1510_INT_FPGA_RTC_A (OMAP_FPGA_IRQ_BASE + 19) +#define OMAP1510_INT_FPGA_RTC_B (OMAP_FPGA_IRQ_BASE + 20) +#define OMAP1510_INT_FPGA_CD (OMAP_FPGA_IRQ_BASE + 21) +#define OMAP1510_INT_FPGA22 (OMAP_FPGA_IRQ_BASE + 22) +#define OMAP1510_INT_FPGA23 (OMAP_FPGA_IRQ_BASE + 23) #endif diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h index 87973654e62..7464c694859 100644 --- a/include/asm-arm/arch-omap/irqs.h +++ b/include/asm-arm/arch-omap/irqs.h @@ -285,7 +285,41 @@ #define OMAP_MAX_GPIO_LINES 192 #define IH_GPIO_BASE (128 + IH2_BASE) #define IH_MPUIO_BASE (OMAP_MAX_GPIO_LINES + IH_GPIO_BASE) -#define IH_BOARD_BASE (16 + IH_MPUIO_BASE) +#define OMAP_IRQ_END (IH_MPUIO_BASE + 16) + +/* External FPGA handles interrupts on Innovator boards */ +#define OMAP_FPGA_IRQ_BASE (OMAP_IRQ_END) +#ifdef CONFIG_MACH_OMAP_INNOVATOR +#define OMAP_FPGA_NR_IRQS 24 +#else +#define OMAP_FPGA_NR_IRQS 0 +#endif +#define OMAP_FPGA_IRQ_END (OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS) + +/* External TWL4030 can handle interrupts on 2430 and 34xx boards */ +#define TWL4030_IRQ_BASE (OMAP_FPGA_IRQ_END) +#ifdef CONFIG_TWL4030_CORE +#define TWL4030_BASE_NR_IRQS 8 +#define TWL4030_PWR_NR_IRQS 8 +#else +#define TWL4030_BASE_NR_IRQS 0 +#define TWL4030_PWR_NR_IRQS 0 +#endif +#define TWL4030_IRQ_END (TWL4030_IRQ_BASE + TWL4030_BASE_NR_IRQS) +#define TWL4030_PWR_IRQ_BASE TWL4030_IRQ_END +#define TWL4030_PWR_IRQ_END (TWL4030_PWR_IRQ_BASE + TWL4030_PWR_NR_IRQS) + +/* External TWL4030 gpio interrupts are optional */ +#define TWL4030_GPIO_IRQ_BASE TWL4030_PWR_IRQ_END +#ifdef CONFIG_TWL4030_GPIO +#define TWL4030_GPIO_NR_IRQS 18 +#else +#define TWL4030_GPIO_NR_IRQS 0 +#endif +#define TWL4030_GPIO_IRQ_END (TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS) + +/* Total number of interrupts depends on the enabled blocks above */ +#define NR_IRQS TWL4030_GPIO_IRQ_END #define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) @@ -293,14 +327,6 @@ extern void omap_init_irq(void); #endif -/* - * The definition of NR_IRQS is in board-specific header file, which is - * included via hardware.h - */ #include -#ifndef NR_IRQS -#define NR_IRQS IH_BOARD_BASE -#endif - #endif -- cgit v1.2.3-70-g09d2 From 137b3ee27ab1b27dba081542476054836978ca45 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Thu, 3 Jul 2008 12:24:41 +0300 Subject: ARM: OMAP: CLKFW: Initial debugfs support for omap clock framework debugfs can provide the infrastructure to trace the dependencies of clock tree hierarchy quite visibly. This patch enables to keep track of clock tree hierarchy and expose their attributes under each clock directry as below: omap:~# tree -d -L 2 /debug/clock/omap_32k_fck/ /debug/clock/omap_32k_fck/ |-- gpt10_fck |-- gpt11_fck |-- gpt1_fck |-- per_32k_alwon_fck | |-- gpio2_fck | |-- gpio3_fck | |-- gpio4_fck | |-- gpio5_fck | |-- gpio6_fck | `-- wdt3_fck |-- ts_fck `-- wkup_32k_fck |-- gpio1_fck `-- wdt2_fck 14 directories omap:~# tree /debug/clock/omap_32k_fck/gpt10_fck/ /debug/clock/omap_32k_fck/gpt10_fck/ |-- flags |-- rate `-- usecount 0 directories, 3 files Although, compared with David Brownell's small patch, this may look bit overkilling, I expect that this debugfs can deal with other PRCM complexities at the same time. For example, powerdomain dependencies can be expressed by using symbolic links of these clocks if powerdomain supports dubgfs as well. Signed-off-by: Hiroshi DOYU Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/clock.c | 128 +++++++++++++++++++++++++++----------- include/asm-arm/arch-omap/clock.h | 3 + 2 files changed, 95 insertions(+), 36 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 2db5580048d..c2e741de020 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/plat-omap/clock.c * - * Copyright (C) 2004 - 2005 Nokia corporation + * Copyright (C) 2004 - 2008 Nokia corporation * Written by Tuukka Tikkanen * * Modified for omap shared clock framework by Tony Lindgren @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -33,41 +34,6 @@ static DEFINE_SPINLOCK(clockfw_lock); static struct clk_functions *arch_clock; -#ifdef CONFIG_PM_DEBUG - -static void print_parents(struct clk *clk) -{ - struct clk *p; - int printed = 0; - - list_for_each_entry(p, &clocks, node) { - if (p->parent == clk && p->usecount) { - if (!clk->usecount && !printed) { - printk("MISMATCH: %s\n", clk->name); - printed = 1; - } - printk("\t%-15s\n", p->name); - } - } -} - -void clk_print_usecounts(void) -{ - unsigned long flags; - struct clk *p; - - spin_lock_irqsave(&clockfw_lock, flags); - list_for_each_entry(p, &clocks, node) { - if (p->usecount) - printk("%-15s: %d\n", p->name, p->usecount); - print_parents(p); - - } - spin_unlock_irqrestore(&clockfw_lock, flags); -} - -#endif - /*------------------------------------------------------------------------- * Standard clock functions defined in include/linux/clk.h *-------------------------------------------------------------------------*/ @@ -446,3 +412,93 @@ int __init clk_init(struct clk_functions * custom_clocks) return 0; } +#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) +/* + * debugfs support to trace clock tree hierarchy and attributes + */ +static struct dentry *clk_debugfs_root; + +static int clk_debugfs_register_one(struct clk *c) +{ + int err; + struct dentry *d, *child; + struct clk *pa = c->parent; + char s[255]; + char *p = s; + + p += sprintf(p, "%s", c->name); + if (c->id != 0) + sprintf(p, ":%d", c->id); + d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root); + if (IS_ERR(d)) + return PTR_ERR(d); + c->dent = d; + + d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount); + if (IS_ERR(d)) { + err = PTR_ERR(d); + goto err_out; + } + d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); + if (IS_ERR(d)) { + err = PTR_ERR(d); + goto err_out; + } + d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags); + if (IS_ERR(d)) { + err = PTR_ERR(d); + goto err_out; + } + return 0; + +err_out: + d = c->dent; + list_for_each_entry(child, &d->d_subdirs, d_u.d_child) + debugfs_remove(child); + debugfs_remove(c->dent); + return err; +} + +static int clk_debugfs_register(struct clk *c) +{ + int err; + struct clk *pa = c->parent; + + if (pa && !pa->dent) { + err = clk_debugfs_register(pa); + if (err) + return err; + } + + if (!c->dent) { + err = clk_debugfs_register_one(c); + if (err) + return err; + } + return 0; +} + +static int __init clk_debugfs_init(void) +{ + struct clk *c; + struct dentry *d; + int err; + + d = debugfs_create_dir("clock", NULL); + if (IS_ERR(d)) + return PTR_ERR(d); + clk_debugfs_root = d; + + list_for_each_entry(c, &clocks, node) { + err = clk_debugfs_register(c); + if (err) + goto err_out; + } + return 0; +err_out: + debugfs_remove(clk_debugfs_root); /* REVISIT: Cleanup correctly */ + return err; +} +late_initcall(clk_debugfs_init); + +#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */ diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h index 12a5e4de951..8490fbba39d 100644 --- a/include/asm-arm/arch-omap/clock.h +++ b/include/asm-arm/arch-omap/clock.h @@ -71,6 +71,9 @@ struct clk { __u8 rate_offset; __u8 src_offset; #endif +#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) + struct dentry *dent; /* For visible tree hierarchy */ +#endif }; struct cpufreq_frequency_table; -- cgit v1.2.3-70-g09d2 From 030b15457d8069a6255579a28db196e002cb9c86 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:41 +0300 Subject: ARM: OMAP: Change omap_cf.c and omap_nor.c to use omap_readw/writew instead of __REG Change omap_cf.c and omap_nor.c to use omap_readw/writew instead of __REG. This is needed for multi-omap in the future. Cc: David Brownell Cc: linux-pcmcia@lists.infradead.org Cc: linux-mtd@lists.infradead.org Signed-off-by: Tony Lindren --- arch/arm/mach-omap1/board-osk.c | 13 ++++++++++--- drivers/mtd/maps/omap_nor.c | 23 ++++++++++++++++------- drivers/pcmcia/omap_cf.c | 25 +++++++++++++------------ include/asm-arm/arch-omap/tc.h | 10 ++++------ 4 files changed, 43 insertions(+), 28 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index a66505f58b1..82ec34c43bc 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -267,13 +267,17 @@ static struct i2c_board_info __initdata osk_i2c_board_info[] = { static void __init osk_init_smc91x(void) { + u32 l; + if ((gpio_request(0, "smc_irq")) < 0) { printk("Error requesting gpio 0 for smc91x irq\n"); return; } /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ - EMIFS_CCS(1) |= 0x3; + l = omap_readl(EMIFS_CCS(1)); + l |= 0x3; + omap_writel(l, EMIFS_CCS(1)); } static void __init osk_init_cf(void) @@ -526,13 +530,16 @@ static void __init osk_mistral_init(void) { } static void __init osk_init(void) { + u32 l; + /* Workaround for wrong CS3 (NOR flash) timing * There are some U-Boot versions out there which configure * wrong CS3 memory timings. This mainly leads to CRC * or similar errors if you use NOR flash (e.g. with JFFS2) */ - if (EMIFS_CCS(3) != EMIFS_CS3_VAL) - EMIFS_CCS(3) = EMIFS_CS3_VAL; + l = omap_readl(EMIFS_CCS(3)); + if (l != EMIFS_CS3_VAL) + omap_writel(EMIFS_CS3_VAL, EMIFS_CCS(3)); osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); osk_flash_resource.end += SZ_32M - 1; diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c index c12d8056beb..68eec6c6c51 100644 --- a/drivers/mtd/maps/omap_nor.c +++ b/drivers/mtd/maps/omap_nor.c @@ -60,13 +60,22 @@ struct omapflash_info { static void omap_set_vpp(struct map_info *map, int enable) { static int count; - - if (enable) { - if (count++ == 0) - OMAP_EMIFS_CONFIG_REG |= OMAP_EMIFS_CONFIG_WP; - } else { - if (count && (--count == 0)) - OMAP_EMIFS_CONFIG_REG &= ~OMAP_EMIFS_CONFIG_WP; + u32 l; + + if (cpu_class_is_omap1()) { + if (enable) { + if (count++ == 0) { + l = omap_readl(EMIFS_CONFIG); + l |= OMAP_EMIFS_CONFIG_WP; + omap_writel(l, EMIFS_CONFIG); + } + } else { + if (count && (--count == 0)) { + l = omap_readl(EMIFS_CONFIG); + l &= ~OMAP_EMIFS_CONFIG_WP; + omap_writel(l, EMIFS_CONFIG); + } + } } } diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 46314b42076..569b746b573 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -38,19 +38,19 @@ #define CF_BASE 0xfffe2800 /* status; read after IRQ */ -#define CF_STATUS_REG __REG16(CF_BASE + 0x00) +#define CF_STATUS (CF_BASE + 0x00) # define CF_STATUS_BAD_READ (1 << 2) # define CF_STATUS_BAD_WRITE (1 << 1) # define CF_STATUS_CARD_DETECT (1 << 0) /* which chipselect (CS0..CS3) is used for CF (active low) */ -#define CF_CFG_REG __REG16(CF_BASE + 0x02) +#define CF_CFG (CF_BASE + 0x02) /* card reset */ -#define CF_CONTROL_REG __REG16(CF_BASE + 0x04) +#define CF_CONTROL (CF_BASE + 0x04) # define CF_CONTROL_RESET (1 << 0) -#define omap_cf_present() (!(CF_STATUS_REG & CF_STATUS_CARD_DETECT)) +#define omap_cf_present() (!(omap_readw(CF_STATUS) & CF_STATUS_CARD_DETECT)) /*--------------------------------------------------------------------------*/ @@ -139,11 +139,11 @@ omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) return -EINVAL; } - control = CF_CONTROL_REG; + control = omap_readw(CF_CONTROL); if (s->flags & SS_RESET) - CF_CONTROL_REG = CF_CONTROL_RESET; + omap_writew(CF_CONTROL_RESET, CF_CONTROL); else - CF_CONTROL_REG = 0; + omap_writew(0, CF_CONTROL); pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); @@ -270,7 +270,7 @@ static int __init omap_cf_probe(struct platform_device *pdev) omap_cfg_reg(V10_1610_CF_IREQ); omap_cfg_reg(W10_1610_CF_RESET); - CF_CFG_REG = ~(1 << seg); + omap_writew(~(1 << seg), CF_CFG); pr_info("%s: cs%d on irq %d\n", driver_name, seg, irq); @@ -279,14 +279,15 @@ static int __init omap_cf_probe(struct platform_device *pdev) * CF/PCMCIA variants... */ pr_debug("%s: cs%d, previous ccs %08x acs %08x\n", driver_name, - seg, EMIFS_CCS(seg), EMIFS_ACS(seg)); - EMIFS_CCS(seg) = 0x0004a1b3; /* synch mode 4 etc */ - EMIFS_ACS(seg) = 0x00000000; /* OE hold/setup */ + seg, omap_readl(EMIFS_CCS(seg)), omap_readl(EMIFS_ACS(seg))); + omap_writel(0x0004a1b3, EMIFS_CCS(seg)); /* synch mode 4 etc */ + omap_writel(0x00000000, EMIFS_ACS(seg)); /* OE hold/setup */ /* CF uses armxor_ck, which is "always" available */ pr_debug("%s: sts %04x cfg %04x control %04x %s\n", driver_name, - CF_STATUS_REG, CF_CFG_REG, CF_CONTROL_REG, + omap_readw(CF_STATUS), omap_readw(CF_CFG), + omap_readw(CF_CONTROL), omap_cf_present() ? "present" : "(not present)"); cf->socket.owner = THIS_MODULE; diff --git a/include/asm-arm/arch-omap/tc.h b/include/asm-arm/arch-omap/tc.h index 8ded218cbea..65a9c82d3bf 100644 --- a/include/asm-arm/arch-omap/tc.h +++ b/include/asm-arm/arch-omap/tc.h @@ -75,16 +75,14 @@ #ifndef __ASSEMBLER__ /* EMIF Slow Interface Configuration Register */ -#define OMAP_EMIFS_CONFIG_REG __REG32(EMIFS_CONFIG) - #define OMAP_EMIFS_CONFIG_FR (1 << 4) #define OMAP_EMIFS_CONFIG_PDE (1 << 3) #define OMAP_EMIFS_CONFIG_PWD_EN (1 << 2) #define OMAP_EMIFS_CONFIG_BM (1 << 1) #define OMAP_EMIFS_CONFIG_WP (1 << 0) -#define EMIFS_CCS(n) __REG32(EMIFS_CS0_CONFIG + (4 * (n))) -#define EMIFS_ACS(n) __REG32(EMIFS_ACS0 + (4 * (n))) +#define EMIFS_CCS(n) (EMIFS_CS0_CONFIG + (4 * (n))) +#define EMIFS_ACS(n) (EMIFS_ACS0 + (4 * (n))) /* Almost all documentation for chip and board memory maps assumes * BM is clear. Most devel boards have a switch to control booting @@ -93,13 +91,13 @@ */ static inline u32 omap_cs0_phys(void) { - return (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM) + return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM) ? OMAP_CS3_PHYS : 0; } static inline u32 omap_cs3_phys(void) { - return (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM) + return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM) ? 0 : OMAP_CS3_PHYS; } -- cgit v1.2.3-70-g09d2 From f35ae6346850f6c192269b09088b20261760f0e0 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:43 +0300 Subject: ARM: OMAP: USB: Change omap USB code to use omap_read/write instead of __REG Change omap USB code to use omap_read/write instead of __REG for multi-omap Cc: David Brownell Cc: linux-usb@vger.kernel.org Cc: i2c@lm-sensors.org Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-osk.c | 5 +- arch/arm/plat-omap/usb.c | 131 +++++++---- drivers/i2c/chips/isp1301_omap.c | 163 ++++++++------ drivers/usb/gadget/omap_udc.c | 468 ++++++++++++++++++++++----------------- drivers/usb/gadget/omap_udc.h | 61 +++-- drivers/usb/host/ohci-omap.c | 5 +- include/asm-arm/arch-omap/usb.h | 23 +- 7 files changed, 499 insertions(+), 357 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 82ec34c43bc..845c66371ca 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -546,7 +546,10 @@ static void __init osk_init(void) platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); omap_board_config = osk_config; omap_board_config_size = ARRAY_SIZE(osk_config); - USB_TRANSCEIVER_CTRL_REG |= (3 << 1); + + l = omap_readl(USB_TRANSCEIVER_CTRL); + l |= (3 << 1); + omap_writel(l, USB_TRANSCEIVER_CTRL); /* irq for tps65010 chip */ /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */ diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index a619475c4b7..2699c16d4da 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c @@ -1,4 +1,4 @@ -/* + /* * arch/arm/plat-omap/usb.c -- platform level USB initialization * * Copyright (C) 2004 Texas Instruments, Inc. @@ -156,8 +156,12 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) if (nwires == 0) { if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { + u32 l; + /* pulldown D+/D- */ - USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1); + l = omap_readl(USB_TRANSCEIVER_CTRL); + l &= ~(3 << 1); + omap_writel(l, USB_TRANSCEIVER_CTRL); } return 0; } @@ -171,6 +175,8 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) /* internal transceiver (unavailable on 17xx, 24xx) */ if (!cpu_class_is_omap2() && nwires == 2) { + u32 l; + // omap_cfg_reg(P9_USB_DP); // omap_cfg_reg(R8_USB_DM); @@ -185,9 +191,11 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) * - OTG support on this port not yet written */ - USB_TRANSCEIVER_CTRL_REG &= ~(7 << 4); + l = omap_readl(USB_TRANSCEIVER_CTRL); + l &= ~(7 << 4); if (!is_device) - USB_TRANSCEIVER_CTRL_REG |= (3 << 1); + l |= (3 << 1); + omap_writel(l, USB_TRANSCEIVER_CTRL); return 3 << 16; } @@ -217,8 +225,13 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) * with VBUS switching and overcurrent detection. */ - if (cpu_class_is_omap1() && nwires != 6) - USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; + if (cpu_class_is_omap1() && nwires != 6) { + u32 l; + + l = omap_readl(USB_TRANSCEIVER_CTRL); + l &= ~CONF_USB2_UNI_R; + omap_writel(l, USB_TRANSCEIVER_CTRL); + } switch (nwires) { case 3: @@ -238,9 +251,13 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) omap_cfg_reg(K20_24XX_USB0_VM); omap2_usb_devconf_set(0, USB_UNIDIR); } else { + u32 l; + omap_cfg_reg(AA9_USB0_VP); omap_cfg_reg(R9_USB0_VM); - USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R; + l = omap_readl(USB_TRANSCEIVER_CTRL); + l |= CONF_USB2_UNI_R; + omap_writel(l, USB_TRANSCEIVER_CTRL); } break; default: @@ -254,8 +271,13 @@ static u32 __init omap_usb1_init(unsigned nwires) { u32 syscon1 = 0; - if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) - USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R; + if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { + u32 l; + + l = omap_readl(USB_TRANSCEIVER_CTRL); + l &= ~CONF_USB1_UNI_R; + omap_writel(l, USB_TRANSCEIVER_CTRL); + } if (cpu_is_omap24xx()) omap2_usb_devconf_clear(1, USB_BIDIR_TLL); @@ -316,8 +338,13 @@ static u32 __init omap_usb1_init(unsigned nwires) syscon1 = 3; omap_cfg_reg(USB1_VP); omap_cfg_reg(USB1_VM); - if (!cpu_is_omap15xx()) - USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R; + if (!cpu_is_omap15xx()) { + u32 l; + + l = omap_readl(USB_TRANSCEIVER_CTRL); + l |= CONF_USB1_UNI_R; + omap_writel(l, USB_TRANSCEIVER_CTRL); + } break; default: bad: @@ -340,8 +367,13 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) if (alt_pingroup || nwires == 0) return 0; - if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) - USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; + if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { + u32 l; + + l = omap_readl(USB_TRANSCEIVER_CTRL); + l &= ~CONF_USB2_UNI_R; + omap_writel(l, USB_TRANSCEIVER_CTRL); + } /* external transceiver */ if (cpu_is_omap15xx()) { @@ -410,9 +442,13 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) omap_cfg_reg(USB2_VP); omap_cfg_reg(USB2_VM); } else { + u32 l; + omap_cfg_reg(AA9_USB2_VP); omap_cfg_reg(R9_USB2_VM); - USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R; + l = omap_readl(USB_TRANSCEIVER_CTRL); + l |= CONF_USB2_UNI_R; + omap_writel(l, USB_TRANSCEIVER_CTRL); } break; default: @@ -531,10 +567,6 @@ static struct platform_device otg_device = { /*-------------------------------------------------------------------------*/ -#define ULPD_CLOCK_CTRL_REG __REG16(ULPD_CLOCK_CTRL) -#define ULPD_SOFT_REQ_REG __REG16(ULPD_SOFT_REQ) - - // FIXME correct answer depends on hmc_mode, // as does (on omap1) any nonzero value for config->otg port number #ifdef CONFIG_USB_GADGET_OMAP @@ -550,17 +582,17 @@ static struct platform_device otg_device = { void __init omap_otg_init(struct omap_usb_config *config) { - u32 syscon = OTG_SYSCON_1_REG & 0xffff; + u32 syscon; int status; int alt_pingroup = 0; /* NOTE: no bus or clock setup (yet?) */ - syscon = OTG_SYSCON_1_REG & 0xffff; + syscon = omap_readl(OTG_SYSCON_1) & 0xffff; if (!(syscon & OTG_RESET_DONE)) pr_debug("USB resets not complete?\n"); - // OTG_IRQ_EN_REG = 0; + //omap_writew(0, OTG_IRQ_EN); /* pin muxing and transceiver pinouts */ if (config->pins[0] > 2) /* alt pingroup 2 */ @@ -568,8 +600,8 @@ omap_otg_init(struct omap_usb_config *config) syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config)); syscon |= omap_usb1_init(config->pins[1]); syscon |= omap_usb2_init(config->pins[2], alt_pingroup); - pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon); - OTG_SYSCON_1_REG = syscon; + pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); + omap_writel(syscon, OTG_SYSCON_1); syscon = config->hmc_mode; syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; @@ -578,9 +610,10 @@ omap_otg_init(struct omap_usb_config *config) syscon |= OTG_EN; #endif if (cpu_class_is_omap1()) - pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG); - pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon); - OTG_SYSCON_2_REG = syscon; + pr_debug("USB_TRANSCEIVER_CTRL = %03x\n", + omap_readl(USB_TRANSCEIVER_CTRL)); + pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2)); + omap_writel(syscon, OTG_SYSCON_2); printk("USB: hmc %d", config->hmc_mode); if (!alt_pingroup) @@ -597,12 +630,19 @@ omap_otg_init(struct omap_usb_config *config) printk("\n"); if (cpu_class_is_omap1()) { + u16 w; + /* leave USB clocks/controllers off until needed */ - ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ; - ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN; - ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK; + w = omap_readw(ULPD_SOFT_REQ); + w &= ~SOFT_USB_CLK_REQ; + omap_writew(w, ULPD_SOFT_REQ); + + w = omap_readw(ULPD_CLOCK_CTRL); + w &= ~USB_MCLK_EN; + w |= DIS_USB_PVCI_CLK; + omap_writew(w, ULPD_CLOCK_CTRL); } - syscon = OTG_SYSCON_1_REG; + syscon = omap_readl(OTG_SYSCON_1); syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; #ifdef CONFIG_USB_GADGET_OMAP @@ -639,8 +679,8 @@ omap_otg_init(struct omap_usb_config *config) pr_debug("can't register OTG device, %d\n", status); } #endif - pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon); - OTG_SYSCON_1_REG = syscon; + pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); + omap_writel(syscon, OTG_SYSCON_1); status = 0; } @@ -653,18 +693,19 @@ static inline void omap_otg_init(struct omap_usb_config *config) {} #ifdef CONFIG_ARCH_OMAP15XX -#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL) +/* ULPD_DPLL_CTRL */ #define DPLL_IOB (1 << 13) #define DPLL_PLL_ENABLE (1 << 4) #define DPLL_LOCK (1 << 0) -#define ULPD_APLL_CTRL_REG __REG16(ULPD_APLL_CTRL) +/* ULPD_APLL_CTRL */ #define APLL_NDPLL_SWITCH (1 << 0) static void __init omap_1510_usb_init(struct omap_usb_config *config) { unsigned int val; + u16 w; omap_usb0_init(config->pins[0], is_usb0_device(config)); omap_usb1_init(config->pins[1]); @@ -685,12 +726,22 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config) printk("\n"); /* use DPLL for 48 MHz function clock */ - pr_debug("APLL %04x DPLL %04x REQ %04x\n", ULPD_APLL_CTRL_REG, - ULPD_DPLL_CTRL_REG, ULPD_SOFT_REQ_REG); - ULPD_APLL_CTRL_REG &= ~APLL_NDPLL_SWITCH; - ULPD_DPLL_CTRL_REG |= DPLL_IOB | DPLL_PLL_ENABLE; - ULPD_SOFT_REQ_REG |= SOFT_UDC_REQ | SOFT_DPLL_REQ; - while (!(ULPD_DPLL_CTRL_REG & DPLL_LOCK)) + pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL), + omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ)); + + w = omap_readw(ULPD_APLL_CTRL); + w &= ~APLL_NDPLL_SWITCH; + omap_writew(w, ULPD_APLL_CTRL); + + w = omap_readw(ULPD_DPLL_CTRL); + w |= DPLL_IOB | DPLL_PLL_ENABLE; + omap_writew(w, ULPD_DPLL_CTRL); + + w = omap_readw(ULPD_SOFT_REQ); + w |= SOFT_UDC_REQ | SOFT_DPLL_REQ; + omap_writew(w, ULPD_SOFT_REQ); + + while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK)) cpu_relax(); #ifdef CONFIG_USB_GADGET_OMAP diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index b1b45dddb17..03a33f1b9cd 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c @@ -72,7 +72,7 @@ struct isp1301 { }; -/* bits in OTG_CTRL_REG */ +/* bits in OTG_CTRL */ #define OTG_XCEIV_OUTPUTS \ (OTG_ASESSVLD|OTG_BSESSEND|OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID) @@ -186,8 +186,8 @@ isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) /* operational registers */ #define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */ -# define MC1_SPEED_REG (1 << 0) -# define MC1_SUSPEND_REG (1 << 1) +# define MC1_SPEED (1 << 0) +# define MC1_SUSPEND (1 << 1) # define MC1_DAT_SE0 (1 << 2) # define MC1_TRANSPARENT (1 << 3) # define MC1_BDIS_ACON_EN (1 << 4) @@ -274,7 +274,7 @@ static void power_down(struct isp1301 *isp) isp->otg.state = OTG_STATE_UNDEFINED; // isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG); + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_ID_PULLDOWN); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); @@ -283,7 +283,7 @@ static void power_down(struct isp1301 *isp) static void power_up(struct isp1301 *isp) { // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); /* do this only when cpu is driving transceiver, * so host won't see a low speed device... @@ -360,6 +360,8 @@ isp1301_defer_work(struct isp1301 *isp, int work) /* called from irq handlers */ static void a_idle(struct isp1301 *isp, const char *tag) { + u32 l; + if (isp->otg.state == OTG_STATE_A_IDLE) return; @@ -373,13 +375,17 @@ static void a_idle(struct isp1301 *isp, const char *tag) gadget_suspend(isp); } isp->otg.state = OTG_STATE_A_IDLE; - isp->last_otg_ctrl = OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + isp->last_otg_ctrl = l; pr_debug(" --> %s/%s\n", state_name(isp), tag); } /* called from irq handlers */ static void b_idle(struct isp1301 *isp, const char *tag) { + u32 l; + if (isp->otg.state == OTG_STATE_B_IDLE) return; @@ -393,7 +399,9 @@ static void b_idle(struct isp1301 *isp, const char *tag) gadget_suspend(isp); } isp->otg.state = OTG_STATE_B_IDLE; - isp->last_otg_ctrl = OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + isp->last_otg_ctrl = l; pr_debug(" --> %s/%s\n", state_name(isp), tag); } @@ -406,7 +414,7 @@ dump_regs(struct isp1301 *isp, const char *label) u8 src = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); pr_debug("otg: %06x, %s %s, otg/%02x stat/%02x.%02x\n", - OTG_CTRL_REG, label, state_name(isp), + omap_readl(OTG_CTRL), label, state_name(isp), ctrl, status, src); /* mode control and irq enables don't change much */ #endif @@ -429,7 +437,7 @@ dump_regs(struct isp1301 *isp, const char *label) static void check_state(struct isp1301 *isp, const char *tag) { enum usb_otg_state state = OTG_STATE_UNDEFINED; - u8 fsm = OTG_TEST_REG & 0x0ff; + u8 fsm = omap_readw(OTG_TEST) & 0x0ff; unsigned extra = 0; switch (fsm) { @@ -494,7 +502,8 @@ static void check_state(struct isp1301 *isp, const char *tag) if (isp->otg.state == state && !extra) return; pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, - state_string(state), fsm, state_name(isp), OTG_CTRL_REG); + state_string(state), fsm, state_name(isp), + omap_readl(OTG_CTRL)); } #else @@ -508,10 +517,11 @@ static void update_otg1(struct isp1301 *isp, u8 int_src) { u32 otg_ctrl; - otg_ctrl = OTG_CTRL_REG - & OTG_CTRL_MASK - & ~OTG_XCEIV_INPUTS - & ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); + otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + otg_ctrl &= ~OTG_XCEIV_INPUTS; + otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); + + if (int_src & INTR_SESS_VLD) otg_ctrl |= OTG_ASESSVLD; else if (isp->otg.state == OTG_STATE_A_WAIT_VFALL) { @@ -534,7 +544,7 @@ static void update_otg1(struct isp1301 *isp, u8 int_src) return; } } - OTG_CTRL_REG = otg_ctrl; + omap_writel(otg_ctrl, OTG_CTRL); } /* outputs from ISP1301_OTG_STATUS */ @@ -542,15 +552,14 @@ static void update_otg2(struct isp1301 *isp, u8 otg_status) { u32 otg_ctrl; - otg_ctrl = OTG_CTRL_REG - & OTG_CTRL_MASK - & ~OTG_XCEIV_INPUTS - & ~(OTG_BSESSVLD|OTG_BSESSEND); + otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + otg_ctrl &= ~OTG_XCEIV_INPUTS; + otg_ctrl &= ~(OTG_BSESSVLD | OTG_BSESSEND); if (otg_status & OTG_B_SESS_VLD) otg_ctrl |= OTG_BSESSVLD; else if (otg_status & OTG_B_SESS_END) otg_ctrl |= OTG_BSESSEND; - OTG_CTRL_REG = otg_ctrl; + omap_writel(otg_ctrl, OTG_CTRL); } /* inputs going to ISP1301 */ @@ -559,7 +568,7 @@ static void otg_update_isp(struct isp1301 *isp) u32 otg_ctrl, otg_change; u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP; - otg_ctrl = OTG_CTRL_REG; + otg_ctrl = omap_readl(OTG_CTRL); otg_change = otg_ctrl ^ isp->last_otg_ctrl; isp->last_otg_ctrl = otg_ctrl; otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; @@ -639,6 +648,8 @@ pulldown: /* HNP switch to host or peripheral; and SRP */ if (otg_change & OTG_PULLUP) { + u32 l; + switch (isp->otg.state) { case OTG_STATE_B_IDLE: if (clr & OTG1_DP_PULLUP) @@ -655,7 +666,9 @@ pulldown: default: break; } - OTG_CTRL_REG |= OTG_PULLUP; + l = omap_readl(OTG_CTRL); + l |= OTG_PULLUP; + omap_writel(l, OTG_CTRL); } check_state(isp, __func__); @@ -664,20 +677,20 @@ pulldown: static irqreturn_t omap_otg_irq(int irq, void *_isp) { - u16 otg_irq = OTG_IRQ_SRC_REG; + u16 otg_irq = omap_readw(OTG_IRQ_SRC); u32 otg_ctrl; int ret = IRQ_NONE; struct isp1301 *isp = _isp; /* update ISP1301 transciever from OTG controller */ if (otg_irq & OPRT_CHG) { - OTG_IRQ_SRC_REG = OPRT_CHG; + omap_writew(OPRT_CHG, OTG_IRQ_SRC); isp1301_defer_work(isp, WORK_UPDATE_ISP); ret = IRQ_HANDLED; /* SRP to become b_peripheral failed */ } else if (otg_irq & B_SRP_TMROUT) { - pr_debug("otg: B_SRP_TIMEOUT, %06x\n", OTG_CTRL_REG); + pr_debug("otg: B_SRP_TIMEOUT, %06x\n", omap_readl(OTG_CTRL)); notresponding(isp); /* gadget drivers that care should monitor all kinds of @@ -687,31 +700,31 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) if (isp->otg.state == OTG_STATE_B_SRP_INIT) b_idle(isp, "srp_timeout"); - OTG_IRQ_SRC_REG = B_SRP_TMROUT; + omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* HNP to become b_host failed */ } else if (otg_irq & B_HNP_FAIL) { pr_debug("otg: %s B_HNP_FAIL, %06x\n", - state_name(isp), OTG_CTRL_REG); + state_name(isp), omap_readl(OTG_CTRL)); notresponding(isp); - otg_ctrl = OTG_CTRL_REG; + otg_ctrl = omap_readl(OTG_CTRL); otg_ctrl |= OTG_BUSDROP; otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - OTG_CTRL_REG = otg_ctrl; + omap_writel(otg_ctrl, OTG_CTRL); /* subset of b_peripheral()... */ isp->otg.state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); - OTG_IRQ_SRC_REG = B_HNP_FAIL; + omap_writew(B_HNP_FAIL, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* detect SRP from B-device ... */ } else if (otg_irq & A_SRP_DETECT) { pr_debug("otg: %s SRP_DETECT, %06x\n", - state_name(isp), OTG_CTRL_REG); + state_name(isp), omap_readl(OTG_CTRL)); isp1301_defer_work(isp, WORK_UPDATE_OTG); switch (isp->otg.state) { @@ -719,49 +732,49 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) if (!isp->otg.host) break; isp1301_defer_work(isp, WORK_HOST_RESUME); - otg_ctrl = OTG_CTRL_REG; + otg_ctrl = omap_readl(OTG_CTRL); otg_ctrl |= OTG_A_BUSREQ; otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) & ~OTG_XCEIV_INPUTS & OTG_CTRL_MASK; - OTG_CTRL_REG = otg_ctrl; + omap_writel(otg_ctrl, OTG_CTRL); break; default: break; } - OTG_IRQ_SRC_REG = A_SRP_DETECT; + omap_writew(A_SRP_DETECT, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise) * we don't track them separately */ } else if (otg_irq & A_REQ_TMROUT) { - otg_ctrl = OTG_CTRL_REG; + otg_ctrl = omap_readl(OTG_CTRL); pr_info("otg: BCON_TMOUT from %s, %06x\n", state_name(isp), otg_ctrl); notresponding(isp); otg_ctrl |= OTG_BUSDROP; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - OTG_CTRL_REG = otg_ctrl; + omap_writel(otg_ctrl, OTG_CTRL); isp->otg.state = OTG_STATE_A_WAIT_VFALL; - OTG_IRQ_SRC_REG = A_REQ_TMROUT; + omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* A-supplied voltage fell too low; overcurrent */ } else if (otg_irq & A_VBUS_ERR) { - otg_ctrl = OTG_CTRL_REG; + otg_ctrl = omap_readl(OTG_CTRL); printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n", state_name(isp), otg_irq, otg_ctrl); otg_ctrl |= OTG_BUSDROP; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - OTG_CTRL_REG = otg_ctrl; + omap_writel(otg_ctrl, OTG_CTRL); isp->otg.state = OTG_STATE_A_VBUS_ERR; - OTG_IRQ_SRC_REG = A_VBUS_ERR; + omap_writew(A_VBUS_ERR, OTG_IRQ_SRC); ret = IRQ_HANDLED; /* switch driver; the transciever code activates it, @@ -770,7 +783,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) } else if (otg_irq & DRIVER_SWITCH) { int kick = 0; - otg_ctrl = OTG_CTRL_REG; + otg_ctrl = omap_readl(OTG_CTRL); printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n", state_name(isp), (otg_ctrl & OTG_DRIVER_SEL) @@ -793,7 +806,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) } else { if (!(otg_ctrl & OTG_ID)) { otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - OTG_CTRL_REG = otg_ctrl | OTG_A_BUSREQ; + omap_writel(otg_ctrl | OTG_A_BUSREQ, OTG_CTRL); } if (isp->otg.host) { @@ -818,7 +831,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) } } - OTG_IRQ_SRC_REG = DRIVER_SWITCH; + omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC); ret = IRQ_HANDLED; if (kick) @@ -834,12 +847,15 @@ static struct platform_device *otg_dev; static int otg_init(struct isp1301 *isp) { + u32 l; + if (!otg_dev) return -ENODEV; dump_regs(isp, __func__); /* some of these values are board-specific... */ - OTG_SYSCON_2_REG |= OTG_EN + l = omap_readl(OTG_SYSCON_2); + l |= OTG_EN /* for B-device: */ | SRP_GPDATA /* 9msec Bdev D+ pulse */ | SRP_GPDVBUS /* discharge after VBUS pulse */ @@ -849,18 +865,22 @@ static int otg_init(struct isp1301 *isp) | SRP_DPW /* detect 167+ns SRP pulses */ | SRP_DATA | SRP_VBUS /* accept both kinds of SRP pulse */ ; + omap_writel(l, OTG_SYSCON_2); update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); check_state(isp, __func__); pr_debug("otg: %s, %s %06x\n", - state_name(isp), __func__, OTG_CTRL_REG); + state_name(isp), __func__, omap_readl(OTG_CTRL)); - OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG + omap_writew(DRIVER_SWITCH | OPRT_CHG | B_SRP_TMROUT | B_HNP_FAIL - | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT; - OTG_SYSCON_2_REG |= OTG_EN; + | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT, OTG_IRQ_EN); + + l = omap_readl(OTG_SYSCON_2); + l |= OTG_EN; + omap_writel(l, OTG_SYSCON_2); return 0; } @@ -927,7 +947,11 @@ static void otg_unbind(struct isp1301 *isp) static void b_peripheral(struct isp1301 *isp) { - OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; + u32 l; + + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); + usb_gadget_vbus_connect(isp->otg.gadget); #ifdef CONFIG_USB_OTG @@ -999,6 +1023,8 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) isp_bstat = 0; } } else { + u32 l; + /* if user unplugged mini-A end of cable, * don't bypass A_WAIT_VFALL. */ @@ -1019,8 +1045,9 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_BDIS_ACON_EN); isp->otg.state = OTG_STATE_B_IDLE; - OTG_CTRL_REG &= OTG_CTRL_REG & OTG_CTRL_MASK - & ~OTG_CTRL_BITS; + l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + l &= ~OTG_CTRL_BITS; + omap_writel(l, OTG_CTRL); break; case OTG_STATE_B_IDLE: break; @@ -1046,7 +1073,8 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) /* FALLTHROUGH */ case OTG_STATE_B_SRP_INIT: b_idle(isp, __func__); - OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; + l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; + omap_writel(l, OTG_CTRL); /* FALLTHROUGH */ case OTG_STATE_B_IDLE: if (isp->otg.gadget && (isp_bstat & OTG_B_SESS_VLD)) { @@ -1130,11 +1158,11 @@ isp1301_work(struct work_struct *work) case OTG_STATE_A_WAIT_VRISE: isp->otg.state = OTG_STATE_A_HOST; pr_debug(" --> a_host\n"); - otg_ctrl = OTG_CTRL_REG; + otg_ctrl = omap_readl(OTG_CTRL); otg_ctrl |= OTG_A_BUSREQ; otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) & OTG_CTRL_MASK; - OTG_CTRL_REG = otg_ctrl; + omap_writel(otg_ctrl, OTG_CTRL); break; case OTG_STATE_B_WAIT_ACON: isp->otg.state = OTG_STATE_B_HOST; @@ -1274,7 +1302,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) return -ENODEV; if (!host) { - OTG_IRQ_EN_REG = 0; + omap_writew(0, OTG_IRQ_EN); power_down(isp); isp->otg.host = 0; return 0; @@ -1325,12 +1353,13 @@ static int isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) { struct isp1301 *isp = container_of(otg, struct isp1301, otg); + u32 l; if (!otg || isp != the_transceiver) return -ENODEV; if (!gadget) { - OTG_IRQ_EN_REG = 0; + omap_writew(0, OTG_IRQ_EN); if (!isp->otg.default_a) enable_vbus_draw(isp, 0); usb_gadget_vbus_disconnect(isp->otg.gadget); @@ -1351,9 +1380,11 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) isp->otg.gadget = gadget; // FIXME update its refcount - OTG_CTRL_REG = (OTG_CTRL_REG & OTG_CTRL_MASK - & ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS)) - | OTG_ID; + l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; + l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); + l |= OTG_ID; + omap_writel(l, OTG_CTRL); + power_up(isp); isp->otg.state = OTG_STATE_B_IDLE; @@ -1405,16 +1436,17 @@ isp1301_start_srp(struct otg_transceiver *dev) || isp->otg.state != OTG_STATE_B_IDLE) return -ENODEV; - otg_ctrl = OTG_CTRL_REG; + otg_ctrl = omap_readl(OTG_CTRL); if (!(otg_ctrl & OTG_BSESSEND)) return -EINVAL; otg_ctrl |= OTG_B_BUSREQ; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK; - OTG_CTRL_REG = otg_ctrl; + omap_writel(otg_ctrl, OTG_CTRL); isp->otg.state = OTG_STATE_B_SRP_INIT; - pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG); + pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), + omap_readl(OTG_CTRL)); #ifdef CONFIG_USB_OTG check_state(isp, __func__); #endif @@ -1426,6 +1458,7 @@ isp1301_start_hnp(struct otg_transceiver *dev) { #ifdef CONFIG_USB_OTG struct isp1301 *isp = container_of(dev, struct isp1301, otg); + u32 l; if (!dev || isp != the_transceiver) return -ENODEV; @@ -1452,7 +1485,9 @@ isp1301_start_hnp(struct otg_transceiver *dev) #endif /* caller must suspend then clear A_BUSREQ */ usb_gadget_vbus_connect(isp->otg.gadget); - OTG_CTRL_REG |= OTG_A_SETB_HNPEN; + l = omap_readl(OTG_CTRL); + l |= OTG_A_SETB_HNPEN; + omap_writel(l, OTG_CTRL); break; case OTG_STATE_A_PERIPHERAL: @@ -1462,7 +1497,7 @@ isp1301_start_hnp(struct otg_transceiver *dev) return -EILSEQ; } pr_debug("otg: HNP %s, %06x ...\n", - state_name(isp), OTG_CTRL_REG); + state_name(isp), omap_readl(OTG_CTRL)); check_state(isp, __func__); return 0; #else diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 86c029a8d99..03a7f49d207 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -135,13 +135,17 @@ static void use_ep(struct omap_ep *ep, u16 select) if (ep->bEndpointAddress & USB_DIR_IN) num |= UDC_EP_DIR; - UDC_EP_NUM_REG = num | select; + omap_writew(num | select, UDC_EP_NUM); /* when select, MUST deselect later !! */ } static inline void deselect_ep(void) { - UDC_EP_NUM_REG &= ~UDC_EP_SEL; + u16 w; + + w = omap_readw(UDC_EP_NUM); + w &= ~UDC_EP_SEL; + omap_writew(w, UDC_EP_NUM); /* 6 wait states before TX will happen */ } @@ -216,7 +220,7 @@ static int omap_ep_enable(struct usb_ep *_ep, ep->has_dma = 0; ep->lch = -1; use_ep(ep, UDC_EP_SEL); - UDC_CTRL_REG = udc->clr_halt; + omap_writew(udc->clr_halt, UDC_CTRL); ep->ackwait = 0; deselect_ep(); @@ -232,7 +236,7 @@ static int omap_ep_enable(struct usb_ep *_ep, if (desc->bmAttributes != USB_ENDPOINT_XFER_ISOC && !ep->has_dma && !(ep->bEndpointAddress & USB_DIR_IN)) { - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); ep->ackwait = 1 + ep->double_buf; } @@ -259,7 +263,7 @@ static int omap_ep_disable(struct usb_ep *_ep) nuke (ep, -ESHUTDOWN); ep->ep.maxpacket = ep->maxpacket; ep->has_dma = 0; - UDC_CTRL_REG = UDC_SET_HALT; + omap_writew(UDC_SET_HALT, UDC_CTRL); list_del_init(&ep->iso); del_timer(&ep->timer); @@ -360,13 +364,13 @@ write_packet(u8 *buf, struct omap_req *req, unsigned max) if (likely((((int)buf) & 1) == 0)) { wp = (u16 *)buf; while (max >= 2) { - UDC_DATA_REG = *wp++; + omap_writew(*wp++, UDC_DATA); max -= 2; } buf = (u8 *)wp; } while (max--) - *(volatile u8 *)&UDC_DATA_REG = *buf++; + omap_writeb(*buf++, UDC_DATA); return len; } @@ -385,13 +389,13 @@ static int write_fifo(struct omap_ep *ep, struct omap_req *req) prefetch(buf); /* PIO-IN isn't double buffered except for iso */ - ep_stat = UDC_STAT_FLG_REG; + ep_stat = omap_readw(UDC_STAT_FLG); if (ep_stat & UDC_FIFO_UNWRITABLE) return 0; count = ep->ep.maxpacket; count = write_packet(buf, req, count); - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); ep->ackwait = 1; /* last packet is often short (sometimes a zlp) */ @@ -425,13 +429,13 @@ read_packet(u8 *buf, struct omap_req *req, unsigned avail) if (likely((((int)buf) & 1) == 0)) { wp = (u16 *)buf; while (avail >= 2) { - *wp++ = UDC_DATA_REG; + *wp++ = omap_readw(UDC_DATA); avail -= 2; } buf = (u8 *)wp; } while (avail--) - *buf++ = *(volatile u8 *)&UDC_DATA_REG; + *buf++ = omap_readb(UDC_DATA); return len; } @@ -446,7 +450,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) prefetchw(buf); for (;;) { - u16 ep_stat = UDC_STAT_FLG_REG; + u16 ep_stat = omap_readw(UDC_STAT_FLG); is_last = 0; if (ep_stat & FIFO_EMPTY) { @@ -460,7 +464,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) if (ep_stat & UDC_FIFO_FULL) avail = ep->ep.maxpacket; else { - avail = UDC_RXFSTAT_REG; + avail = omap_readw(UDC_RXFSTAT); ep->fnf = ep->double_buf; } count = read_packet(buf, req, avail); @@ -473,7 +477,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) req->req.status = -EOVERFLOW; avail -= count; while (avail--) - (void) *(volatile u8 *)&UDC_DATA_REG; + omap_readw(UDC_DATA); } } else if (req->req.length == req->req.actual) is_last = 1; @@ -535,7 +539,7 @@ static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) static void next_in_dma(struct omap_ep *ep, struct omap_req *req) { - u16 txdma_ctrl; + u16 txdma_ctrl, w; unsigned length = req->req.length - req->req.actual; const int sync_mode = cpu_is_omap15xx() ? OMAP_DMA_SYNC_FRAME @@ -567,13 +571,17 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) omap_start_dma(ep->lch); ep->dma_counter = omap_get_dma_src_pos(ep->lch); - UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel); - UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl; + w = omap_readw(UDC_DMA_IRQ_EN); + w |= UDC_TX_DONE_IE(ep->dma_channel); + omap_writew(w, UDC_DMA_IRQ_EN); + omap_writew(UDC_TXN_START | txdma_ctrl, UDC_TXDMA(ep->dma_channel)); req->dma_bytes = length; } static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status) { + u16 w; + if (status == 0) { req->req.actual += req->dma_bytes; @@ -590,7 +598,9 @@ static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status) /* tx completion */ omap_stop_dma(ep->lch); - UDC_DMA_IRQ_EN_REG &= ~UDC_TX_DONE_IE(ep->dma_channel); + w = omap_readw(UDC_DMA_IRQ_EN); + w &= ~UDC_TX_DONE_IE(ep->dma_channel); + omap_writew(w, UDC_DMA_IRQ_EN); done(ep, req, status); } @@ -598,6 +608,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) { unsigned packets = req->req.length - req->req.actual; int dma_trigger = 0; + u16 w; if (cpu_is_omap24xx()) dma_trigger = OMAP24XX_DMA(USB_W2FC_RX0, ep->dma_channel); @@ -626,10 +637,12 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) 0, 0); ep->dma_counter = omap_get_dma_dst_pos(ep->lch); - UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); - UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel); - UDC_EP_NUM_REG = (ep->bEndpointAddress & 0xf); - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(UDC_RXN_STOP | (packets - 1), UDC_RXDMA(ep->dma_channel)); + w = omap_readw(UDC_DMA_IRQ_EN); + w |= UDC_RX_EOT_IE(ep->dma_channel); + omap_writew(w, UDC_DMA_IRQ_EN); + omap_writew(ep->bEndpointAddress & 0xf, UDC_EP_NUM); + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); omap_start_dma(ep->lch); } @@ -637,7 +650,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) static void finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one) { - u16 count; + u16 count, w; if (status == 0) ep->dma_counter = (u16) (req->req.dma + req->req.actual); @@ -656,13 +669,15 @@ finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one) return; /* rx completion */ - UDC_DMA_IRQ_EN_REG &= ~UDC_RX_EOT_IE(ep->dma_channel); + w = omap_readw(UDC_DMA_IRQ_EN); + w &= ~UDC_RX_EOT_IE(ep->dma_channel); + omap_writew(w, UDC_DMA_IRQ_EN); done(ep, req, status); } static void dma_irq(struct omap_udc *udc, u16 irq_src) { - u16 dman_stat = UDC_DMAN_STAT_REG; + u16 dman_stat = omap_readw(UDC_DMAN_STAT); struct omap_ep *ep; struct omap_req *req; @@ -676,7 +691,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) struct omap_req, queue); finish_in_dma(ep, req, 0); } - UDC_IRQ_SRC_REG = UDC_TXN_DONE; + omap_writew(UDC_TXN_DONE, UDC_IRQ_SRC); if (!list_empty (&ep->queue)) { req = container_of(ep->queue.next, @@ -695,7 +710,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) struct omap_req, queue); finish_out_dma(ep, req, 0, dman_stat & UDC_DMA_RX_SB); } - UDC_IRQ_SRC_REG = UDC_RXN_EOT; + omap_writew(UDC_RXN_EOT, UDC_IRQ_SRC); if (!list_empty (&ep->queue)) { req = container_of(ep->queue.next, @@ -709,7 +724,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) ep->irqs++; /* omap15xx does this unasked... */ VDBG("%s, RX_CNT irq?\n", ep->ep.name); - UDC_IRQ_SRC_REG = UDC_RXN_CNT; + omap_writew(UDC_RXN_CNT, UDC_IRQ_SRC); } } @@ -732,9 +747,9 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) is_in = ep->bEndpointAddress & USB_DIR_IN; if (is_in) - reg = UDC_TXDMA_CFG_REG; + reg = omap_readw(UDC_TXDMA_CFG); else - reg = UDC_RXDMA_CFG_REG; + reg = omap_readw(UDC_RXDMA_CFG); reg |= UDC_DMA_REQ; /* "pulse" activated */ ep->dma_channel = 0; @@ -762,7 +777,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { - UDC_TXDMA_CFG_REG = reg; + omap_writew(reg, UDC_TXDMA_CFG); /* EMIFF or SDRC */ omap_set_dma_src_burst_mode(ep->lch, OMAP_DMA_DATA_BURST_4); @@ -771,7 +786,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, - (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), + (unsigned long) io_v2p(UDC_DATA_DMA), 0, 0); } } else { @@ -783,12 +798,12 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { - UDC_RXDMA_CFG_REG = reg; + omap_writew(reg, UDC_RXDMA_CFG); /* TIPB */ omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, - (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), + (unsigned long) io_v2p(UDC_DATA_DMA), 0, 0); /* EMIFF or SDRC */ omap_set_dma_dest_burst_mode(ep->lch, @@ -830,7 +845,7 @@ just_restart: (is_in ? write_fifo : read_fifo)(ep, req); deselect_ep(); if (!is_in) { - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); ep->ackwait = 1 + ep->double_buf; } /* IN: 6 wait states before it'll tx */ @@ -864,23 +879,25 @@ static void dma_channel_release(struct omap_ep *ep) /* wait till current packet DMA finishes, and fifo empties */ if (ep->bEndpointAddress & USB_DIR_IN) { - UDC_TXDMA_CFG_REG = (UDC_TXDMA_CFG_REG & ~mask) | UDC_DMA_REQ; + omap_writew((omap_readw(UDC_TXDMA_CFG) & ~mask) | UDC_DMA_REQ, + UDC_TXDMA_CFG); if (req) { finish_in_dma(ep, req, -ECONNRESET); /* clear FIFO; hosts probably won't empty it */ use_ep(ep, UDC_EP_SEL); - UDC_CTRL_REG = UDC_CLR_EP; + omap_writew(UDC_CLR_EP, UDC_CTRL); deselect_ep(); } - while (UDC_TXDMA_CFG_REG & mask) + while (omap_readw(UDC_TXDMA_CFG) & mask) udelay(10); } else { - UDC_RXDMA_CFG_REG = (UDC_RXDMA_CFG_REG & ~mask) | UDC_DMA_REQ; + omap_writew((omap_readw(UDC_RXDMA_CFG) & ~mask) | UDC_DMA_REQ, + UDC_RXDMA_CFG); /* dma empties the fifo */ - while (UDC_RXDMA_CFG_REG & mask) + while (omap_readw(UDC_RXDMA_CFG) & mask) udelay(10); if (req) finish_out_dma(ep, req, -ECONNRESET, 0); @@ -967,9 +984,13 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req->req.actual = 0; /* maybe kickstart non-iso i/o queues */ - if (is_iso) - UDC_IRQ_EN_REG |= UDC_SOF_IE; - else if (list_empty(&ep->queue) && !ep->stopped && !ep->ackwait) { + if (is_iso) { + u16 w; + + w = omap_readw(UDC_IRQ_EN); + w |= UDC_SOF_IE; + omap_writew(w, UDC_IRQ_EN); + } else if (list_empty(&ep->queue) && !ep->stopped && !ep->ackwait) { int is_in; if (ep->bEndpointAddress == 0) { @@ -987,23 +1008,23 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) * requests to non-control endpoints */ if (udc->ep0_set_config) { - u16 irq_en = UDC_IRQ_EN_REG; + u16 irq_en = omap_readw(UDC_IRQ_EN); irq_en |= UDC_DS_CHG_IE | UDC_EP0_IE; if (!udc->ep0_reset_config) irq_en |= UDC_EPN_RX_IE | UDC_EPN_TX_IE; - UDC_IRQ_EN_REG = irq_en; + omap_writew(irq_en, UDC_IRQ_EN); } /* STATUS for zero length DATA stages is * always an IN ... even for IN transfers, * a weird case which seem to stall OMAP. */ - UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR); - UDC_CTRL_REG = UDC_CLR_EP; - UDC_CTRL_REG = UDC_SET_FIFO_EN; - UDC_EP_NUM_REG = UDC_EP_DIR; + omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); + omap_writew(UDC_CLR_EP, UDC_CTRL); + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + omap_writew(UDC_EP_DIR, UDC_EP_NUM); /* cleanup */ udc->ep0_pending = 0; @@ -1012,11 +1033,11 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* non-empty DATA stage */ } else if (is_in) { - UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; + omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); } else { if (udc->ep0_setup) goto irq_wait; - UDC_EP_NUM_REG = UDC_EP_SEL; + omap_writew(UDC_EP_SEL, UDC_EP_NUM); } } else { is_in = ep->bEndpointAddress & USB_DIR_IN; @@ -1032,7 +1053,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req = NULL; deselect_ep(); if (!is_in) { - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); ep->ackwait = 1 + ep->double_buf; } /* IN: 6 wait states before it'll tx */ @@ -1100,9 +1121,9 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) else if (value) { if (ep->udc->ep0_set_config) { WARN("error changing config?\n"); - UDC_SYSCON2_REG = UDC_CLR_CFG; + omap_writew(UDC_CLR_CFG, UDC_SYSCON2); } - UDC_SYSCON2_REG = UDC_STALL_CMD; + omap_writew(UDC_STALL_CMD, UDC_SYSCON2); ep->udc->ep0_pending = 0; status = 0; } else /* NOP */ @@ -1129,8 +1150,8 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) channel = 0; use_ep(ep, UDC_EP_SEL); - if (UDC_STAT_FLG_REG & UDC_NON_ISO_FIFO_EMPTY) { - UDC_CTRL_REG = UDC_SET_HALT; + if (omap_readw(UDC_STAT_FLG) & UDC_NON_ISO_FIFO_EMPTY) { + omap_writew(UDC_SET_HALT, UDC_CTRL); status = 0; } else status = -EAGAIN; @@ -1140,10 +1161,10 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) dma_channel_claim(ep, channel); } else { use_ep(ep, 0); - UDC_CTRL_REG = ep->udc->clr_halt; + omap_writew(ep->udc->clr_halt, UDC_CTRL); ep->ackwait = 0; if (!(ep->bEndpointAddress & USB_DIR_IN)) { - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); ep->ackwait = 1 + ep->double_buf; } } @@ -1175,7 +1196,7 @@ static struct usb_ep_ops omap_ep_ops = { static int omap_get_frame(struct usb_gadget *gadget) { - u16 sof = UDC_SOF_REG; + u16 sof = omap_readw(UDC_SOF); return (sof & UDC_TS_OK) ? (sof & UDC_TS) : -EL2NSYNC; } @@ -1194,7 +1215,7 @@ static int omap_wakeup(struct usb_gadget *gadget) */ if (udc->devstat & (UDC_B_HNP_ENABLE|UDC_R_WK_OK)) { DBG("remote wakeup...\n"); - UDC_SYSCON2_REG = UDC_RMT_WKP; + omap_writew(UDC_RMT_WKP, UDC_SYSCON2); retval = 0; } @@ -1217,12 +1238,12 @@ omap_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) udc = container_of(gadget, struct omap_udc, gadget); spin_lock_irqsave(&udc->lock, flags); - syscon1 = UDC_SYSCON1_REG; + syscon1 = omap_readw(UDC_SYSCON1); if (is_selfpowered) syscon1 |= UDC_SELF_PWR; else syscon1 &= ~UDC_SELF_PWR; - UDC_SYSCON1_REG = syscon1; + omap_writew(syscon1, UDC_SYSCON1); spin_unlock_irqrestore(&udc->lock, flags); return 0; @@ -1235,18 +1256,36 @@ static int can_pullup(struct omap_udc *udc) static void pullup_enable(struct omap_udc *udc) { - UDC_SYSCON1_REG |= UDC_PULLUP_EN; - if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) - OTG_CTRL_REG |= OTG_BSESSVLD; - UDC_IRQ_EN_REG = UDC_DS_CHG_IE; + u16 w; + + w = omap_readw(UDC_SYSCON1); + w |= UDC_PULLUP_EN; + omap_writew(w, UDC_SYSCON1); + if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) { + u32 l; + + l = omap_readl(OTG_CTRL); + l |= OTG_BSESSVLD; + omap_writel(l, OTG_CTRL); + } + omap_writew(UDC_DS_CHG_IE, UDC_IRQ_EN); } static void pullup_disable(struct omap_udc *udc) { - if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) - OTG_CTRL_REG &= ~OTG_BSESSVLD; - UDC_IRQ_EN_REG = UDC_DS_CHG_IE; - UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; + u16 w; + + if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) { + u32 l; + + l = omap_readl(OTG_CTRL); + l &= ~OTG_BSESSVLD; + omap_writel(l, OTG_CTRL); + } + omap_writew(UDC_DS_CHG_IE, UDC_IRQ_EN); + w = omap_readw(UDC_SYSCON1); + w &= ~UDC_PULLUP_EN; + omap_writew(w, UDC_SYSCON1); } static struct omap_udc *udc; @@ -1274,6 +1313,7 @@ static int omap_vbus_session(struct usb_gadget *gadget, int is_active) { struct omap_udc *udc; unsigned long flags; + u32 l; udc = container_of(gadget, struct omap_udc, gadget); spin_lock_irqsave(&udc->lock, flags); @@ -1281,10 +1321,12 @@ static int omap_vbus_session(struct usb_gadget *gadget, int is_active) udc->vbus_active = (is_active != 0); if (cpu_is_omap15xx()) { /* "software" detect, ignored if !VBUS_MODE_1510 */ + l = omap_readl(FUNC_MUX_CTRL_0); if (is_active) - FUNC_MUX_CTRL_0_REG |= VBUS_CTRL_1510; + l |= VBUS_CTRL_1510; else - FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510; + l &= ~VBUS_CTRL_1510; + omap_writel(l, FUNC_MUX_CTRL_0); } if (udc->dc_clk != NULL && is_active) { if (!udc->clk_requested) { @@ -1354,9 +1396,9 @@ static void nuke(struct omap_ep *ep, int status) dma_channel_release(ep); use_ep(ep, 0); - UDC_CTRL_REG = UDC_CLR_EP; + omap_writew(UDC_CLR_EP, UDC_CTRL); if (ep->bEndpointAddress && ep->bmAttributes != USB_ENDPOINT_XFER_ISOC) - UDC_CTRL_REG = UDC_SET_HALT; + omap_writew(UDC_SET_HALT, UDC_CTRL); while (!list_empty(&ep->queue)) { req = list_entry(ep->queue.next, struct omap_req, queue); @@ -1384,8 +1426,8 @@ static void update_otg(struct omap_udc *udc) if (!gadget_is_otg(&udc->gadget)) return; - if (OTG_CTRL_REG & OTG_ID) - devstat = UDC_DEVSTAT_REG; + if (omap_readl(OTG_CTRL) & OTG_ID) + devstat = omap_readw(UDC_DEVSTAT); else devstat = 0; @@ -1396,9 +1438,14 @@ static void update_otg(struct omap_udc *udc) /* Enable HNP early, avoiding races on suspend irq path. * ASSUMES OTG state machine B_BUS_REQ input is true. */ - if (udc->gadget.b_hnp_enable) - OTG_CTRL_REG = (OTG_CTRL_REG | OTG_B_HNPEN | OTG_B_BUSREQ) - & ~OTG_PULLUP; + if (udc->gadget.b_hnp_enable) { + u32 l; + + l = omap_readl(OTG_CTRL); + l |= OTG_B_HNPEN | OTG_B_BUSREQ; + l &= ~OTG_PULLUP; + omap_writel(l, OTG_CTRL); + } } static void ep0_irq(struct omap_udc *udc, u16 irq_src) @@ -1416,7 +1463,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) nuke(ep0, 0); if (ack) { - UDC_IRQ_SRC_REG = ack; + omap_writew(ack, UDC_IRQ_SRC); irq_src = UDC_SETUP; } } @@ -1436,9 +1483,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) if (irq_src & UDC_EP0_TX) { int stat; - UDC_IRQ_SRC_REG = UDC_EP0_TX; - UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; - stat = UDC_STAT_FLG_REG; + omap_writew(UDC_EP0_TX, UDC_IRQ_SRC); + omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM); + stat = omap_readw(UDC_STAT_FLG); if (stat & UDC_ACK) { if (udc->ep0_in) { /* write next IN packet from response, @@ -1446,26 +1493,26 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) */ if (req) stat = write_fifo(ep0, req); - UDC_EP_NUM_REG = UDC_EP_DIR; + omap_writew(UDC_EP_DIR, UDC_EP_NUM); if (!req && udc->ep0_pending) { - UDC_EP_NUM_REG = UDC_EP_SEL; - UDC_CTRL_REG = UDC_CLR_EP; - UDC_CTRL_REG = UDC_SET_FIFO_EN; - UDC_EP_NUM_REG = 0; + omap_writew(UDC_EP_SEL, UDC_EP_NUM); + omap_writew(UDC_CLR_EP, UDC_CTRL); + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + omap_writew(0, UDC_EP_NUM); udc->ep0_pending = 0; } /* else: 6 wait states before it'll tx */ } else { /* ack status stage of OUT transfer */ - UDC_EP_NUM_REG = UDC_EP_DIR; + omap_writew(UDC_EP_DIR, UDC_EP_NUM); if (req) done(ep0, req, 0); } req = NULL; } else if (stat & UDC_STALL) { - UDC_CTRL_REG = UDC_CLR_HALT; - UDC_EP_NUM_REG = UDC_EP_DIR; + omap_writew(UDC_CLR_HALT, UDC_CTRL); + omap_writew(UDC_EP_DIR, UDC_EP_NUM); } else { - UDC_EP_NUM_REG = UDC_EP_DIR; + omap_writew(UDC_EP_DIR, UDC_EP_NUM); } } @@ -1473,9 +1520,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) if (irq_src & UDC_EP0_RX) { int stat; - UDC_IRQ_SRC_REG = UDC_EP0_RX; - UDC_EP_NUM_REG = UDC_EP_SEL; - stat = UDC_STAT_FLG_REG; + omap_writew(UDC_EP0_RX, UDC_IRQ_SRC); + omap_writew(UDC_EP_SEL, UDC_EP_NUM); + stat = omap_readw(UDC_STAT_FLG); if (stat & UDC_ACK) { if (!udc->ep0_in) { stat = 0; @@ -1483,34 +1530,35 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) * reactiviting the fifo; stall on errors. */ if (!req || (stat = read_fifo(ep0, req)) < 0) { - UDC_SYSCON2_REG = UDC_STALL_CMD; + omap_writew(UDC_STALL_CMD, UDC_SYSCON2); udc->ep0_pending = 0; stat = 0; } else if (stat == 0) - UDC_CTRL_REG = UDC_SET_FIFO_EN; - UDC_EP_NUM_REG = 0; + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + omap_writew(0, UDC_EP_NUM); /* activate status stage */ if (stat == 1) { done(ep0, req, 0); /* that may have STALLed ep0... */ - UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; - UDC_CTRL_REG = UDC_CLR_EP; - UDC_CTRL_REG = UDC_SET_FIFO_EN; - UDC_EP_NUM_REG = UDC_EP_DIR; + omap_writew(UDC_EP_SEL | UDC_EP_DIR, + UDC_EP_NUM); + omap_writew(UDC_CLR_EP, UDC_CTRL); + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + omap_writew(UDC_EP_DIR, UDC_EP_NUM); udc->ep0_pending = 0; } } else { /* ack status stage of IN transfer */ - UDC_EP_NUM_REG = 0; + omap_writew(0, UDC_EP_NUM); if (req) done(ep0, req, 0); } } else if (stat & UDC_STALL) { - UDC_CTRL_REG = UDC_CLR_HALT; - UDC_EP_NUM_REG = 0; + omap_writew(UDC_CLR_HALT, UDC_CTRL); + omap_writew(0, UDC_EP_NUM); } else { - UDC_EP_NUM_REG = 0; + omap_writew(0, UDC_EP_NUM); } } @@ -1525,14 +1573,14 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) /* read the (latest) SETUP message */ do { - UDC_EP_NUM_REG = UDC_SETUP_SEL; + omap_writew(UDC_SETUP_SEL, UDC_EP_NUM); /* two bytes at a time */ - u.word[0] = UDC_DATA_REG; - u.word[1] = UDC_DATA_REG; - u.word[2] = UDC_DATA_REG; - u.word[3] = UDC_DATA_REG; - UDC_EP_NUM_REG = 0; - } while (UDC_IRQ_SRC_REG & UDC_SETUP); + u.word[0] = omap_readw(UDC_DATA); + u.word[1] = omap_readw(UDC_DATA); + u.word[2] = omap_readw(UDC_DATA); + u.word[3] = omap_readw(UDC_DATA); + omap_writew(0, UDC_EP_NUM); + } while (omap_readw(UDC_IRQ_SRC) & UDC_SETUP); #define w_value le16_to_cpu(u.r.wValue) #define w_index le16_to_cpu(u.r.wIndex) @@ -1563,9 +1611,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) * later if it fails the request. */ if (udc->ep0_reset_config) - UDC_SYSCON2_REG = UDC_CLR_CFG; + omap_writew(UDC_CLR_CFG, UDC_SYSCON2); else - UDC_SYSCON2_REG = UDC_DEV_CFG; + omap_writew(UDC_DEV_CFG, UDC_SYSCON2); update_otg(udc); goto delegate; case USB_REQ_CLEAR_FEATURE: @@ -1583,10 +1631,10 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) || !ep->desc) goto do_stall; use_ep(ep, 0); - UDC_CTRL_REG = udc->clr_halt; + omap_writew(udc->clr_halt, UDC_CTRL); ep->ackwait = 0; if (!(ep->bEndpointAddress & USB_DIR_IN)) { - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); ep->ackwait = 1 + ep->double_buf; } /* NOTE: assumes the host behaves sanely, @@ -1619,15 +1667,15 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) } use_ep(ep, 0); /* can't halt if fifo isn't empty... */ - UDC_CTRL_REG = UDC_CLR_EP; - UDC_CTRL_REG = UDC_SET_HALT; + omap_writew(UDC_CLR_EP, UDC_CTRL); + omap_writew(UDC_SET_HALT, UDC_CTRL); VDBG("%s halted by host\n", ep->name); ep0out_status_stage: status = 0; - UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; - UDC_CTRL_REG = UDC_CLR_EP; - UDC_CTRL_REG = UDC_SET_FIFO_EN; - UDC_EP_NUM_REG = UDC_EP_DIR; + omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM); + omap_writew(UDC_CLR_EP, UDC_CTRL); + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + omap_writew(UDC_EP_DIR, UDC_EP_NUM); udc->ep0_pending = 0; break; case USB_REQ_GET_STATUS: @@ -1664,10 +1712,10 @@ intf_status: zero_status: /* return two zero bytes */ - UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; - UDC_DATA_REG = 0; - UDC_CTRL_REG = UDC_SET_FIFO_EN; - UDC_EP_NUM_REG = UDC_EP_DIR; + omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM); + omap_writew(0, UDC_DATA); + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + omap_writew(UDC_EP_DIR, UDC_EP_NUM); status = 0; VDBG("GET_STATUS, interface %d\n", w_index); /* next, status stage */ @@ -1676,8 +1724,8 @@ zero_status: delegate: /* activate the ep0out fifo right away */ if (!udc->ep0_in && w_length) { - UDC_EP_NUM_REG = 0; - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(0, UDC_EP_NUM); + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); } /* gadget drivers see class/vendor specific requests, @@ -1718,9 +1766,9 @@ do_stall: if (udc->ep0_reset_config) WARN("error resetting config?\n"); else - UDC_SYSCON2_REG = UDC_CLR_CFG; + omap_writew(UDC_CLR_CFG, UDC_SYSCON2); } - UDC_SYSCON2_REG = UDC_STALL_CMD; + omap_writew(UDC_STALL_CMD, UDC_SYSCON2); udc->ep0_pending = 0; } } @@ -1734,7 +1782,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) { u16 devstat, change; - devstat = UDC_DEVSTAT_REG; + devstat = omap_readw(UDC_DEVSTAT); change = devstat ^ udc->devstat; udc->devstat = devstat; @@ -1774,7 +1822,8 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) INFO("USB reset done, gadget %s\n", udc->driver->driver.name); /* ep0 traffic is legal from now on */ - UDC_IRQ_EN_REG = UDC_DS_CHG_IE | UDC_EP0_IE; + omap_writew(UDC_DS_CHG_IE | UDC_EP0_IE, + UDC_IRQ_EN); } change &= ~UDC_USB_RESET; } @@ -1818,7 +1867,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) VDBG("devstat %03x, ignore change %03x\n", devstat, change); - UDC_IRQ_SRC_REG = UDC_DS_CHG; + omap_writew(UDC_DS_CHG, UDC_IRQ_SRC); } static irqreturn_t omap_udc_irq(int irq, void *_udc) @@ -1829,7 +1878,7 @@ static irqreturn_t omap_udc_irq(int irq, void *_udc) unsigned long flags; spin_lock_irqsave(&udc->lock, flags); - irq_src = UDC_IRQ_SRC_REG; + irq_src = omap_readw(UDC_IRQ_SRC); /* Device state change (usb ch9 stuff) */ if (irq_src & UDC_DS_CHG) { @@ -1852,7 +1901,7 @@ static irqreturn_t omap_udc_irq(int irq, void *_udc) irq_src &= ~(UDC_TXN_DONE|UDC_RXN_CNT|UDC_RXN_EOT); } - irq_src &= ~(UDC_SOF|UDC_EPN_TX|UDC_EPN_RX); + irq_src &= ~(UDC_IRQ_SOF | UDC_EPN_TX|UDC_EPN_RX); if (irq_src) DBG("udc_irq, unhandled %03x\n", irq_src); spin_unlock_irqrestore(&udc->lock, flags); @@ -1873,7 +1922,7 @@ static void pio_out_timer(unsigned long _ep) spin_lock_irqsave(&ep->udc->lock, flags); if (!list_empty(&ep->queue) && ep->ackwait) { use_ep(ep, UDC_EP_SEL); - stat_flg = UDC_STAT_FLG_REG; + stat_flg = omap_readw(UDC_STAT_FLG); if ((stat_flg & UDC_ACK) && (!(stat_flg & UDC_FIFO_EN) || (ep->double_buf && HALF_FULL(stat_flg)))) { @@ -1883,8 +1932,8 @@ static void pio_out_timer(unsigned long _ep) req = container_of(ep->queue.next, struct omap_req, queue); (void) read_fifo(ep, req); - UDC_EP_NUM_REG = ep->bEndpointAddress; - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(ep->bEndpointAddress, UDC_EP_NUM); + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); ep->ackwait = 1 + ep->double_buf; } else deselect_ep(); @@ -1904,20 +1953,20 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) unsigned long flags; spin_lock_irqsave(&udc->lock, flags); - epn_stat = UDC_EPN_STAT_REG; - irq_src = UDC_IRQ_SRC_REG; + epn_stat = omap_readw(UDC_EPN_STAT); + irq_src = omap_readw(UDC_IRQ_SRC); /* handle OUT first, to avoid some wasteful NAKs */ if (irq_src & UDC_EPN_RX) { epnum = (epn_stat >> 8) & 0x0f; - UDC_IRQ_SRC_REG = UDC_EPN_RX; + omap_writew(UDC_EPN_RX, UDC_IRQ_SRC); status = IRQ_HANDLED; ep = &udc->ep[epnum]; ep->irqs++; - UDC_EP_NUM_REG = epnum | UDC_EP_SEL; + omap_writew(epnum | UDC_EP_SEL, UDC_EP_NUM); ep->fnf = 0; - if ((UDC_STAT_FLG_REG & UDC_ACK)) { + if (omap_readw(UDC_STAT_FLG) & UDC_ACK) { ep->ackwait--; if (!list_empty(&ep->queue)) { int stat; @@ -1929,15 +1978,15 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) } } /* min 6 clock delay before clearing EP_SEL ... */ - epn_stat = UDC_EPN_STAT_REG; - epn_stat = UDC_EPN_STAT_REG; - UDC_EP_NUM_REG = epnum; + epn_stat = omap_readw(UDC_EPN_STAT); + epn_stat = omap_readw(UDC_EPN_STAT); + omap_writew(epnum, UDC_EP_NUM); /* enabling fifo _after_ clearing ACK, contrary to docs, * reduces lossage; timer still needed though (sigh). */ if (ep->fnf) { - UDC_CTRL_REG = UDC_SET_FIFO_EN; + omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); ep->ackwait = 1 + ep->double_buf; } mod_timer(&ep->timer, PIO_OUT_TIMEOUT); @@ -1946,13 +1995,13 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) /* then IN transfers */ else if (irq_src & UDC_EPN_TX) { epnum = epn_stat & 0x0f; - UDC_IRQ_SRC_REG = UDC_EPN_TX; + omap_writew(UDC_EPN_TX, UDC_IRQ_SRC); status = IRQ_HANDLED; ep = &udc->ep[16 + epnum]; ep->irqs++; - UDC_EP_NUM_REG = epnum | UDC_EP_DIR | UDC_EP_SEL; - if ((UDC_STAT_FLG_REG & UDC_ACK)) { + omap_writew(epnum | UDC_EP_DIR | UDC_EP_SEL, UDC_EP_NUM); + if (omap_readw(UDC_STAT_FLG) & UDC_ACK) { ep->ackwait = 0; if (!list_empty(&ep->queue)) { req = container_of(ep->queue.next, @@ -1961,9 +2010,9 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) } } /* min 6 clock delay before clearing EP_SEL ... */ - epn_stat = UDC_EPN_STAT_REG; - epn_stat = UDC_EPN_STAT_REG; - UDC_EP_NUM_REG = epnum | UDC_EP_DIR; + epn_stat = omap_readw(UDC_EPN_STAT); + epn_stat = omap_readw(UDC_EPN_STAT); + omap_writew(epnum | UDC_EP_DIR, UDC_EP_NUM); /* then 6 clocks before it'd tx */ } @@ -1991,7 +2040,7 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) req = list_entry(ep->queue.next, struct omap_req, queue); use_ep(ep, UDC_EP_SEL); - stat = UDC_STAT_FLG_REG; + stat = omap_readw(UDC_STAT_FLG); /* NOTE: like the other controller drivers, this isn't * currently reporting lost or damaged frames. @@ -2023,9 +2072,14 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) if (!list_empty(&ep->queue)) pending = 1; } - if (!pending) - UDC_IRQ_EN_REG &= ~UDC_SOF_IE; - UDC_IRQ_SRC_REG = UDC_SOF; + if (!pending) { + u16 w; + + w = omap_readw(UDC_IRQ_EN); + w &= ~UDC_SOF_IE; + omap_writew(w, UDC_IRQ_EN); + } + omap_writew(UDC_IRQ_SOF, UDC_IRQ_SRC); spin_unlock_irqrestore(&udc->lock, flags); return IRQ_HANDLED; @@ -2074,7 +2128,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) continue; use_ep(ep, 0); - UDC_CTRL_REG = UDC_SET_HALT; + omap_writew(UDC_SET_HALT, UDC_CTRL); } udc->ep0_pending = 0; udc->ep[0].irqs = 0; @@ -2098,7 +2152,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) } DBG("bound to driver %s\n", driver->driver.name); - UDC_IRQ_SRC_REG = UDC_IRQ_SRC_MASK; + omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); /* connect to bus through transceiver */ if (udc->transceiver) { @@ -2195,7 +2249,7 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) else buf[0] = 0; - stat_flg = UDC_STAT_FLG_REG; + stat_flg = omap_readw(UDC_STAT_FLG); seq_printf(s, "\n%s %s%s%sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n", ep->name, buf, @@ -2262,11 +2316,11 @@ static int proc_otg_show(struct seq_file *s) trans = CONTROL_DEVCONF_REG; } else { ctrl_name = "tranceiver_ctrl"; - trans = USB_TRANSCEIVER_CTRL_REG; + trans = omap_readw(USB_TRANSCEIVER_CTRL); } seq_printf(s, "\nOTG rev %d.%d, %s %05x\n", tmp >> 4, tmp & 0xf, ctrl_name, trans); - tmp = OTG_SYSCON_1_REG; + tmp = omap_readw(OTG_SYSCON_1); seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," FOURBITS "\n", tmp, trx_mode(USB2_TRX_MODE(tmp), trans & CONF_USB2_UNI_R), @@ -2278,7 +2332,7 @@ static int proc_otg_show(struct seq_file *s) (tmp & HST_IDLE_EN) ? " !host" : "", (tmp & DEV_IDLE_EN) ? " !dev" : "", (tmp & OTG_RESET_DONE) ? " reset_done" : " reset_active"); - tmp = OTG_SYSCON_2_REG; + tmp = omap_readl(OTG_SYSCON_2); seq_printf(s, "otg_syscon2 %08x%s" EIGHTBITS " b_ase_brst=%d hmc=%d\n", tmp, (tmp & OTG_EN) ? " otg_en" : "", @@ -2293,7 +2347,7 @@ static int proc_otg_show(struct seq_file *s) (tmp & HMC_TLLATTACH) ? " tllattach" : "", B_ASE_BRST(tmp), OTG_HMC(tmp)); - tmp = OTG_CTRL_REG; + tmp = omap_readl(OTG_CTRL); seq_printf(s, "otg_ctrl %06x" EIGHTBITS EIGHTBITS "%s\n", tmp, (tmp & OTG_ASESSVLD) ? " asess" : "", (tmp & OTG_BSESSEND) ? " bsess_end" : "", @@ -2313,13 +2367,13 @@ static int proc_otg_show(struct seq_file *s) (tmp & OTG_PU_VBUS) ? " pu_vb" : "", (tmp & OTG_PU_ID) ? " pu_id" : "" ); - tmp = OTG_IRQ_EN_REG; + tmp = omap_readw(OTG_IRQ_EN); seq_printf(s, "otg_irq_en %04x" "\n", tmp); - tmp = OTG_IRQ_SRC_REG; + tmp = omap_readw(OTG_IRQ_SRC); seq_printf(s, "otg_irq_src %04x" "\n", tmp); - tmp = OTG_OUTCTRL_REG; + tmp = omap_readw(OTG_OUTCTRL); seq_printf(s, "otg_outctrl %04x" "\n", tmp); - tmp = OTG_TEST_REG; + tmp = omap_readw(OTG_TEST); seq_printf(s, "otg_test %04x" "\n", tmp); return 0; } @@ -2340,7 +2394,7 @@ static int proc_udc_show(struct seq_file *s, void *_) driver_desc, use_dma ? " (dma)" : ""); - tmp = UDC_REV_REG & 0xff; + tmp = omap_readw(UDC_REV) & 0xff; seq_printf(s, "UDC rev %d.%d, fifo mode %d, gadget %s\n" "hmc %d, transceiver %s\n", @@ -2354,16 +2408,16 @@ static int proc_udc_show(struct seq_file *s, void *_) ? "external" : "(none)")); if (cpu_class_is_omap1()) { seq_printf(s, "ULPD control %04x req %04x status %04x\n", - __REG16(ULPD_CLOCK_CTRL), - __REG16(ULPD_SOFT_REQ), - __REG16(ULPD_STATUS_REQ)); + omap_readw(ULPD_CLOCK_CTRL), + omap_readw(ULPD_SOFT_REQ), + omap_readw(ULPD_STATUS_REQ)); } /* OTG controller registers */ if (!cpu_is_omap15xx()) proc_otg_show(s); - tmp = UDC_SYSCON1_REG; + tmp = omap_readw(UDC_SYSCON1); seq_printf(s, "\nsyscon1 %04x" EIGHTBITS "\n", tmp, (tmp & UDC_CFG_LOCK) ? " cfg_lock" : "", (tmp & UDC_DATA_ENDIAN) ? " data_endian" : "", @@ -2382,7 +2436,7 @@ static int proc_udc_show(struct seq_file *s, void *_) return 0; } - tmp = UDC_DEVSTAT_REG; + tmp = omap_readw(UDC_DEVSTAT); seq_printf(s, "devstat %04x" EIGHTBITS "%s%s\n", tmp, (tmp & UDC_B_HNP_ENABLE) ? " b_hnp" : "", (tmp & UDC_A_HNP_SUPPORT) ? " a_hnp" : "", @@ -2394,20 +2448,20 @@ static int proc_udc_show(struct seq_file *s, void *_) (tmp & UDC_ADD) ? " ADD" : "", (tmp & UDC_DEF) ? " DEF" : "", (tmp & UDC_ATT) ? " ATT" : ""); - seq_printf(s, "sof %04x\n", UDC_SOF_REG); - tmp = UDC_IRQ_EN_REG; + seq_printf(s, "sof %04x\n", omap_readw(UDC_SOF)); + tmp = omap_readw(UDC_IRQ_EN); seq_printf(s, "irq_en %04x" FOURBITS "%s\n", tmp, (tmp & UDC_SOF_IE) ? " sof" : "", (tmp & UDC_EPN_RX_IE) ? " epn_rx" : "", (tmp & UDC_EPN_TX_IE) ? " epn_tx" : "", (tmp & UDC_DS_CHG_IE) ? " ds_chg" : "", (tmp & UDC_EP0_IE) ? " ep0" : ""); - tmp = UDC_IRQ_SRC_REG; + tmp = omap_readw(UDC_IRQ_SRC); seq_printf(s, "irq_src %04x" EIGHTBITS "%s%s\n", tmp, (tmp & UDC_TXN_DONE) ? " txn_done" : "", (tmp & UDC_RXN_CNT) ? " rxn_cnt" : "", (tmp & UDC_RXN_EOT) ? " rxn_eot" : "", - (tmp & UDC_SOF) ? " sof" : "", + (tmp & UDC_IRQ_SOF) ? " sof" : "", (tmp & UDC_EPN_RX) ? " epn_rx" : "", (tmp & UDC_EPN_TX) ? " epn_tx" : "", (tmp & UDC_DS_CHG) ? " ds_chg" : "", @@ -2417,7 +2471,7 @@ static int proc_udc_show(struct seq_file *s, void *_) if (use_dma) { unsigned i; - tmp = UDC_DMA_IRQ_EN_REG; + tmp = omap_readw(UDC_DMA_IRQ_EN); seq_printf(s, "dma_irq_en %04x%s" EIGHTBITS "\n", tmp, (tmp & UDC_TX_DONE_IE(3)) ? " tx2_done" : "", (tmp & UDC_RX_CNT_IE(3)) ? " rx2_cnt" : "", @@ -2431,29 +2485,29 @@ static int proc_udc_show(struct seq_file *s, void *_) (tmp & UDC_RX_CNT_IE(1)) ? " rx0_cnt" : "", (tmp & UDC_RX_EOT_IE(1)) ? " rx0_eot" : ""); - tmp = UDC_RXDMA_CFG_REG; + tmp = omap_readw(UDC_RXDMA_CFG); seq_printf(s, "rxdma_cfg %04x\n", tmp); if (tmp) { for (i = 0; i < 3; i++) { if ((tmp & (0x0f << (i * 4))) == 0) continue; seq_printf(s, "rxdma[%d] %04x\n", i, - UDC_RXDMA_REG(i + 1)); + omap_readw(UDC_RXDMA(i + 1))); } } - tmp = UDC_TXDMA_CFG_REG; + tmp = omap_readw(UDC_TXDMA_CFG); seq_printf(s, "txdma_cfg %04x\n", tmp); if (tmp) { for (i = 0; i < 3; i++) { if (!(tmp & (0x0f << (i * 4)))) continue; seq_printf(s, "txdma[%d] %04x\n", i, - UDC_TXDMA_REG(i + 1)); + omap_readw(UDC_TXDMA(i + 1))); } } } - tmp = UDC_DEVSTAT_REG; + tmp = omap_readw(UDC_DEVSTAT); if (tmp & UDC_ATT) { proc_ep_show(s, &udc->ep[0]); if (tmp & UDC_ADD) { @@ -2505,7 +2559,7 @@ static inline void remove_proc_file(void) {} * buffer space among the endpoints we'll be operating. * * NOTE: as of OMAP 1710 ES2.0, writing a new endpoint config when - * UDC_SYSCON_1_REG.CFG_LOCK is set can now work. We won't use that + * UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that * capability yet though. */ static unsigned __init @@ -2567,9 +2621,9 @@ omap_ep_setup(char *name, u8 addr, u8 type, name, addr, epn_rxtx, maxp, dbuf ? "x2" : "", buf); if (addr & USB_DIR_IN) - UDC_EP_TX_REG(addr & 0xf) = epn_rxtx; + omap_writew(epn_rxtx, UDC_EP_TX(addr & 0xf)); else - UDC_EP_RX_REG(addr) = epn_rxtx; + omap_writew(epn_rxtx, UDC_EP_RX(addr)); /* next endpoint's buffer starts after this one's */ buf += maxp; @@ -2608,15 +2662,15 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) unsigned tmp, buf; /* abolish any previous hardware state */ - UDC_SYSCON1_REG = 0; - UDC_IRQ_EN_REG = 0; - UDC_IRQ_SRC_REG = UDC_IRQ_SRC_MASK; - UDC_DMA_IRQ_EN_REG = 0; - UDC_RXDMA_CFG_REG = 0; - UDC_TXDMA_CFG_REG = 0; + omap_writew(0, UDC_SYSCON1); + omap_writew(0, UDC_IRQ_EN); + omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); + omap_writew(0, UDC_DMA_IRQ_EN); + omap_writew(0, UDC_RXDMA_CFG); + omap_writew(0, UDC_TXDMA_CFG); /* UDC_PULLUP_EN gates the chip clock */ - // OTG_SYSCON_1_REG |= DEV_IDLE_EN; + // OTG_SYSCON_1 |= DEV_IDLE_EN; udc = kzalloc(sizeof(*udc), GFP_KERNEL); if (!udc) @@ -2647,8 +2701,8 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) /* initially disable all non-ep0 endpoints */ for (tmp = 1; tmp < 15; tmp++) { - UDC_EP_RX_REG(tmp) = 0; - UDC_EP_TX_REG(tmp) = 0; + omap_writew(0, UDC_EP_RX(tmp)); + omap_writew(0, UDC_EP_TX(tmp)); } #define OMAP_BULK_EP(name,addr) \ @@ -2733,7 +2787,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) ERR("unsupported fifo_mode #%d\n", fifo_mode); return -ENODEV; } - UDC_SYSCON1_REG = UDC_CFG_LOCK|UDC_SELF_PWR; + omap_writew(UDC_CFG_LOCK|UDC_SELF_PWR, UDC_SYSCON1); INFO("fifo mode %d, %d bytes not used\n", fifo_mode, 2048 - buf); return 0; } @@ -2777,7 +2831,7 @@ static int __init omap_udc_probe(struct platform_device *pdev) } INFO("OMAP UDC rev %d.%d%s\n", - UDC_REV_REG >> 4, UDC_REV_REG & 0xf, + omap_readw(UDC_REV) >> 4, omap_readw(UDC_REV) & 0xf, config->otg ? ", Mini-AB" : ""); /* use the mode given to us by board init code */ @@ -2792,12 +2846,12 @@ static int __init omap_udc_probe(struct platform_device *pdev) * know when to turn PULLUP_EN on/off; and that * means we always "need" the 48MHz clock. */ - u32 tmp = FUNC_MUX_CTRL_0_REG; - - FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510; + u32 tmp = omap_readl(FUNC_MUX_CTRL_0); + tmp &= ~VBUS_CTRL_1510; + omap_writel(tmp, FUNC_MUX_CTRL_0); tmp |= VBUS_MODE_1510; tmp &= ~VBUS_CTRL_1510; - FUNC_MUX_CTRL_0_REG = tmp; + omap_writel(tmp, FUNC_MUX_CTRL_0); } } else { /* The transceiver may package some GPIO logic or handle @@ -2877,7 +2931,7 @@ known: #endif /* starting with omap1710 es2.0, clear toggle is a separate bit */ - if (UDC_REV_REG >= 0x61) + if (omap_readw(UDC_REV) >= 0x61) udc->clr_halt = UDC_RESET_EP | UDC_CLRDATA_TOGGLE; else udc->clr_halt = UDC_RESET_EP; @@ -2975,7 +3029,7 @@ static int __exit omap_udc_remove(struct platform_device *pdev) put_device(udc->transceiver->dev); udc->transceiver = NULL; } - UDC_SYSCON1_REG = 0; + omap_writew(0, UDC_SYSCON1); remove_proc_file(); @@ -3006,7 +3060,7 @@ static int __exit omap_udc_remove(struct platform_device *pdev) * * REVISIT we should probably reject suspend requests when there's a host * session active, rather than disconnecting, at least on boards that can - * report VBUS irqs (UDC_DEVSTAT_REG.UDC_ATT). And in any case, we need to + * report VBUS irqs (UDC_DEVSTAT.UDC_ATT). And in any case, we need to * make host resumes and VBUS detection trigger OMAP wakeup events; that * may involve talking to an external transceiver (e.g. isp1301). */ @@ -3015,7 +3069,7 @@ static int omap_udc_suspend(struct platform_device *dev, pm_message_t message) { u32 devstat; - devstat = UDC_DEVSTAT_REG; + devstat = omap_readw(UDC_DEVSTAT); /* we're requesting 48 MHz clock if the pullup is enabled * (== we're attached to the host) and we're not suspended, diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h index c6b9cbc7230..8522bbb1227 100644 --- a/drivers/usb/gadget/omap_udc.h +++ b/drivers/usb/gadget/omap_udc.h @@ -8,23 +8,22 @@ /* * USB device/endpoint management registers */ -#define UDC_REG(offset) __REG16(UDC_BASE + (offset)) -#define UDC_REV_REG UDC_REG(0x0) /* Revision */ -#define UDC_EP_NUM_REG UDC_REG(0x4) /* Which endpoint */ +#define UDC_REV (UDC_BASE + 0x0) /* Revision */ +#define UDC_EP_NUM (UDC_BASE + 0x4) /* Which endpoint */ # define UDC_SETUP_SEL (1 << 6) # define UDC_EP_SEL (1 << 5) # define UDC_EP_DIR (1 << 4) /* low 4 bits for endpoint number */ -#define UDC_DATA_REG UDC_REG(0x08) /* Endpoint FIFO */ -#define UDC_CTRL_REG UDC_REG(0x0C) /* Endpoint control */ +#define UDC_DATA (UDC_BASE + 0x08) /* Endpoint FIFO */ +#define UDC_CTRL (UDC_BASE + 0x0C) /* Endpoint control */ # define UDC_CLR_HALT (1 << 7) # define UDC_SET_HALT (1 << 6) # define UDC_CLRDATA_TOGGLE (1 << 3) # define UDC_SET_FIFO_EN (1 << 2) # define UDC_CLR_EP (1 << 1) # define UDC_RESET_EP (1 << 0) -#define UDC_STAT_FLG_REG UDC_REG(0x10) /* Endpoint status */ +#define UDC_STAT_FLG (UDC_BASE + 0x10) /* Endpoint status */ # define UDC_NO_RXPACKET (1 << 15) # define UDC_MISS_IN (1 << 14) # define UDC_DATA_FLUSH (1 << 13) @@ -38,8 +37,8 @@ # define UDC_FIFO_EN (1 << 2) # define UDC_NON_ISO_FIFO_EMPTY (1 << 1) # define UDC_NON_ISO_FIFO_FULL (1 << 0) -#define UDC_RXFSTAT_REG UDC_REG(0x14) /* OUT bytecount */ -#define UDC_SYSCON1_REG UDC_REG(0x18) /* System config 1 */ +#define UDC_RXFSTAT (UDC_BASE + 0x14) /* OUT bytecount */ +#define UDC_SYSCON1 (UDC_BASE + 0x18) /* System config 1 */ # define UDC_CFG_LOCK (1 << 8) # define UDC_DATA_ENDIAN (1 << 7) # define UDC_DMA_ENDIAN (1 << 6) @@ -48,12 +47,12 @@ # define UDC_SELF_PWR (1 << 2) # define UDC_SOFF_DIS (1 << 1) # define UDC_PULLUP_EN (1 << 0) -#define UDC_SYSCON2_REG UDC_REG(0x1C) /* System config 2 */ +#define UDC_SYSCON2 (UDC_BASE + 0x1C) /* System config 2 */ # define UDC_RMT_WKP (1 << 6) # define UDC_STALL_CMD (1 << 5) # define UDC_DEV_CFG (1 << 3) # define UDC_CLR_CFG (1 << 2) -#define UDC_DEVSTAT_REG UDC_REG(0x20) /* Device status */ +#define UDC_DEVSTAT (UDC_BASE + 0x20) /* Device status */ # define UDC_B_HNP_ENABLE (1 << 9) # define UDC_A_HNP_SUPPORT (1 << 8) # define UDC_A_ALT_HNP_SUPPORT (1 << 7) @@ -64,26 +63,26 @@ # define UDC_ADD (1 << 2) # define UDC_DEF (1 << 1) # define UDC_ATT (1 << 0) -#define UDC_SOF_REG UDC_REG(0x24) /* Start of frame */ +#define UDC_SOF (UDC_BASE + 0x24) /* Start of frame */ # define UDC_FT_LOCK (1 << 12) # define UDC_TS_OK (1 << 11) # define UDC_TS 0x03ff -#define UDC_IRQ_EN_REG UDC_REG(0x28) /* Interrupt enable */ +#define UDC_IRQ_EN (UDC_BASE + 0x28) /* Interrupt enable */ # define UDC_SOF_IE (1 << 7) # define UDC_EPN_RX_IE (1 << 5) # define UDC_EPN_TX_IE (1 << 4) # define UDC_DS_CHG_IE (1 << 3) # define UDC_EP0_IE (1 << 0) -#define UDC_DMA_IRQ_EN_REG UDC_REG(0x2C) /* DMA irq enable */ +#define UDC_DMA_IRQ_EN (UDC_BASE + 0x2C) /* DMA irq enable */ /* rx/tx dma channels numbered 1-3 not 0-2 */ # define UDC_TX_DONE_IE(n) (1 << (4 * (n) - 2)) # define UDC_RX_CNT_IE(n) (1 << (4 * (n) - 3)) # define UDC_RX_EOT_IE(n) (1 << (4 * (n) - 4)) -#define UDC_IRQ_SRC_REG UDC_REG(0x30) /* Interrupt source */ +#define UDC_IRQ_SRC (UDC_BASE + 0x30) /* Interrupt source */ # define UDC_TXN_DONE (1 << 10) # define UDC_RXN_CNT (1 << 9) # define UDC_RXN_EOT (1 << 8) -# define UDC_SOF (1 << 7) +# define UDC_IRQ_SOF (1 << 7) # define UDC_EPN_RX (1 << 5) # define UDC_EPN_TX (1 << 4) # define UDC_DS_CHG (1 << 3) @@ -91,41 +90,41 @@ # define UDC_EP0_RX (1 << 1) # define UDC_EP0_TX (1 << 0) # define UDC_IRQ_SRC_MASK 0x7bf -#define UDC_EPN_STAT_REG UDC_REG(0x34) /* EP irq status */ -#define UDC_DMAN_STAT_REG UDC_REG(0x38) /* DMA irq status */ +#define UDC_EPN_STAT (UDC_BASE + 0x34) /* EP irq status */ +#define UDC_DMAN_STAT (UDC_BASE + 0x38) /* DMA irq status */ # define UDC_DMA_RX_SB (1 << 12) # define UDC_DMA_RX_SRC(x) (((x)>>8) & 0xf) # define UDC_DMA_TX_SRC(x) (((x)>>0) & 0xf) /* DMA configuration registers: up to three channels in each direction. */ -#define UDC_RXDMA_CFG_REG UDC_REG(0x40) /* 3 eps for RX DMA */ +#define UDC_RXDMA_CFG (UDC_BASE + 0x40) /* 3 eps for RX DMA */ # define UDC_DMA_REQ (1 << 12) -#define UDC_TXDMA_CFG_REG UDC_REG(0x44) /* 3 eps for TX DMA */ -#define UDC_DATA_DMA_REG UDC_REG(0x48) /* rx/tx fifo addr */ +#define UDC_TXDMA_CFG (UDC_BASE + 0x44) /* 3 eps for TX DMA */ +#define UDC_DATA_DMA (UDC_BASE + 0x48) /* rx/tx fifo addr */ /* rx/tx dma control, numbering channels 1-3 not 0-2 */ -#define UDC_TXDMA_REG(chan) UDC_REG(0x50 - 4 + 4 * (chan)) +#define UDC_TXDMA(chan) (UDC_BASE + 0x50 - 4 + 4 * (chan)) # define UDC_TXN_EOT (1 << 15) /* bytes vs packets */ # define UDC_TXN_START (1 << 14) /* start transfer */ # define UDC_TXN_TSC 0x03ff /* units in xfer */ -#define UDC_RXDMA_REG(chan) UDC_REG(0x60 - 4 + 4 * (chan)) +#define UDC_RXDMA(chan) (UDC_BASE + 0x60 - 4 + 4 * (chan)) # define UDC_RXN_STOP (1 << 15) /* enable EOT irq */ # define UDC_RXN_TC 0x00ff /* packets in xfer */ /* * Endpoint configuration registers (used before CFG_LOCK is set) - * UDC_EP_TX_REG(0) is unused + * UDC_EP_TX(0) is unused */ -#define UDC_EP_RX_REG(endpoint) UDC_REG(0x80 + (endpoint)*4) +#define UDC_EP_RX(endpoint) (UDC_BASE + 0x80 + (endpoint)*4) # define UDC_EPN_RX_VALID (1 << 15) # define UDC_EPN_RX_DB (1 << 14) /* buffer size in bits 13, 12 */ # define UDC_EPN_RX_ISO (1 << 11) /* buffer pointer in low 11 bits */ -#define UDC_EP_TX_REG(endpoint) UDC_REG(0xc0 + (endpoint)*4) - /* same bitfields as in RX_REG */ +#define UDC_EP_TX(endpoint) (UDC_BASE + 0xc0 + (endpoint)*4) + /* same bitfields as in RX */ /*-------------------------------------------------------------------------*/ @@ -195,14 +194,14 @@ struct omap_udc { /*-------------------------------------------------------------------------*/ -#define MOD_CONF_CTRL_0_REG __REG32(MOD_CONF_CTRL_0) -#define VBUS_W2FC_1510 (1 << 17) /* 0 gpio0, 1 dvdd2 pin */ +/* MOD_CONF_CTRL_0 */ +#define VBUS_W2FC_1510 (1 << 17) /* 0 gpio0, 1 dvdd2 pin */ -#define FUNC_MUX_CTRL_0_REG __REG32(FUNC_MUX_CTRL_0) +/* FUNC_MUX_CTRL_0 */ #define VBUS_CTRL_1510 (1 << 19) /* 1 connected (software) */ #define VBUS_MODE_1510 (1 << 18) /* 0 hardware, 1 software */ -#define HMC_1510 ((MOD_CONF_CTRL_0_REG >> 1) & 0x3f) -#define HMC_1610 (OTG_SYSCON_2_REG & 0x3f) +#define HMC_1510 ((omap_readl(MOD_CONF_CTRL_0) >> 1) & 0x3f) +#define HMC_1610 (omap_readl(OTG_SYSCON_2) & 0x3f) #define HMC (cpu_is_omap15xx() ? HMC_1510 : HMC_1610) diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 6859fb5f1d6..2b7c04079d5 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -169,13 +169,16 @@ static void start_hnp(struct ohci_hcd *ohci) { const unsigned port = ohci_to_hcd(ohci)->self.otg_port - 1; unsigned long flags; + u32 l; otg_start_hnp(ohci->transceiver); local_irq_save(flags); ohci->transceiver->state = OTG_STATE_A_SUSPEND; writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]); - OTG_CTRL_REG &= ~OTG_A_BUSREQ; + l = omap_readl(OTG_CTRL); + l &= ~OTG_A_BUSREQ; + omap_writel(l, OTG_CTRL); local_irq_restore(flags); } diff --git a/include/asm-arm/arch-omap/usb.h b/include/asm-arm/arch-omap/usb.h index 2147d18aaea..ddf1861e6df 100644 --- a/include/asm-arm/arch-omap/usb.h +++ b/include/asm-arm/arch-omap/usb.h @@ -34,11 +34,8 @@ /* * OTG and transceiver registers, for OMAPs starting with ARM926 */ -#define OTG_REG32(offset) __REG32(OTG_BASE + (offset)) -#define OTG_REG16(offset) __REG16(OTG_BASE + (offset)) - -#define OTG_REV_REG OTG_REG32(0x00) -#define OTG_SYSCON_1_REG OTG_REG32(0x04) +#define OTG_REV (OTG_BASE + 0x00) +#define OTG_SYSCON_1 (OTG_BASE + 0x04) # define USB2_TRX_MODE(w) (((w)>>24)&0x07) # define USB1_TRX_MODE(w) (((w)>>20)&0x07) # define USB0_TRX_MODE(w) (((w)>>16)&0x07) @@ -47,7 +44,7 @@ # define DEV_IDLE_EN (1 << 13) # define OTG_RESET_DONE (1 << 2) # define OTG_SOFT_RESET (1 << 1) -#define OTG_SYSCON_2_REG OTG_REG32(0x08) +#define OTG_SYSCON_2 (OTG_BASE + 0x08) # define OTG_EN (1 << 31) # define USBX_SYNCHRO (1 << 30) # define OTG_MST16 (1 << 29) @@ -65,7 +62,7 @@ # define HMC_TLLSPEED (1 << 7) # define HMC_TLLATTACH (1 << 6) # define OTG_HMC(w) (((w)>>0)&0x3f) -#define OTG_CTRL_REG OTG_REG32(0x0c) +#define OTG_CTRL (OTG_BASE + 0x0c) # define OTG_USB2_EN (1 << 29) # define OTG_USB2_DP (1 << 28) # define OTG_USB2_DM (1 << 27) @@ -92,7 +89,7 @@ # define OTG_PD_VBUS (1 << 2) # define OTG_PU_VBUS (1 << 1) # define OTG_PU_ID (1 << 0) -#define OTG_IRQ_EN_REG OTG_REG16(0x10) +#define OTG_IRQ_EN (OTG_BASE + 0x10) /* 16-bit */ # define DRIVER_SWITCH (1 << 15) # define A_VBUS_ERR (1 << 13) # define A_REQ_TMROUT (1 << 12) @@ -102,9 +99,9 @@ # define B_SRP_DONE (1 << 8) # define B_SRP_STARTED (1 << 7) # define OPRT_CHG (1 << 0) -#define OTG_IRQ_SRC_REG OTG_REG16(0x14) +#define OTG_IRQ_SRC (OTG_BASE + 0x14) /* 16-bit */ // same bits as in IRQ_EN -#define OTG_OUTCTRL_REG OTG_REG16(0x18) +#define OTG_OUTCTRL (OTG_BASE + 0x18) /* 16-bit */ # define OTGVPD (1 << 14) # define OTGVPU (1 << 13) # define OTGPUID (1 << 12) @@ -117,13 +114,13 @@ # define USB0VDR (1 << 2) # define USB0PDEN (1 << 1) # define USB0PUEN (1 << 0) -#define OTG_TEST_REG OTG_REG16(0x20) -#define OTG_VENDOR_CODE_REG OTG_REG32(0xfc) +#define OTG_TEST (OTG_BASE + 0x20) /* 16-bit */ +#define OTG_VENDOR_CODE (OTG_BASE + 0xfc) /* 16-bit */ /*-------------------------------------------------------------------------*/ /* OMAP1 */ -#define USB_TRANSCEIVER_CTRL_REG __REG32(0xfffe1000 + 0x0064) +#define USB_TRANSCEIVER_CTRL (0xfffe1000 + 0x0064) # define CONF_USB2_UNI_R (1 << 8) # define CONF_USB1_UNI_R (1 << 7) # define CONF_USB_PORT0_R(x) (((x)>>4)&0x7) -- cgit v1.2.3-70-g09d2 From e1f80bfca86ab48b7bed731b32262fb1a2835de5 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:43 +0300 Subject: ARM: OMAP: Remove __REG access for multi-omap This does not play nicely with multi-omap as it cannot be replaced by a function in io.c for omaps with different IO bases. Signed-off-by: Tony Lindgren --- include/asm-arm/arch-omap/io.h | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h index 160578e1f55..e1fb7ec7d47 100644 --- a/include/asm-arm/arch-omap/io.h +++ b/include/asm-arm/arch-omap/io.h @@ -183,35 +183,12 @@ #define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v)) #define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v)) -/* 16 bit uses LDRH/STRH, base +/- offset_8 */ -typedef struct { volatile u16 offset[256]; } __regbase16; -#define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff)) \ - ->offset[((vaddr)&0xff)>>1] -#define __REG16(paddr) __REGV16(io_p2v(paddr)) - -/* 8/32 bit uses LDR/STR, base +/- offset_12 */ -typedef struct { volatile u8 offset[4096]; } __regbase8; -#define __REGV8(vaddr) ((__regbase8 *)((vaddr)&~4095)) \ - ->offset[((vaddr)&4095)>>0] -#define __REG8(paddr) __REGV8(io_p2v(paddr)) - -typedef struct { volatile u32 offset[4096]; } __regbase32; -#define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095)) \ - ->offset[((vaddr)&4095)>>2] -#define __REG32(paddr) __REGV32(io_p2v(paddr)) - extern void omap1_map_common_io(void); extern void omap1_init_common_hw(void); extern void omap2_map_common_io(void); extern void omap2_init_common_hw(void); -#else - -#define __REG8(paddr) io_p2v(paddr) -#define __REG16(paddr) io_p2v(paddr) -#define __REG32(paddr) io_p2v(paddr) - #endif #endif -- cgit v1.2.3-70-g09d2 From a58caad11301a5bdc2d7b76596ab5477221f7a9b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Jul 2008 12:24:44 +0300 Subject: ARM: OMAP: Introduce omap_globals and prcm access functions for multi-omap New struct omap_globals contains the omap processor specific module bases. Use omap_globals to set the various base addresses to make detecting omap chip type simpler. Also introduce OMAP1_IO_ADDRESS and OMAP2_IO_ADDRESS for future multi-omap patches. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/cm.h | 13 +++----- arch/arm/mach-omap2/control.c | 24 +++++---------- arch/arm/mach-omap2/memory.c | 11 +++++-- arch/arm/mach-omap2/mux.c | 2 +- arch/arm/mach-omap2/prcm.c | 55 +++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/prm.h | 12 ++------ arch/arm/mach-omap2/sdrc.h | 10 +++---- arch/arm/plat-omap/common.c | 59 +++++++++++++++++++++++++++++++------ include/asm-arm/arch-omap/common.h | 15 ++++++++++ include/asm-arm/arch-omap/control.h | 4 +-- include/asm-arm/arch-omap/io.h | 3 ++ 11 files changed, 150 insertions(+), 58 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 8489f3029fe..e2d404e6945 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -96,15 +96,10 @@ /* Clock management domain register get/set */ #ifndef __ASSEMBLER__ -static inline void cm_write_mod_reg(u32 val, s16 module, s16 idx) -{ - __raw_writel(val, OMAP_CM_REGADDR(module, idx)); -} - -static inline u32 cm_read_mod_reg(s16 module, s16 idx) -{ - return __raw_readl(OMAP_CM_REGADDR(module, idx)); -} + +extern u32 cm_read_mod_reg(s16 module, u16 idx); +extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); + #endif /* CM register bits shared between 24XX and 3430 */ diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index a5d86a49c21..51f70300996 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -13,22 +13,21 @@ #undef DEBUG #include +#include -#include - +#include #include -static u32 omap2_ctrl_base; +static void __iomem *omap2_ctrl_base; -#define OMAP_CTRL_REGADDR(reg) (void __iomem *)IO_ADDRESS(omap2_ctrl_base \ - + (reg)) +#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg)) -void omap_ctrl_base_set(u32 base) +void __init omap2_set_globals_control(struct omap_globals *omap2_globals) { - omap2_ctrl_base = base; + omap2_ctrl_base = omap2_globals->ctrl; } -u32 omap_ctrl_base_get(void) +void __iomem *omap_ctrl_base_get(void) { return omap2_ctrl_base; } @@ -50,25 +49,16 @@ u32 omap_ctrl_readl(u16 offset) void omap_ctrl_writeb(u8 val, u16 offset) { - pr_debug("omap_ctrl_writeb: writing 0x%0x to 0x%0x\n", val, - (u32)OMAP_CTRL_REGADDR(offset)); - __raw_writeb(val, OMAP_CTRL_REGADDR(offset)); } void omap_ctrl_writew(u16 val, u16 offset) { - pr_debug("omap_ctrl_writew: writing 0x%0x to 0x%0x\n", val, - (u32)OMAP_CTRL_REGADDR(offset)); - __raw_writew(val, OMAP_CTRL_REGADDR(offset)); } void omap_ctrl_writel(u32 val, u16 offset) { - pr_debug("omap_ctrl_writel: writing 0x%0x to 0x%0x\n", val, - (u32)OMAP_CTRL_REGADDR(offset)); - __raw_writel(val, OMAP_CTRL_REGADDR(offset)); } diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c index 12479081881..73cadb2c75c 100644 --- a/arch/arm/mach-omap2/memory.c +++ b/arch/arm/mach-omap2/memory.c @@ -24,6 +24,7 @@ #include +#include #include #include @@ -32,8 +33,8 @@ #include "memory.h" #include "sdrc.h" -unsigned long omap2_sdrc_base; -unsigned long omap2_sms_base; +void __iomem *omap2_sdrc_base; +void __iomem *omap2_sms_base; static struct memory_timings mem_timings; static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2; @@ -154,6 +155,12 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode) mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); } +void __init omap2_set_globals_memory(struct omap_globals *omap2_globals) +{ + omap2_sdrc_base = omap2_globals->sdrc; + omap2_sms_base = omap2_globals->sms; +} + /* turn on smart idle modes for SDRAM scheduler and controller */ void __init omap2_init_memory(void) { diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 930770012a7..8f98b20f30a 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -236,7 +236,7 @@ void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u8 reg) warn = (orig != reg); if (debug || warn) printk(KERN_WARNING - "MUX: setup %s (0x%08x): 0x%02x -> 0x%02x\n", + "MUX: setup %s (0x%p): 0x%04x -> 0x%04x\n", cfg->name, omap_ctrl_base_get() + cfg->mux_reg, orig, reg); } diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index b12f423b859..9584376d055 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -16,12 +16,18 @@ #include #include #include +#include -#include +#include +#include +#include "clock.h" #include "prm.h" #include "prm-regbits-24xx.h" +static void __iomem *prm_base; +static void __iomem *cm_base; + extern void omap2_clk_prepare_for_reboot(void); u32 omap_prcm_get_reset_sources(void) @@ -41,3 +47,50 @@ void omap_prcm_arch_reset(char mode) prm_write_mod_reg(wkup, WKUP_MOD, RM_RSTCTRL); } } + +static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg) +{ + BUG_ON(!base); + return __raw_readl(base + module + reg); +} + +static inline void __omap_prcm_write(u32 value, void __iomem *base, + s16 module, u16 reg) +{ + BUG_ON(!base); + __raw_writel(value, base + module + reg); +} + +/* Read a register in a PRM module */ +u32 prm_read_mod_reg(s16 module, u16 idx) +{ + return __omap_prcm_read(prm_base, module, idx); +} +EXPORT_SYMBOL(prm_read_mod_reg); + +/* Write into a register in a PRM module */ +void prm_write_mod_reg(u32 val, s16 module, u16 idx) +{ + __omap_prcm_write(val, prm_base, module, idx); +} +EXPORT_SYMBOL(prm_write_mod_reg); + +/* Read a register in a CM module */ +u32 cm_read_mod_reg(s16 module, u16 idx) +{ + return __omap_prcm_read(cm_base, module, idx); +} +EXPORT_SYMBOL(cm_read_mod_reg); + +/* Write into a register in a CM module */ +void cm_write_mod_reg(u32 val, s16 module, u16 idx) +{ + __omap_prcm_write(val, cm_base, module, idx); +} +EXPORT_SYMBOL(cm_write_mod_reg); + +void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) +{ + prm_base = omap2_globals->prm; + cm_base = omap2_globals->cm; +} diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index dcdb35bfa0c..e901fb99b23 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -166,16 +166,8 @@ #ifndef __ASSEMBLER__ /* Power/reset management domain register get/set */ - -static inline void prm_write_mod_reg(u32 val, s16 module, s16 idx) -{ - __raw_writel(val, OMAP_PRM_REGADDR(module, idx)); -} - -static inline u32 prm_read_mod_reg(s16 module, s16 idx) -{ - return __raw_readl(OMAP_PRM_REGADDR(module, idx)); -} +extern u32 prm_read_mod_reg(s16 module, u16 idx); +extern void prm_write_mod_reg(u32 val, s16 module, u16 idx); #endif diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h index d7f23bc9550..1b1fe4f6e03 100644 --- a/arch/arm/mach-omap2/sdrc.h +++ b/arch/arm/mach-omap2/sdrc.h @@ -18,13 +18,11 @@ #include #ifndef __ASSEMBLER__ -extern unsigned long omap2_sdrc_base; -extern unsigned long omap2_sms_base; +extern void __iomem *omap2_sdrc_base; +extern void __iomem *omap2_sms_base; -#define OMAP_SDRC_REGADDR(reg) \ - (void __iomem *)IO_ADDRESS(omap2_sdrc_base + (reg)) -#define OMAP_SMS_REGADDR(reg) \ - (void __iomem *)IO_ADDRESS(omap2_sms_base + (reg)) +#define OMAP_SDRC_REGADDR(reg) (omap2_sdrc_base + (reg)) +#define OMAP_SMS_REGADDR(reg) (omap2_sms_base + (reg)) /* SDRC global register get/set */ diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index bd1cef2c3c1..8d04929a3c7 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -241,30 +242,70 @@ arch_initcall(omap_init_clocksource_32k); /* Global address base setup code */ +#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) + +static struct omap_globals *omap2_globals; + +static void __init __omap2_set_globals(void) +{ + omap2_set_globals_memory(omap2_globals); + omap2_set_globals_control(omap2_globals); + omap2_set_globals_prcm(omap2_globals); +} + +#endif + #if defined(CONFIG_ARCH_OMAP2420) + +static struct omap_globals omap242x_globals = { + .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x48014000), + .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE), + .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE), + .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE), + .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE), + .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CM_BASE), +}; + void __init omap2_set_globals_242x(void) { - omap2_sdrc_base = OMAP2420_SDRC_BASE; - omap2_sms_base = OMAP2420_SMS_BASE; - omap_ctrl_base_set(OMAP2420_CTRL_BASE); + omap2_globals = &omap242x_globals; + __omap2_set_globals(); } #endif #if defined(CONFIG_ARCH_OMAP2430) + +static struct omap_globals omap243x_globals = { + .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4900a000), + .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE), + .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE), + .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE), + .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE), + .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_CM_BASE), +}; + void __init omap2_set_globals_243x(void) { - omap2_sdrc_base = OMAP243X_SDRC_BASE; - omap2_sms_base = OMAP243X_SMS_BASE; - omap_ctrl_base_set(OMAP243X_CTRL_BASE); + omap2_globals = &omap243x_globals; + __omap2_set_globals(); } #endif #if defined(CONFIG_ARCH_OMAP3430) + +static struct omap_globals omap343x_globals = { + .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4830A000), + .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE), + .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE), + .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE), + .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE), + .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_CM_BASE), +}; + void __init omap2_set_globals_343x(void) { - omap2_sdrc_base = OMAP343X_SDRC_BASE; - omap2_sms_base = OMAP343X_SMS_BASE; - omap_ctrl_base_set(OMAP343X_CTRL_BASE); + omap2_globals = &omap343x_globals; + __omap2_set_globals(); } #endif diff --git a/include/asm-arm/arch-omap/common.h b/include/asm-arm/arch-omap/common.h index 36a3b62d4d8..8ac03071f60 100644 --- a/include/asm-arm/arch-omap/common.h +++ b/include/asm-arm/arch-omap/common.h @@ -47,8 +47,23 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate, } #endif +/* IO bases for various OMAP processors */ +struct omap_globals { + void __iomem *tap; /* Control module ID code */ + void __iomem *sdrc; /* SDRAM Controller */ + void __iomem *sms; /* SDRAM Memory Scheduler */ + void __iomem *ctrl; /* System Control Module */ + void __iomem *prm; /* Power and Reset Management */ + void __iomem *cm; /* Clock Management */ +}; + void omap2_set_globals_242x(void); void omap2_set_globals_243x(void); void omap2_set_globals_343x(void); +/* These get called from omap2_set_globals_xxxx(), do not call these */ +void omap2_set_globals_memory(struct omap_globals *); +void omap2_set_globals_control(struct omap_globals *); +void omap2_set_globals_prcm(struct omap_globals *); + #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff --git a/include/asm-arm/arch-omap/control.h b/include/asm-arm/arch-omap/control.h index 59c0686f8be..987553e3eeb 100644 --- a/include/asm-arm/arch-omap/control.h +++ b/include/asm-arm/arch-omap/control.h @@ -167,8 +167,7 @@ #ifndef __ASSEMBLY__ #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) -extern void omap_ctrl_base_set(u32 base); -extern u32 omap_ctrl_base_get(void); +extern void __iomem *omap_ctrl_base_get(void); extern u8 omap_ctrl_readb(u16 offset); extern u16 omap_ctrl_readw(u16 offset); extern u32 omap_ctrl_readl(u16 offset); @@ -176,7 +175,6 @@ extern void omap_ctrl_writeb(u8 val, u16 offset); extern void omap_ctrl_writew(u16 val, u16 offset); extern void omap_ctrl_writel(u32 val, u16 offset); #else -#define omap_ctrl_base_set(x) WARN_ON(1) #define omap_ctrl_base_get() 0 #define omap_ctrl_readb(x) 0 #define omap_ctrl_readw(x) 0 diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h index e1fb7ec7d47..0b13557fd30 100644 --- a/include/asm-arm/arch-omap/io.h +++ b/include/asm-arm/arch-omap/io.h @@ -60,6 +60,7 @@ #define IO_SIZE 0x40000 #define IO_VIRT (IO_PHYS - IO_OFFSET) #define IO_ADDRESS(pa) ((pa) - IO_OFFSET) +#define OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET) #define io_p2v(pa) ((pa) - IO_OFFSET) #define io_v2p(va) ((va) + IO_OFFSET) @@ -91,6 +92,7 @@ #define IO_OFFSET 0x90000000 #define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ +#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ #define io_p2v(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ #define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */ @@ -148,6 +150,7 @@ #define IO_OFFSET 0x90000000 #define IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ +#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ #define io_p2v(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ #define io_v2p(va) ((va) - IO_OFFSET)/* Works for L3 and L4 */ -- cgit v1.2.3-70-g09d2 From 097c584cd48844d9ef8402bdc6ab49e7e2135f31 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 3 Jul 2008 12:24:45 +0300 Subject: ARM: OMAP: Add OMAP chip type structure; clean up mach-omap2/id.c Add a new OMAP chip identification interface, omap_chip_id. omap_chip_id is a structure which contains one bit for each OMAP2/3 CPU type, and on 3430, ES level. For example, the CHIP_IS_OMAP2420 bit is set in omap_chip at boot on an OMAP2420. On OMAP3430ES2, both CHIP_IS_OMAP3430 and CHIP_IS_OMAP3430ES2 bits are set. omap_chip is set in mach-omap2/id.c by _set_omap_chip(). Other code should use the omap_chip_is() function to test against omap_chip. Also, clean up id.c by splitting some code out of omap_check_revision() into its own function, _set_system_rev(); and converting some debug printk()s into pr_debug(). Second revision. Signed-off-by: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/id.c | 195 ++++++++++++++++++++++++++++++++++------ include/asm-arm/arch-omap/cpu.h | 39 +++++++- 2 files changed, 205 insertions(+), 29 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 4dfd878d796..dff4b16cead 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -17,16 +17,23 @@ #include -#if defined(CONFIG_ARCH_OMAP2420) -#define OMAP24XX_TAP_BASE io_p2v(0x48014000) -#endif +#include +#include -#if defined(CONFIG_ARCH_OMAP2430) -#define OMAP24XX_TAP_BASE io_p2v(0x4900A000) +#if defined(CONFIG_ARCH_OMAP2420) +#define TAP_BASE io_p2v(0x48014000) +#elif defined(CONFIG_ARCH_OMAP2430) +#define TAP_BASE io_p2v(0x4900A000) +#elif defined(CONFIG_ARCH_OMAP34XX) +#define TAP_BASE io_p2v(0x4830A000) #endif #define OMAP_TAP_IDCODE 0x0204 +#if defined(CONFIG_ARCH_OMAP34XX) +#define OMAP_TAP_PROD_ID 0x0210 +#else #define OMAP_TAP_PROD_ID 0x0208 +#endif #define OMAP_TAP_DIE_ID_0 0x0218 #define OMAP_TAP_DIE_ID_1 0x021C @@ -56,9 +63,134 @@ static struct omap_id omap_ids[] __initdata = { { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 }, }; +static struct omap_chip_id omap_chip; + +/** + * omap_chip_is - test whether currently running OMAP matches a chip type + * @oc: omap_chip_t to test against + * + * Test whether the currently-running OMAP chip matches the supplied + * chip type 'oc'. Returns 1 upon a match; 0 upon failure. + */ +int omap_chip_is(struct omap_chip_id oci) +{ + return (oci.oc & omap_chip.oc) ? 1 : 0; +} +EXPORT_SYMBOL(omap_chip_is); + static u32 __init read_tap_reg(int reg) { - return __raw_readl(OMAP24XX_TAP_BASE + reg); + unsigned int regval = 0; + u32 cpuid; + + /* Reading the IDCODE register on 3430 ES1 results in a + * data abort as the register is not exposed on the OCP + * Hence reading the Cortex Rev + */ + cpuid = read_cpuid(CPUID_ID); + + /* If the processor type is Cortex-A8 and the revision is 0x0 + * it means its Cortex r0p0 which is 3430 ES1 + */ + if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) { + switch (reg) { + case OMAP_TAP_IDCODE : regval = 0x0B7AE02F; break; + /* Making DevType as 0xF in ES1 to differ from ES2 */ + case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break; + case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break; + case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break; + case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break; + case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break; + } + } else + regval = __raw_readl(TAP_BASE + reg); + + return regval; + +} + +/* + * _set_system_rev - set the system_rev global based on current OMAP chip type + * + * Set the system_rev global. This is primarily used by the cpu_is_omapxxxx() + * macros. + */ +static void __init _set_system_rev(u32 type, u8 rev) +{ + u32 i, ctrl_status; + + /* + * system_rev encoding is as follows + * system_rev & 0xff000000 -> Omap Class (24xx/34xx) + * system_rev & 0xfff00000 -> Omap Sub Class (242x/343x) + * system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430) + * system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 ) + * system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD ) + * system_rev & 0x000000c0 -> IDCODE revision[6:7] + * system_rev & 0x0000003f -> sys_boot[0:5] + */ + /* Embedding the ES revision info in type field */ + system_rev = type; + /* Also add IDCODE revision info only two lower bits */ + system_rev |= ((rev & 0x3) << 6); + + /* Add in the device type and sys_boot fields (see above) */ + if (cpu_is_omap24xx()) { + i = OMAP24XX_CONTROL_STATUS; + } else if (cpu_is_omap343x()) { + i = OMAP343X_CONTROL_STATUS; + } else { + printk(KERN_ERR "id: unknown CPU type\n"); + BUG(); + } + ctrl_status = omap_ctrl_readl(i); + system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK | + OMAP2_SYSBOOT_4_MASK | + OMAP2_SYSBOOT_3_MASK | + OMAP2_SYSBOOT_2_MASK | + OMAP2_SYSBOOT_1_MASK | + OMAP2_SYSBOOT_0_MASK)); + system_rev |= (ctrl_status & OMAP2_DEVICETYPE_MASK); +} + + +/* + * _set_omap_chip - set the omap_chip global based on OMAP chip type + * + * Build the omap_chip bits. This variable is used by powerdomain and + * clockdomain code to indicate whether structures are applicable for + * the current OMAP chip type by ANDing it against a 'platform' bitfield + * in the structure. + */ +static void __init _set_omap_chip(void) +{ + if (cpu_is_omap343x()) { + + omap_chip.oc = CHIP_IS_OMAP3430; + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) + omap_chip.oc |= CHIP_IS_OMAP3430ES1; + else if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) + omap_chip.oc |= CHIP_IS_OMAP3430ES2; + + } else if (cpu_is_omap243x()) { + + /* Currently only supports 2430ES2.1 and 2430-all */ + omap_chip.oc |= CHIP_IS_OMAP2430; + + } else if (cpu_is_omap242x()) { + + /* Currently only supports 2420ES2.1.1 and 2420-all */ + omap_chip.oc |= CHIP_IS_OMAP2420; + + } else { + + /* Current CPU not supported by this code. */ + printk(KERN_WARNING "OMAP chip type code does not yet support " + "this CPU type.\n"); + WARN_ON(1); + + } + } void __init omap2_check_revision(void) @@ -76,21 +208,31 @@ void __init omap2_check_revision(void) rev = (idcode >> 28) & 0x0f; dev_type = (prod_id >> 16) & 0x0f; -#ifdef DEBUG - printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", - idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); - printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_0)); - printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", - read_tap_reg(OMAP_TAP_DIE_ID_1), - (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); - printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_2)); - printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_3)); - printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", - prod_id, dev_type); -#endif + pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", + idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); + pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", + read_tap_reg(OMAP_TAP_DIE_ID_0)); + pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", + read_tap_reg(OMAP_TAP_DIE_ID_1), + (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); + pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", + read_tap_reg(OMAP_TAP_DIE_ID_2)); + pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", + read_tap_reg(OMAP_TAP_DIE_ID_3)); + pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", + prod_id, dev_type); + + /* + * Detection for 34xx ES2.0 and above can be done with just + * hawkeye and rev. See TRM 1.5.2 Device Identification. + * Note that rev cannot be used directly as ES1.0 uses value 0. + */ + if (hawkeye == 0xb7ae) { + system_rev = 0x34300000 | ((1 + rev) << 12); + pr_info("OMAP%04x ES2.%i\n", system_rev >> 16, rev); + _set_omap_chip(); + return; + } /* Check hawkeye ids */ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { @@ -114,16 +256,15 @@ void __init omap2_check_revision(void) omap_ids[i].type >> 16); j = i; } - system_rev = omap_ids[j].type; - system_rev |= rev << 8; + _set_system_rev(omap_ids[j].type, rev); - /* Add the cpu class info (24xx) */ - system_rev |= 0x24; + _set_omap_chip(); pr_info("OMAP%04x", system_rev >> 16); if ((system_rev >> 8) & 0x0f) - printk("%x", (system_rev >> 8) & 0x0f); - printk("\n"); + pr_info("ES%x", (system_rev >> 12) & 0xf); + pr_info("\n"); + } diff --git a/include/asm-arm/arch-omap/cpu.h b/include/asm-arm/arch-omap/cpu.h index e8a4cf52778..52db09f8328 100644 --- a/include/asm-arm/arch-omap/cpu.h +++ b/include/asm-arm/arch-omap/cpu.h @@ -3,7 +3,7 @@ * * OMAP cpu type detection * - * Copyright (C) 2004 Nokia Corporation + * Copyright (C) 2004, 2008 Nokia Corporation * * Written by Tony Lindgren * @@ -26,6 +26,12 @@ #ifndef __ASM_ARCH_OMAP_CPU_H #define __ASM_ARCH_OMAP_CPU_H +struct omap_chip_id { + u8 oc; +}; + +#define OMAP_CHIP_INIT(x) { .oc = x } + extern unsigned int system_rev; #define omap2_cpu_rev() ((system_rev >> 12) & 0x0f) @@ -345,6 +351,33 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP2430_REV_ES1_0 0x24300000 #define OMAP3430_REV_ES1_0 0x34300000 #define OMAP3430_REV_ES2_0 0x34301000 +#define OMAP3430_REV_ES2_1 0x34302000 +#define OMAP3430_REV_ES2_2 0x34303000 + +/* + * omap_chip bits + * + * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is + * valid on all chips of that type. CHIP_IS_OMAP3430ES{1,2} indicates + * something that is only valid on that particular ES revision. + * + * These bits may be ORed together to indicate structures that are + * available on multiple chip types. + * + * To test whether a particular structure matches the current OMAP chip type, + * use omap_chip_is(). + * + */ +#define CHIP_IS_OMAP2420 (1 << 0) +#define CHIP_IS_OMAP2430 (1 << 1) +#define CHIP_IS_OMAP3430 (1 << 2) +#define CHIP_IS_OMAP3430ES1 (1 << 3) +#define CHIP_IS_OMAP3430ES2 (1 << 4) + +#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430) + +int omap_chip_is(struct omap_chip_id oci); + /* * Macro to detect device type i.e. EMU/HS/TST/GP/BAD @@ -362,6 +395,8 @@ IS_OMAP_TYPE(3430, 0x3430) #define is_device_type_gp() (get_device_type() == DEVICE_TYPE_GP) #define is_device_type_bad() (get_device_type() == DEVICE_TYPE_BAD) -#endif +void omap2_check_revision(void); + +#endif /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */ #endif -- cgit v1.2.3-70-g09d2 From 542313cc98e72d026d2df86f515699dfaface460 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 3 Jul 2008 12:24:45 +0300 Subject: ARM: OMAP2: Clock: Add OMAP3 DPLL autoidle functions This patch adds support for DPLL autoidle control to the OMAP3 clock framework. These functions will be used by the noncore DPLL enable and disable code - this is because, according to the CDP code, the DPLL autoidle status must be saved and restored across DPLL lock/bypass/off transitions. N.B.: the CORE DPLL (DPLL3) has three autoidle mode options, rather than just two. This code currently does not support the third option, low-power bypass autoidle. Signed-off-by: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock34xx.c | 299 +++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/clock34xx.h | 83 +++++++--- arch/arm/mach-omap2/cm-regbits-34xx.h | 18 +- arch/arm/mach-omap2/cm.h | 1 + include/asm-arm/arch-omap/clock.h | 5 + 5 files changed, 376 insertions(+), 30 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index b42bdd6079a..4263099b1ad 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -1,10 +1,11 @@ /* * OMAP3-specific clock framework functions * - * Copyright (C) 2007 Texas Instruments, Inc. - * Copyright (C) 2007 Nokia Corporation + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Copyright (C) 2007-2008 Nokia Corporation * * Written by Paul Walmsley + * Testing and integration fixes by Jouni Högander * * Parts of this code are based on code written by * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu @@ -23,6 +24,7 @@ #include #include #include +#include #include #include @@ -37,8 +39,11 @@ #include "cm.h" #include "cm-regbits-34xx.h" -/* CM_CLKEN_PLL*.EN* bit values */ -#define DPLL_LOCKED 0x7 +/* CM_AUTOIDLE_PLL*.AUTO_* bit values */ +#define DPLL_AUTOIDLE_DISABLE 0x0 +#define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1 + +#define MAX_DPLL_WAIT_TRIES 1000000 /** * omap3_dpll_recalc - recalculate DPLL rate @@ -53,6 +58,290 @@ static void omap3_dpll_recalc(struct clk *clk) propagate_rate(clk); } +/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */ +static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits) +{ + const struct dpll_data *dd; + + dd = clk->dpll_data; + + cm_rmw_reg_bits(dd->enable_mask, clken_bits << __ffs(dd->enable_mask), + dd->control_reg); +} + +/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */ +static int _omap3_wait_dpll_status(struct clk *clk, u8 state) +{ + const struct dpll_data *dd; + int i = 0; + int ret = -EINVAL; + u32 idlest_mask; + + dd = clk->dpll_data; + + state <<= dd->idlest_bit; + idlest_mask = 1 << dd->idlest_bit; + + while (((cm_read_reg(dd->idlest_reg) & idlest_mask) != state) && + i < MAX_DPLL_WAIT_TRIES) { + i++; + udelay(1); + } + + if (i == MAX_DPLL_WAIT_TRIES) { + printk(KERN_ERR "clock: %s failed transition to '%s'\n", + clk->name, (state) ? "locked" : "bypassed"); + } else { + pr_debug("clock: %s transition to '%s' in %d loops\n", + clk->name, (state) ? "locked" : "bypassed", i); + + ret = 0; + } + + return ret; +} + +/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */ + +/* + * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to lock. Waits for the DPLL to report + * readiness before returning. Will save and restore the DPLL's + * autoidle state across the enable, per the CDP code. If the DPLL + * locked successfully, return 0; if the DPLL did not lock in the time + * allotted, or DPLL3 was passed in, return -EINVAL. + */ +static int _omap3_noncore_dpll_lock(struct clk *clk) +{ + u8 ai; + int r; + + if (clk == &dpll3_ck) + return -EINVAL; + + pr_debug("clock: locking DPLL %s\n", clk->name); + + ai = omap3_dpll_autoidle_read(clk); + + _omap3_dpll_write_clken(clk, DPLL_LOCKED); + + if (ai) { + /* + * If no downstream clocks are enabled, CM_IDLEST bit + * may never become active, so don't wait for DPLL to lock. + */ + r = 0; + omap3_dpll_allow_idle(clk); + } else { + r = _omap3_wait_dpll_status(clk, 1); + omap3_dpll_deny_idle(clk); + }; + + return r; +} + +/* + * omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to enter low-power bypass mode. In + * bypass mode, the DPLL's rate is set equal to its parent clock's + * rate. Waits for the DPLL to report readiness before returning. + * Will save and restore the DPLL's autoidle state across the enable, + * per the CDP code. If the DPLL entered bypass mode successfully, + * return 0; if the DPLL did not enter bypass in the time allotted, or + * DPLL3 was passed in, or the DPLL does not support low-power bypass, + * return -EINVAL. + */ +static int _omap3_noncore_dpll_bypass(struct clk *clk) +{ + int r; + u8 ai; + + if (clk == &dpll3_ck) + return -EINVAL; + + if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) + return -EINVAL; + + pr_debug("clock: configuring DPLL %s for low-power bypass\n", + clk->name); + + ai = omap3_dpll_autoidle_read(clk); + + _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS); + + r = _omap3_wait_dpll_status(clk, 0); + + if (ai) + omap3_dpll_allow_idle(clk); + else + omap3_dpll_deny_idle(clk); + + return r; +} + +/* + * _omap3_noncore_dpll_stop - instruct a DPLL to stop + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to enter low-power stop. Will save and + * restore the DPLL's autoidle state across the stop, per the CDP + * code. If DPLL3 was passed in, or the DPLL does not support + * low-power stop, return -EINVAL; otherwise, return 0. + */ +static int _omap3_noncore_dpll_stop(struct clk *clk) +{ + u8 ai; + + if (clk == &dpll3_ck) + return -EINVAL; + + if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP))) + return -EINVAL; + + pr_debug("clock: stopping DPLL %s\n", clk->name); + + ai = omap3_dpll_autoidle_read(clk); + + _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP); + + if (ai) + omap3_dpll_allow_idle(clk); + else + omap3_dpll_deny_idle(clk); + + return 0; +} + +/** + * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. + * The choice of modes depends on the DPLL's programmed rate: if it is + * the same as the DPLL's parent clock, it will enter bypass; + * otherwise, it will enter lock. This code will wait for the DPLL to + * indicate readiness before returning, unless the DPLL takes too long + * to enter the target state. Intended to be used as the struct clk's + * enable function. If DPLL3 was passed in, or the DPLL does not + * support low-power stop, or if the DPLL took too long to enter + * bypass or lock, return -EINVAL; otherwise, return 0. + */ +static int omap3_noncore_dpll_enable(struct clk *clk) +{ + int r; + + if (clk == &dpll3_ck) + return -EINVAL; + + if (clk->parent->rate == clk_get_rate(clk)) + r = _omap3_noncore_dpll_bypass(clk); + else + r = _omap3_noncore_dpll_lock(clk); + + return r; +} + +/** + * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode + * @clk: pointer to a DPLL struct clk + * + * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. + * The choice of modes depends on the DPLL's programmed rate: if it is + * the same as the DPLL's parent clock, it will enter bypass; + * otherwise, it will enter lock. This code will wait for the DPLL to + * indicate readiness before returning, unless the DPLL takes too long + * to enter the target state. Intended to be used as the struct clk's + * enable function. If DPLL3 was passed in, or the DPLL does not + * support low-power stop, or if the DPLL took too long to enter + * bypass or lock, return -EINVAL; otherwise, return 0. + */ +static void omap3_noncore_dpll_disable(struct clk *clk) +{ + if (clk == &dpll3_ck) + return; + + _omap3_noncore_dpll_stop(clk); +} + +/** + * omap3_dpll_autoidle_read - read a DPLL's autoidle bits + * @clk: struct clk * of the DPLL to read + * + * Return the DPLL's autoidle bits, shifted down to bit 0. Returns + * -EINVAL if passed a null pointer or if the struct clk does not + * appear to refer to a DPLL. + */ +static u32 omap3_dpll_autoidle_read(struct clk *clk) +{ + const struct dpll_data *dd; + u32 v; + + if (!clk || !clk->dpll_data) + return -EINVAL; + + dd = clk->dpll_data; + + v = cm_read_reg(dd->autoidle_reg); + v &= dd->autoidle_mask; + v >>= __ffs(dd->autoidle_mask); + + return v; +} + +/** + * omap3_dpll_allow_idle - enable DPLL autoidle bits + * @clk: struct clk * of the DPLL to operate on + * + * Enable DPLL automatic idle control. This automatic idle mode + * switching takes effect only when the DPLL is locked, at least on + * OMAP3430. The DPLL will enter low-power stop when its downstream + * clocks are gated. No return value. + */ +static void omap3_dpll_allow_idle(struct clk *clk) +{ + const struct dpll_data *dd; + + if (!clk || !clk->dpll_data) + return; + + dd = clk->dpll_data; + + /* + * REVISIT: CORE DPLL can optionally enter low-power bypass + * by writing 0x5 instead of 0x1. Add some mechanism to + * optionally enter this mode. + */ + cm_rmw_reg_bits(dd->autoidle_mask, + DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask), + dd->autoidle_reg); +} + +/** + * omap3_dpll_deny_idle - prevent DPLL from automatically idling + * @clk: struct clk * of the DPLL to operate on + * + * Disable DPLL automatic idle control. No return value. + */ +static void omap3_dpll_deny_idle(struct clk *clk) +{ + const struct dpll_data *dd; + + if (!clk || !clk->dpll_data) + return; + + dd = clk->dpll_data; + + cm_rmw_reg_bits(dd->autoidle_mask, + DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask), + dd->autoidle_reg); +} + +/* Clock control for DPLL outputs */ + /** * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate * @clk: DPLL output struct clk @@ -89,6 +378,8 @@ static void omap3_clkoutx2_recalc(struct clk *clk) propagate_rate(clk); } +/* Common clock code */ + /* * As it is structured now, this will prevent an OMAP2/3 multiboot * kernel from compiling. This will need further attention. diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 73624dc04c9..e349d48ee80 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -1,14 +1,19 @@ /* * OMAP3 clock framework * - * Virtual clocks are introduced as a convenient tools. - * They are sources for other clocks and not supposed - * to be requested from drivers directly. - * * Copyright (C) 2007-2008 Texas Instruments, Inc. * Copyright (C) 2007-2008 Nokia Corporation * * Written by Paul Walmsley + * With many device clock fixes by Kevin Hilman and Jouni Högander + * DPLL bypass clock support added by Roman Tereshonkov + * + */ + +/* + * Virtual clocks are introduced as convenient tools. + * They are sources for other clocks and not supposed + * to be requested from drivers directly. */ #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H @@ -24,6 +29,11 @@ static void omap3_dpll_recalc(struct clk *clk); static void omap3_clkoutx2_recalc(struct clk *clk); +static void omap3_dpll_allow_idle(struct clk *clk); +static void omap3_dpll_deny_idle(struct clk *clk); +static u32 omap3_dpll_autoidle_read(struct clk *clk); +static int omap3_noncore_dpll_enable(struct clk *clk); +static void omap3_noncore_dpll_disable(struct clk *clk); /* * DPLL1 supplies clock to the MPU. @@ -33,6 +43,11 @@ static void omap3_clkoutx2_recalc(struct clk *clk); * DPLL5 supplies other peripheral clocks (USBHOST, USIM). */ +/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ +#define DPLL_LOW_POWER_STOP 0x1 +#define DPLL_LOW_POWER_BYPASS 0x5 +#define DPLL_LOCKED 0x7 + /* PRM CLOCKS */ /* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */ @@ -246,9 +261,14 @@ static const struct dpll_data dpll1_dd = { .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK, .control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL), .enable_mask = OMAP3430_EN_MPU_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), .auto_recal_bit = OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430_MPU_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430_MPU_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL), + .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), + .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT, }; static struct clk dpll1_ck = { @@ -303,16 +323,24 @@ static const struct dpll_data dpll2_dd = { .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK, .control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL), .enable_mask = OMAP3430_EN_IVA2_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) | + (1 << DPLL_LOW_POWER_BYPASS), .auto_recal_bit = OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL), + .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), + .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT }; static struct clk dpll2_ck = { .name = "dpll2_ck", .parent = &sys_ck, .dpll_data = &dpll2_dd, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, + .enable = &omap3_noncore_dpll_enable, + .disable = &omap3_noncore_dpll_disable, .recalc = &omap3_dpll_recalc, }; @@ -338,9 +366,11 @@ static struct clk dpll2_m2_ck = { .recalc = &omap2_clksel_recalc, }; -/* DPLL3 */ -/* Source clock for all interfaces and for some device fclks */ -/* Type: DPLL */ +/* + * DPLL3 + * Source clock for all interfaces and for some device fclks + * REVISIT: Also supports fast relock bypass - not included below + */ static const struct dpll_data dpll3_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK, @@ -350,6 +380,8 @@ static const struct dpll_data dpll3_dd = { .auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), + .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK, }; static struct clk dpll3_ck = { @@ -439,7 +471,7 @@ static struct clk core_ck = { .name = "core_ck", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK, + .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, .clksel = core_ck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -456,7 +488,7 @@ static struct clk dpll3_m2x2_ck = { .name = "dpll3_m2x2_ck", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK, + .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, .clksel = dpll3_m2x2_ck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -503,7 +535,7 @@ static struct clk emu_core_alwon_ck = { .parent = &dpll3_m3x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK, + .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, .clksel = emu_core_alwon_ck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -519,16 +551,23 @@ static const struct dpll_data dpll4_dd = { .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), + .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), + .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT, }; static struct clk dpll4_ck = { .name = "dpll4_ck", .parent = &sys_ck, .dpll_data = &dpll4_dd, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, + .enable = &omap3_noncore_dpll_enable, + .disable = &omap3_noncore_dpll_disable, .recalc = &omap3_dpll_recalc, }; @@ -584,7 +623,7 @@ static struct clk omap_96m_alwon_fck = { .parent = &dpll4_m2x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, .clksel = omap_96m_alwon_fck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -610,7 +649,7 @@ static struct clk cm_96m_fck = { .parent = &dpll4_m2x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, .clksel = cm_96m_fck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -652,7 +691,7 @@ static struct clk virt_omap_54m_fck = { .parent = &dpll4_m3x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, .clksel = virt_omap_54m_fck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -810,17 +849,23 @@ static const struct dpll_data dpll5_dd = { .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK, .control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2), .enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), .auto_recal_bit = OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL), + .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), + .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT, }; static struct clk dpll5_ck = { .name = "dpll5_ck", .parent = &sys_ck, .dpll_data = &dpll5_dd, - .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES | - ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES, + .enable = &omap3_noncore_dpll_enable, + .disable = &omap3_noncore_dpll_disable, .recalc = &omap3_dpll_recalc, }; @@ -1939,7 +1984,7 @@ static struct clk dss1_alwon_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_DSS1_SHIFT, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, .clksel = dss1_alwon_fck_clksel, .flags = CLOCK_IN_OMAP343X, .recalc = &omap2_clksel_recalc, @@ -1995,7 +2040,7 @@ static struct clk cam_mclk = { .parent = &dpll4_m5x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, .clksel = cam_mclk_clksel, .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_CAM_SHIFT, diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 3c38395f644..ee4c0ca1a70 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -72,7 +72,8 @@ #define OMAP3430_ST_IVA2 (1 << 0) /* CM_IDLEST_PLL_IVA2 */ -#define OMAP3430_ST_IVA2_CLK (1 << 0) +#define OMAP3430_ST_IVA2_CLK_SHIFT 0 +#define OMAP3430_ST_IVA2_CLK_MASK (1 << 0) /* CM_AUTOIDLE_PLL_IVA2 */ #define OMAP3430_AUTO_IVA2_DPLL_SHIFT 0 @@ -115,10 +116,7 @@ #define OMAP3430_ST_MPU (1 << 0) /* CM_IDLEST_PLL_MPU */ -#define OMAP3430_ST_MPU_CLK (1 << 0) -#define OMAP3430_ST_IVA2_CLK_MASK (1 << 0) - -/* CM_IDLEST_PLL_MPU */ +#define OMAP3430_ST_MPU_CLK_SHIFT 0 #define OMAP3430_ST_MPU_CLK_MASK (1 << 0) /* CM_AUTOIDLE_PLL_MPU */ @@ -408,8 +406,10 @@ #define OMAP3430_ST_12M_CLK (1 << 4) #define OMAP3430_ST_48M_CLK (1 << 3) #define OMAP3430_ST_96M_CLK (1 << 2) -#define OMAP3430_ST_PERIPH_CLK (1 << 1) -#define OMAP3430_ST_CORE_CLK (1 << 0) +#define OMAP3430_ST_PERIPH_CLK_SHIFT 1 +#define OMAP3430_ST_PERIPH_CLK_MASK (1 << 1) +#define OMAP3430_ST_CORE_CLK_SHIFT 0 +#define OMAP3430_ST_CORE_CLK_MASK (1 << 0) /* CM_IDLEST2_CKGEN */ #define OMAP3430ES2_ST_120M_CLK_SHIFT 1 @@ -423,6 +423,10 @@ #define OMAP3430_AUTO_CORE_DPLL_SHIFT 0 #define OMAP3430_AUTO_CORE_DPLL_MASK (0x7 << 0) +/* CM_AUTOIDLE2_PLL */ +#define OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT 0 +#define OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK (0x7 << 0) + /* CM_CLKSEL1_PLL */ /* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */ #define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27 diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 1dd873fcc2b..87a44c715aa 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -81,6 +81,7 @@ #define OMAP3430ES2_CM_FCLKEN3 0x0008 #define OMAP3430_CM_IDLEST_PLL CM_IDLEST2 #define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2 +#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2 #define OMAP3430_CM_CLKSEL1 CM_CLKSEL #define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL #define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2 diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h index 8490fbba39d..22daa5d64d3 100644 --- a/include/asm-arm/arch-omap/clock.h +++ b/include/asm-arm/arch-omap/clock.h @@ -34,11 +34,16 @@ struct dpll_data { u32 mult_mask; u32 div1_mask; # if defined(CONFIG_ARCH_OMAP3) + u8 modes; void __iomem *control_reg; u32 enable_mask; u8 auto_recal_bit; u8 recal_en_bit; u8 recal_st_bit; + void __iomem *autoidle_reg; + u32 autoidle_mask; + void __iomem *idlest_reg; + u8 idlest_bit; # endif }; -- cgit v1.2.3-70-g09d2 From 88b8ba90570067178d32c654ad95786041e86e86 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 3 Jul 2008 12:24:46 +0300 Subject: ARM: OMAP2: Clock: New OMAP2/3 DPLL rate rounding algorithm This patch adds a new rate rounding algorithm for DPLL clocks on the OMAP2/3 architecture. For a desired DPLL target rate, there may be several multiplier/divider (M, N) values which will generate a sufficiently close rate. Lower N values result in greater power economy. However, lower N values can cause the difference between the rounded rate and the target rate ("rate error") to be larger than it would be with a higher N. This can cause downstream devices to run more slowly than they otherwise would. This DPLL rate rounding algorithm: - attempts to find the lowest possible N (DPLL divider) to reach the target_rate (since, according to Richard Woodruff , lower N values save more power than higher N values). - allows developers to set an upper bound on the error between the rounded rate and the desired target rate ("rate tolerance"), so an appropriate balance between rate fidelity and power savings can be set. This maximum rate error tolerance is set via omap2_set_dpll_rate_tolerance(). - never returns a rounded rate higher than the target rate. The rate rounding algorithm caches the last rounded M, N, and rate computation to avoid rounding the rate twice for each clk_set_rate() call. (This patch does not yet implement set_rate for DPLLs; that follows in a future patch.) The algorithm trades execution speed for rate accuracy. It will find the (M, N) set that results in the least rate error, within a specified rate tolerance. It does this by evaluating each divider setting - on OMAP3, this involves 128 steps. Another approach to DPLL rate rounding would be to bail out as soon as a valid rate is found within the rate tolerance, which would trade rate accuracy for execution speed. Alternate implementations welcome. This code is not yet used by the OMAP24XX DPLL clock, since it is currently defined as a composite clock, fusing the DPLL M,N and the M2 output divider. This patch also renames the existing OMAP24xx DPLL programming functions to highlight that they program both the DPLL and the DPLL's output multiplier. Signed-off-by: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/clock.c | 198 +++++++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/clock.h | 5 + arch/arm/mach-omap2/clock24xx.c | 12 +-- arch/arm/mach-omap2/clock24xx.h | 17 +++- arch/arm/mach-omap2/clock34xx.h | 36 +++++-- include/asm-arm/arch-omap/clock.h | 9 +- 6 files changed, 258 insertions(+), 19 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 0243480e8bf..15675bce801 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -41,6 +41,24 @@ #define MAX_CLOCK_ENABLE_WAIT 100000 +/* DPLL rate rounding: minimum DPLL multiplier, divider values */ +#define DPLL_MIN_MULTIPLIER 1 +#define DPLL_MIN_DIVIDER 1 + +/* Possible error results from _dpll_test_mult */ +#define DPLL_MULT_UNDERFLOW (1 << 0) + +/* + * Scale factor to mitigate roundoff errors in DPLL rate rounding. + * The higher the scale factor, the greater the risk of arithmetic overflow, + * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR + * must be a power of DPLL_SCALE_BASE. + */ +#define DPLL_SCALE_FACTOR 64 +#define DPLL_SCALE_BASE 2 +#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ + (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) + u8 cpu_mask; /*------------------------------------------------------------------------- @@ -95,7 +113,7 @@ u32 omap2_get_dpll_rate(struct clk *clk) { long long dpll_clk; u32 dpll_mult, dpll_div, dpll; - const struct dpll_data *dd; + struct dpll_data *dd; dd = clk->dpll_data; /* REVISIT: What do we return on error? */ @@ -724,6 +742,184 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) return 0; } +/* DPLL rate rounding code */ + +/** + * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding + * @clk: struct clk * of the DPLL + * @tolerance: maximum rate error tolerance + * + * Set the maximum DPLL rate error tolerance for the rate rounding + * algorithm. The rate tolerance is an attempt to balance DPLL power + * saving (the least divider value "n") vs. rate fidelity (the least + * difference between the desired DPLL target rate and the rounded + * rate out of the algorithm). So, increasing the tolerance is likely + * to decrease DPLL power consumption and increase DPLL rate error. + * Returns -EINVAL if provided a null clock ptr or a clk that is not a + * DPLL; or 0 upon success. + */ +int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance) +{ + if (!clk || !clk->dpll_data) + return -EINVAL; + + clk->dpll_data->rate_tolerance = tolerance; + + return 0; +} + +static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n) +{ + unsigned long long num; + + num = (unsigned long long)parent_rate * m; + do_div(num, n); + return num; +} + +/* + * _dpll_test_mult - test a DPLL multiplier value + * @m: pointer to the DPLL m (multiplier) value under test + * @n: current DPLL n (divider) value under test + * @new_rate: pointer to storage for the resulting rounded rate + * @target_rate: the desired DPLL rate + * @parent_rate: the DPLL's parent clock rate + * + * This code tests a DPLL multiplier value, ensuring that the + * resulting rate will not be higher than the target_rate, and that + * the multiplier value itself is valid for the DPLL. Initially, the + * integer pointed to by the m argument should be prescaled by + * multiplying by DPLL_SCALE_FACTOR. The code will replace this with + * a non-scaled m upon return. This non-scaled m will result in a + * new_rate as close as possible to target_rate (but not greater than + * target_rate) given the current (parent_rate, n, prescaled m) + * triple. Returns DPLL_MULT_UNDERFLOW in the event that the + * non-scaled m attempted to underflow, which can allow the calling + * function to bail out early; or 0 upon success. + */ +static int _dpll_test_mult(int *m, int n, unsigned long *new_rate, + unsigned long target_rate, + unsigned long parent_rate) +{ + int flags = 0, carry = 0; + + /* Unscale m and round if necessary */ + if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL) + carry = 1; + *m = (*m / DPLL_SCALE_FACTOR) + carry; + + /* + * The new rate must be <= the target rate to avoid programming + * a rate that is impossible for the hardware to handle + */ + *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); + if (*new_rate > target_rate) { + (*m)--; + *new_rate = 0; + } + + /* Guard against m underflow */ + if (*m < DPLL_MIN_MULTIPLIER) { + *m = DPLL_MIN_MULTIPLIER; + *new_rate = 0; + flags = DPLL_MULT_UNDERFLOW; + } + + if (*new_rate == 0) + *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); + + return flags; +} + +/** + * omap2_dpll_round_rate - round a target rate for an OMAP DPLL + * @clk: struct clk * for a DPLL + * @target_rate: desired DPLL clock rate + * + * Given a DPLL, a desired target rate, and a rate tolerance, round + * the target rate to a possible, programmable rate for this DPLL. + * Rate tolerance is assumed to be set by the caller before this + * function is called. Attempts to select the minimum possible n + * within the tolerance to reduce power consumption. Stores the + * computed (m, n) in the DPLL's dpll_data structure so set_rate() + * will not need to call this (expensive) function again. Returns ~0 + * if the target rate cannot be rounded, either because the rate is + * too low or because the rate tolerance is set too tightly; or the + * rounded rate upon success. + */ +long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) +{ + int m, n, r, e, scaled_max_m; + unsigned long scaled_rt_rp, new_rate; + int min_e = -1, min_e_m = -1, min_e_n = -1; + + if (!clk || !clk->dpll_data) + return ~0; + + pr_debug("clock: starting DPLL round_rate for clock %s, target rate " + "%ld\n", clk->name, target_rate); + + scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR); + scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR; + + clk->dpll_data->last_rounded_rate = 0; + + for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) { + + /* Compute the scaled DPLL multiplier, based on the divider */ + m = scaled_rt_rp * n; + + /* + * Since we're counting n down, a m overflow means we can + * can immediately skip to the next n + */ + if (m > scaled_max_m) + continue; + + r = _dpll_test_mult(&m, n, &new_rate, target_rate, + clk->parent->rate); + + e = target_rate - new_rate; + pr_debug("clock: n = %d: m = %d: rate error is %d " + "(new_rate = %ld)\n", n, m, e, new_rate); + + if (min_e == -1 || + min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) { + min_e = e; + min_e_m = m; + min_e_n = n; + + pr_debug("clock: found new least error %d\n", min_e); + } + + /* + * Since we're counting n down, a m underflow means we + * can bail out completely (since as n decreases in + * the next iteration, there's no way that m can + * increase beyond the current m) + */ + if (r & DPLL_MULT_UNDERFLOW) + break; + } + + if (min_e < 0) { + pr_debug("clock: error: target rate or tolerance too low\n"); + return ~0; + } + + clk->dpll_data->last_rounded_m = min_e_m; + clk->dpll_data->last_rounded_n = min_e_n; + clk->dpll_data->last_rounded_rate = + _dpll_compute_new_rate(clk->parent->rate, min_e_m, min_e_n); + + pr_debug("clock: final least error: e = %d, m = %d, n = %d\n", + min_e, min_e_m, min_e_n); + pr_debug("clock: final rate: %ld (target rate: %ld)\n", + clk->dpll_data->last_rounded_rate, target_rate); + + return clk->dpll_data->last_rounded_rate; +} + /*------------------------------------------------------------------------- * Omap2 clock reset and init functions *-------------------------------------------------------------------------*/ diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index f97948548f2..3cd37cb57c5 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -18,11 +18,16 @@ #include +/* The maximum error between a target DPLL rate and the rounded rate in Hz */ +#define DEFAULT_DPLL_RATE_TOLERANCE 50000 + int omap2_clk_enable(struct clk *clk); void omap2_clk_disable(struct clk *clk); long omap2_clk_round_rate(struct clk *clk, unsigned long rate); int omap2_clk_set_rate(struct clk *clk, unsigned long rate); int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent); +int omap2_dpll_rate_tolerance_set(struct clk *clk, unsigned int tolerance); +long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate); #ifdef CONFIG_OMAP_RESET_CLOCKS void omap2_clk_disable_unused(struct clk *clk); diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index ece32d8acba..aa567876651 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c @@ -154,7 +154,7 @@ static void omap2_clk_fixed_disable(struct clk *clk) * Uses the current prcm set to tell if a rate is valid. * You can go slower, but not faster within a given rate set. */ -static u32 omap2_dpll_round_rate(unsigned long target_rate) +long omap2_dpllcore_round_rate(unsigned long target_rate) { u32 high, low, core_clk_src; @@ -183,14 +183,14 @@ static u32 omap2_dpll_round_rate(unsigned long target_rate) } -static void omap2_dpll_recalc(struct clk *clk) +static void omap2_dpllcore_recalc(struct clk *clk) { clk->rate = omap2_get_dpll_rate_24xx(clk); propagate_rate(clk); } -static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate) +static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) { u32 cur_rate, low, mult, div, valid_rate, done_rate; u32 bypass = 0; @@ -209,7 +209,7 @@ static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate) } else if ((rate == (cur_rate * 2)) && (mult == 1)) { omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); } else if (rate != cur_rate) { - valid_rate = omap2_dpll_round_rate(rate); + valid_rate = omap2_dpllcore_round_rate(rate); if (valid_rate != rate) goto dpll_exit; @@ -256,7 +256,7 @@ static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate) omap2_init_memory_params(omap2_dll_force_needed()); omap2_reprogram_sdrc(done_rate, 0); } - omap2_dpll_recalc(&dpll_ck); + omap2_dpllcore_recalc(&dpll_ck); ret = 0; dpll_exit: @@ -383,7 +383,7 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate) local_irq_restore(flags); } - omap2_dpll_recalc(&dpll_ck); + omap2_dpllcore_recalc(&dpll_ck); return 0; } diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h index 06e1118ddba..be4e25554e0 100644 --- a/arch/arm/mach-omap2/clock24xx.h +++ b/arch/arm/mach-omap2/clock24xx.h @@ -30,12 +30,12 @@ static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate); static void omap2_sys_clk_recalc(struct clk *clk); static void omap2_osc_clk_recalc(struct clk *clk); static void omap2_sys_clk_recalc(struct clk *clk); -static void omap2_dpll_recalc(struct clk *clk); +static void omap2_dpllcore_recalc(struct clk *clk); static int omap2_clk_fixed_enable(struct clk *clk); static void omap2_clk_fixed_disable(struct clk *clk); static int omap2_enable_osc_ck(struct clk *clk); static void omap2_disable_osc_ck(struct clk *clk); -static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate); +static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate); /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP @@ -665,20 +665,27 @@ static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */ * deal with this */ -static const struct dpll_data dpll_dd = { +static struct dpll_data dpll_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), .mult_mask = OMAP24XX_DPLL_MULT_MASK, .div1_mask = OMAP24XX_DPLL_DIV_MASK, + .max_multiplier = 1024, + .max_divider = 16, + .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; +/* + * XXX Cannot add round_rate here yet, as this is still a composite clock, + * not just a DPLL + */ static struct clk dpll_ck = { .name = "dpll_ck", .parent = &sys_ck, /* Can be func_32k also */ .dpll_data = &dpll_dd, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES | ALWAYS_ENABLED, - .recalc = &omap2_dpll_recalc, - .set_rate = &omap2_reprogram_dpll, + .recalc = &omap2_dpllcore_recalc, + .set_rate = &omap2_reprogram_dpllcore, }; static struct clk apll96_ck = { diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index e349d48ee80..05757eb032b 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h @@ -35,6 +35,10 @@ static u32 omap3_dpll_autoidle_read(struct clk *clk); static int omap3_noncore_dpll_enable(struct clk *clk); static void omap3_noncore_dpll_disable(struct clk *clk); +/* Maximum DPLL multiplier, divider values for OMAP3 */ +#define OMAP3_MAX_DPLL_MULT 2048 +#define OMAP3_MAX_DPLL_DIV 128 + /* * DPLL1 supplies clock to the MPU. * DPLL2 supplies clock to the IVA2. @@ -255,7 +259,7 @@ static const struct clksel_rate div16_dpll_rates[] = { /* DPLL1 */ /* MPU clock source */ /* Type: DPLL */ -static const struct dpll_data dpll1_dd = { +static struct dpll_data dpll1_dd = { .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK, .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK, @@ -269,6 +273,9 @@ static const struct dpll_data dpll1_dd = { .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK, .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .max_divider = OMAP3_MAX_DPLL_DIV, + .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll1_ck = { @@ -276,6 +283,7 @@ static struct clk dpll1_ck = { .parent = &sys_ck, .dpll_data = &dpll1_dd, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, + .round_rate = &omap2_dpll_round_rate, .recalc = &omap3_dpll_recalc, }; @@ -317,7 +325,7 @@ static struct clk dpll1_x2m2_ck = { /* IVA2 clock source */ /* Type: DPLL */ -static const struct dpll_data dpll2_dd = { +static struct dpll_data dpll2_dd = { .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK, .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK, @@ -331,7 +339,10 @@ static const struct dpll_data dpll2_dd = { .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL), .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK, .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), - .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT + .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .max_divider = OMAP3_MAX_DPLL_DIV, + .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll2_ck = { @@ -341,6 +352,7 @@ static struct clk dpll2_ck = { .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, .enable = &omap3_noncore_dpll_enable, .disable = &omap3_noncore_dpll_disable, + .round_rate = &omap2_dpll_round_rate, .recalc = &omap3_dpll_recalc, }; @@ -371,7 +383,7 @@ static struct clk dpll2_m2_ck = { * Source clock for all interfaces and for some device fclks * REVISIT: Also supports fast relock bypass - not included below */ -static const struct dpll_data dpll3_dd = { +static struct dpll_data dpll3_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK, .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK, @@ -382,6 +394,9 @@ static const struct dpll_data dpll3_dd = { .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT, .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .max_divider = OMAP3_MAX_DPLL_DIV, + .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll3_ck = { @@ -389,6 +404,7 @@ static struct clk dpll3_ck = { .parent = &sys_ck, .dpll_data = &dpll3_dd, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, + .round_rate = &omap2_dpll_round_rate, .recalc = &omap3_dpll_recalc, }; @@ -545,7 +561,7 @@ static struct clk emu_core_alwon_ck = { /* DPLL4 */ /* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ /* Type: DPLL */ -static const struct dpll_data dpll4_dd = { +static struct dpll_data dpll4_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, @@ -559,6 +575,9 @@ static const struct dpll_data dpll4_dd = { .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .max_divider = OMAP3_MAX_DPLL_DIV, + .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll4_ck = { @@ -568,6 +587,7 @@ static struct clk dpll4_ck = { .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, .enable = &omap3_noncore_dpll_enable, .disable = &omap3_noncore_dpll_disable, + .round_rate = &omap2_dpll_round_rate, .recalc = &omap3_dpll_recalc, }; @@ -843,7 +863,7 @@ static struct clk emu_per_alwon_ck = { /* Supplies 120MHz clock, USIM source clock */ /* Type: DPLL */ /* 3430ES2 only */ -static const struct dpll_data dpll5_dd = { +static struct dpll_data dpll5_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4), .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK, .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK, @@ -857,6 +877,9 @@ static const struct dpll_data dpll5_dd = { .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK, .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .max_divider = OMAP3_MAX_DPLL_DIV, + .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll5_ck = { @@ -866,6 +889,7 @@ static struct clk dpll5_ck = { .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES, .enable = &omap3_noncore_dpll_enable, .disable = &omap3_noncore_dpll_disable, + .round_rate = &omap2_dpll_round_rate, .recalc = &omap3_dpll_recalc, }; diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h index 22daa5d64d3..4c7b3514f71 100644 --- a/include/asm-arm/arch-omap/clock.h +++ b/include/asm-arm/arch-omap/clock.h @@ -33,6 +33,13 @@ struct dpll_data { void __iomem *mult_div1_reg; u32 mult_mask; u32 div1_mask; + u16 last_rounded_m; + u8 last_rounded_n; + unsigned long last_rounded_rate; + unsigned int rate_tolerance; + u16 max_multiplier; + u8 max_divider; + u32 max_tolerance; # if defined(CONFIG_ARCH_OMAP3) u8 modes; void __iomem *control_reg; @@ -71,7 +78,7 @@ struct clk { void __iomem *clksel_reg; u32 clksel_mask; const struct clksel *clksel; - const struct dpll_data *dpll_data; + struct dpll_data *dpll_data; #else __u8 rate_offset; __u8 src_offset; -- cgit v1.2.3-70-g09d2 From 5cca91479b8ac6a60b61bc56e72389c681387211 Mon Sep 17 00:00:00 2001 From: eric miao Date: Sun, 13 Apr 2008 21:46:34 +0100 Subject: [ARM] pxa: make zylonite use the generic PWM backlight driver Patch mostly by Eric Miao, minor edits by rmk. Signed-off-by: eric miao Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 2 ++ arch/arm/mach-pxa/zylonite.c | 26 +++++++++++++++++--------- arch/arm/mach-pxa/zylonite_pxa300.c | 4 +--- arch/arm/mach-pxa/zylonite_pxa320.c | 2 +- include/asm-arm/arch-pxa/zylonite.h | 1 - 5 files changed, 21 insertions(+), 14 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 9c01505b182..b7a3281c420 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -116,6 +116,7 @@ config MACH_COLIBRI config MACH_ZYLONITE bool "PXA3xx Development Platform" select PXA3xx + select HAVE_PWM config MACH_LITTLETON bool "PXA3xx Form Factor Platform (aka Littleton)" @@ -276,6 +277,7 @@ config PXA_SSP config PXA_PWM tristate + default BACKLIGHT_PWM help Enable support for PXA2xx/PXA3xx PWM controllers endif diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 4a0028087ea..b13bb938513 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -28,12 +29,12 @@ #include #include +#include "devices.h" #include "generic.h" #define MAX_SLOTS 3 struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS]; -int gpio_backlight; int gpio_eth_irq; int wm9713_irq; @@ -62,10 +63,20 @@ static struct platform_device smc91x_device = { }; #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) -static void zylonite_backlight_power(int on) -{ - gpio_set_value(gpio_backlight, on); -} +static struct platform_pwm_backlight_data zylonite_backlight_data = { + .pwm_id = 3, + .max_brightness = 100, + .dft_brightness = 100, + .pwm_period_ns = 10000, +}; + +static struct platform_device zylonite_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm1.dev, + .platform_data = &zylonite_backlight_data, + }, +}; static struct pxafb_mode_info toshiba_ltm035a776c_mode = { .pixclock = 110000, @@ -98,7 +109,6 @@ static struct pxafb_mode_info toshiba_ltm04c380k_mode = { static struct pxafb_mach_info zylonite_toshiba_lcd_info = { .num_modes = 1, .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, - .pxafb_backlight_power = zylonite_backlight_power, }; static struct pxafb_mode_info sharp_ls037_modes[] = { @@ -134,13 +144,11 @@ static struct pxafb_mach_info zylonite_sharp_lcd_info = { .modes = sharp_ls037_modes, .num_modes = 2, .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, - .pxafb_backlight_power = zylonite_backlight_power, }; static void __init zylonite_init_lcd(void) { - /* backlight GPIO: output, default on */ - gpio_direction_output(gpio_backlight, 1); + platform_device_register(&zylonite_backlight_device); if (lcd_id & 0x20) { set_pxa_fb_info(&zylonite_sharp_lcd_info); diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 324fb9daae2..6f7ae972b8d 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -50,6 +50,7 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO75_LCD_BIAS, GPIO76_LCD_VSYNC, GPIO127_LCD_CS_N, + GPIO20_PWM3_OUT, /* backlight */ /* BTUART */ GPIO111_UART2_RTS, @@ -200,9 +201,6 @@ void __init zylonite_pxa300_init(void) /* detect LCD panel */ zylonite_detect_lcd_panel(); - /* GPIO pin assignment */ - gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20); - /* MMC card detect & write protect for controller 0 */ zylonite_mmc_slot[0].gpio_cd = EXT_GPIO(0); zylonite_mmc_slot[0].gpio_wp = EXT_GPIO(2); diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 193d07903b0..2b4fc34919a 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -49,6 +49,7 @@ static mfp_cfg_t mfp_cfg[] __initdata = { GPIO15_2_LCD_LCLK, GPIO16_2_LCD_PCLK, GPIO17_2_LCD_BIAS, + GPIO14_PWM3_OUT, /* backlight */ /* FFUART */ GPIO41_UART1_RXD | MFP_LPM_EDGE_FALL, @@ -187,7 +188,6 @@ void __init zylonite_pxa320_init(void) zylonite_detect_lcd_panel(); /* GPIO pin assignment */ - gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14); gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9); /* MMC card detect & write protect for controller 0 */ diff --git a/include/asm-arm/arch-pxa/zylonite.h b/include/asm-arm/arch-pxa/zylonite.h index 4881b80f0f9..de577de8d18 100644 --- a/include/asm-arm/arch-pxa/zylonite.h +++ b/include/asm-arm/arch-pxa/zylonite.h @@ -15,7 +15,6 @@ struct platform_mmc_slot { extern struct platform_mmc_slot zylonite_mmc_slot[]; -extern int gpio_backlight; extern int gpio_eth_irq; extern int wm9713_irq; -- cgit v1.2.3-70-g09d2 From 50bbb05d60e1897abad92d42bf185314be36bd74 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Apr 2008 15:56:08 +0100 Subject: [ARM] rpc: deprecate __ioaddr() and __ioaddrc() helpers Now everything is converted to use MMIO accessors, these helpers are no longer required. Signed-off-by: Russell King --- include/asm-arm/arch-rpc/io.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h index b4da08d7a33..6bd2295c0e0 100644 --- a/include/asm-arm/arch-rpc/io.h +++ b/include/asm-arm/arch-rpc/io.h @@ -126,7 +126,7 @@ static inline unsigned sz __in##fnsuffix (unsigned int port) \ return (unsigned sz)value; \ } -static inline void __iomem *__ioaddr(unsigned int port) +static inline void __iomem *__deprecated __ioaddr(unsigned int port) { void __iomem *ret; if (__PORT_PCIO(port)) @@ -232,8 +232,7 @@ DECLARE_IO(int,l,"") result; \ }) -#define __ioaddrc(port) \ - ((__PORT_PCIO(port) ? PCIO_BASE : IO_BASE) + ((port) << 2)) +#define __ioaddrc(port) __ioaddr(port) #define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p)) #define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p)) -- cgit v1.2.3-70-g09d2 From 9ecba1f288d2cf87d1b6a9401d5ce17464eb776d Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Apr 2008 16:01:38 +0100 Subject: [ARM] rpc: ecard: remove deprecated ecard_address() and relatives ecard_address() is obsolete, and has been marked deprecated since at least 2.6.12-rc2. All in-tree users have been updated to use the new approach, so it's time to remove this. Signed-off-by: Russell King --- arch/arm/kernel/ecard.c | 13 ++++++------- arch/arm/kernel/ecard.h | 13 +++++++++++++ include/asm-arm/ecard.h | 35 ----------------------------------- 3 files changed, 19 insertions(+), 42 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index a53c0aba5c1..8bfd299bfe7 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -680,7 +680,7 @@ static int __init ecard_probeirqhw(void) #define IO_EC_MEMC8_BASE 0 #endif -unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) +static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) { unsigned long address = 0; int slot = ec->slot_no; @@ -1002,7 +1002,7 @@ ecard_probe(int slot, card_type_t type) } rc = -ENODEV; - if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0) + if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0) goto nodev; cid.r_zero = 1; @@ -1141,10 +1141,10 @@ static int ecard_drv_probe(struct device *dev) id = ecard_match_device(drv->id_table, ec); - ecard_claim(ec); + ec->claimed = 1; ret = drv->probe(ec, id); if (ret) - ecard_release(ec); + ec->claimed = 0; return ret; } @@ -1154,7 +1154,7 @@ static int ecard_drv_remove(struct device *dev) struct ecard_driver *drv = ECARD_DRV(dev->driver); drv->remove(ec); - ecard_release(ec); + ec->claimed = 0; /* * Restore the default operations. We ensure that the @@ -1182,7 +1182,7 @@ static void ecard_drv_shutdown(struct device *dev) if (dev->driver) { if (drv->shutdown) drv->shutdown(ec); - ecard_release(ec); + ec->claimed = 0; } /* @@ -1239,7 +1239,6 @@ static int ecard_bus_init(void) postcore_initcall(ecard_bus_init); EXPORT_SYMBOL(ecard_readchunk); -EXPORT_SYMBOL(__ecard_address); EXPORT_SYMBOL(ecard_register_driver); EXPORT_SYMBOL(ecard_remove_driver); EXPORT_SYMBOL(ecard_bus_type); diff --git a/arch/arm/kernel/ecard.h b/arch/arm/kernel/ecard.h index d7c2dacf935..4642d436be2 100644 --- a/arch/arm/kernel/ecard.h +++ b/arch/arm/kernel/ecard.h @@ -54,3 +54,16 @@ struct ex_chunk_dir { #define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16)) #define c_start(x) ((x)->r_start) }; + +typedef enum ecard_type { /* Cards address space */ + ECARD_IOC, + ECARD_MEMC, + ECARD_EASI +} card_type_t; + +typedef enum { /* Speed for ECARD_IOC space */ + ECARD_SLOW = 0, + ECARD_MEDIUM = 1, + ECARD_FAST = 2, + ECARD_SYNC = 3 +} card_speed_t; diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h index 684fe064523..5e22881a630 100644 --- a/include/asm-arm/ecard.h +++ b/include/asm-arm/ecard.h @@ -85,19 +85,6 @@ #define MAX_ECARDS 9 -typedef enum { /* Cards address space */ - ECARD_IOC, - ECARD_MEMC, - ECARD_EASI -} card_type_t; - -typedef enum { /* Speed for ECARD_IOC space */ - ECARD_SLOW = 0, - ECARD_MEDIUM = 1, - ECARD_FAST = 2, - ECARD_SYNC = 3 -} card_speed_t; - struct ecard_id { /* Card ID structure */ unsigned short manufacturer; unsigned short product; @@ -189,16 +176,6 @@ struct in_chunk_dir { } d; }; -/* - * ecard_claim: claim an expansion card entry - */ -#define ecard_claim(ec) ((ec)->claimed = 1) - -/* - * ecard_release: release an expansion card entry - */ -#define ecard_release(ec) ((ec)->claimed = 0) - /* * Read a chunk from an expansion card * cd : where to put read data @@ -208,18 +185,6 @@ struct in_chunk_dir { */ extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num); -/* - * Obtain the address of a card. This returns the "old style" address - * and should no longer be used. - */ -static inline unsigned int __deprecated -ecard_address(struct expansion_card *ec, card_type_t type, card_speed_t speed) -{ - extern unsigned int __ecard_address(struct expansion_card *, - card_type_t, card_speed_t); - return __ecard_address(ec, type, speed); -} - /* * Request and release ecard resources */ -- cgit v1.2.3-70-g09d2 From 3c093f9f182eef6a8dc535f2c62b36a0320d0db1 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Mon, 9 Jun 2008 16:24:10 -0700 Subject: [ARM] fix header guards Acked-by: Dan Williams Signed-off-by: Vegard Nossum Signed-off-by: Andrew Morton Signed-off-by: Russell King --- include/asm-arm/arch-iop13xx/dma.h | 2 +- include/asm-arm/arch-msm/irqs.h | 1 + include/asm-arm/arch-msm/timex.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-iop13xx/dma.h b/include/asm-arm/arch-iop13xx/dma.h index 2e15da53ff7..d79846fbb39 100644 --- a/include/asm-arm/arch-iop13xx/dma.h +++ b/include/asm-arm/arch-iop13xx/dma.h @@ -1,3 +1,3 @@ #ifndef _IOP13XX_DMA_H -#define _IOP13XX_DMA_H_ +#define _IOP13XX_DMA_H #endif diff --git a/include/asm-arm/arch-msm/irqs.h b/include/asm-arm/arch-msm/irqs.h index 565430cfaa7..e62a108b185 100644 --- a/include/asm-arm/arch-msm/irqs.h +++ b/include/asm-arm/arch-msm/irqs.h @@ -15,6 +15,7 @@ */ #ifndef __ASM_ARCH_MSM_IRQS_H +#define __ASM_ARCH_MSM_IRQS_H /* MSM ARM11 Interrupt Numbers */ /* See 80-VE113-1 A, pp219-221 */ diff --git a/include/asm-arm/arch-msm/timex.h b/include/asm-arm/arch-msm/timex.h index 154b23fb359..8724487ab4c 100644 --- a/include/asm-arm/arch-msm/timex.h +++ b/include/asm-arm/arch-msm/timex.h @@ -14,6 +14,7 @@ */ #ifndef __ASM_ARCH_MSM_TIMEX_H +#define __ASM_ARCH_MSM_TIMEX_H #define CLOCK_TICK_RATE 1000000 -- cgit v1.2.3-70-g09d2 From 826cbdaff29764bb6928c715c6a025e49469dda9 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 13 Jun 2008 10:28:36 +0100 Subject: [ARM] 5092/1: Fix the I-cache invalidation on ARMv6 and later CPUs This patch adds the I-cache invalidation in update_mmu_cache if the corresponding vma is marked as executable. It also invalidates the I-cache if a thread migrates to a CPU it never ran on. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/fault-armv.c | 4 ++++ arch/arm/mm/flush.c | 2 ++ include/asm-arm/cacheflush.h | 7 +++++++ include/asm-arm/mmu_context.h | 5 +++++ 4 files changed, 18 insertions(+) (limited to 'include/asm-arm') diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index 44558d5f931..fbfa2605844 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -144,13 +144,17 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) page = pfn_to_page(pfn); mapping = page_mapping(page); if (mapping) { +#ifndef CONFIG_SMP int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); if (dirty) __flush_dcache_page(mapping, page); +#endif if (cache_is_vivt()) make_coherent(mapping, vma, addr, pfn); + else if (vma->vm_flags & VM_EXEC) + __flush_icache_all(); } } diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 9df507d36e0..029ee65fda2 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -199,6 +199,8 @@ void flush_dcache_page(struct page *page) __flush_dcache_page(mapping, page); if (mapping && cache_is_vivt()) __flush_dcache_aliases(mapping, page); + else if (mapping) + __flush_icache_all(); } } EXPORT_SYMBOL(flush_dcache_page); diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 759a97b56ee..559fb4af1f6 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -410,6 +410,13 @@ extern void flush_dcache_page(struct page *); extern void __flush_dcache_page(struct address_space *mapping, struct page *page); +static inline void __flush_icache_all(void) +{ + asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" + : + : "r" (0)); +} + #define ARCH_HAS_FLUSH_ANON_PAGE static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h index 6913d02ca5d..91b9dfdfed5 100644 --- a/include/asm-arm/mmu_context.h +++ b/include/asm-arm/mmu_context.h @@ -97,6 +97,11 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, #ifdef CONFIG_MMU unsigned int cpu = smp_processor_id(); +#ifdef CONFIG_SMP + /* check for possible thread migration */ + if (!cpus_empty(next->cpu_vm_mask) && !cpu_isset(cpu, next->cpu_vm_mask)) + __flush_icache_all(); +#endif if (!cpu_test_and_set(cpu, next->cpu_vm_mask) || prev != next) { check_context(next); cpu_switch_mm(next->pgd, next); -- cgit v1.2.3-70-g09d2 From f7def13ed0775ee506c62a8612a124dce1776ac2 Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Wed, 25 Jun 2008 13:25:13 +0100 Subject: [ARM] 5122/1: imx_dma_request_by_prio simpilfication imx_dma_request_by_prio can return channel number by itself. No need to supply variable address through parameters. Also converted all drivers using this function. Signed-off-by: Paulius Zaleckas Acked-by: Sascha Hauer Signed-off-by: Russell King --- arch/arm/mach-imx/dma.c | 13 ++++--------- drivers/mmc/host/imxmmc.c | 4 ++-- drivers/spi/spi_imx.c | 16 ++++++++-------- include/asm-arm/arch-imx/imx-dma.h | 2 +- 4 files changed, 15 insertions(+), 20 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c index a59ff2987cb..ee1c6f06ff6 100644 --- a/arch/arm/mach-imx/dma.c +++ b/arch/arm/mach-imx/dma.c @@ -410,7 +410,6 @@ void imx_dma_free(imx_dmach_t dma_ch) /** * imx_dma_request_by_prio - find and request some of free channels best suiting requested priority - * @dma_ch: i.MX DMA channel number * @name: the driver/caller own non-%NULL identification * @prio: one of the hardware distinguished priority level: * %DMA_PRIO_HIGH, %DMA_PRIO_MEDIUM, %DMA_PRIO_LOW @@ -420,11 +419,9 @@ void imx_dma_free(imx_dmach_t dma_ch) * in the higher and then even lower priority groups. * * Return value: If there is no free channel to allocate, -%ENODEV is returned. - * Zero value indicates successful channel allocation. + * On successful allocation channel is returned. */ -int -imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name, - imx_dma_prio prio) +imx_dmach_t imx_dma_request_by_prio(const char *name, imx_dma_prio prio) { int i; int best; @@ -444,15 +441,13 @@ imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name, for (i = best; i < IMX_DMA_CHANNELS; i++) { if (!imx_dma_request(i, name)) { - *pdma_ch = i; - return 0; + return i; } } for (i = best - 1; i >= 0; i--) { if (!imx_dma_request(i, name)) { - *pdma_ch = i; - return 0; + return i; } } diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 95f33e87a99..c4349c746cb 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c @@ -1017,8 +1017,8 @@ static int imxmci_probe(struct platform_device *pdev) host->imask = IMXMCI_INT_MASK_DEFAULT; MMC_INT_MASK = host->imask; - - if(imx_dma_request_by_prio(&host->dma, DRIVER_NAME, DMA_PRIO_LOW)<0){ + host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW); + if(host->dma < 0) { dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n"); ret = -EBUSY; goto out; diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index c730d05bfeb..547e3029827 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -1526,24 +1526,24 @@ static int __init spi_imx_probe(struct platform_device *pdev) drv_data->rx_channel = -1; if (platform_info->enable_dma) { /* Get rx DMA channel */ - status = imx_dma_request_by_prio(&drv_data->rx_channel, - "spi_imx_rx", DMA_PRIO_HIGH); - if (status < 0) { + drv_data->rx_channel = imx_dma_request_by_prio("spi_imx_rx", + DMA_PRIO_HIGH); + if (drv_data->rx_channel < 0) { dev_err(dev, "probe - problem (%d) requesting rx channel\n", - status); + drv_data->rx_channel); goto err_no_rxdma; } else imx_dma_setup_handlers(drv_data->rx_channel, NULL, dma_err_handler, drv_data); /* Get tx DMA channel */ - status = imx_dma_request_by_prio(&drv_data->tx_channel, - "spi_imx_tx", DMA_PRIO_MEDIUM); - if (status < 0) { + drv_data->tx_channel = imx_dma_request_by_prio("spi_imx_tx", + DMA_PRIO_MEDIUM); + if (drv_data->tx_channel < 0) { dev_err(dev, "probe - problem (%d) requesting tx channel\n", - status); + drv_data->tx_channel); imx_dma_free(drv_data->rx_channel); goto err_no_txdma; } else diff --git a/include/asm-arm/arch-imx/imx-dma.h b/include/asm-arm/arch-imx/imx-dma.h index 5b1066da4e1..44d89c35539 100644 --- a/include/asm-arm/arch-imx/imx-dma.h +++ b/include/asm-arm/arch-imx/imx-dma.h @@ -88,7 +88,7 @@ int imx_dma_request(imx_dmach_t dma_ch, const char *name); void imx_dma_free(imx_dmach_t dma_ch); -int imx_dma_request_by_prio(imx_dmach_t *pdma_ch, const char *name, imx_dma_prio prio); +imx_dmach_t imx_dma_request_by_prio(const char *name, imx_dma_prio prio); #endif /* _ASM_ARCH_IMX_DMA_H */ -- cgit v1.2.3-70-g09d2 From f348a2a2817e9d24b1edd4befc9659ec83501ca5 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 3 Jul 2008 11:24:25 +0100 Subject: [ARM] S3C24XX: Add gpiolib support Add support for gpilib on all S3C24XX platforms. Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/Kconfig | 1 + arch/arm/plat-s3c24xx/Makefile | 1 + arch/arm/plat-s3c24xx/gpiolib.c | 259 ++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-s3c2410/gpio.h | 74 ++--------- 4 files changed, 273 insertions(+), 62 deletions(-) create mode 100644 arch/arm/plat-s3c24xx/gpiolib.c (limited to 'include/asm-arm') diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index b66fb3c4e22..1521f1ce3b2 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -9,6 +9,7 @@ config PLAT_S3C24XX depends on ARCH_S3C2410 default y if ARCH_S3C2410 select NO_IOPORT + select HAVE_GPIO_LIB help Base platform code for any Samsung S3C24XX device diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 131d20237dd..b91e6258568 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -16,6 +16,7 @@ obj-y += cpu.o obj-y += irq.o obj-y += devs.o obj-y += gpio.o +obj-y += gpiolib.o obj-y += time.o obj-y += clock.o diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c new file mode 100644 index 00000000000..825d8d0c5ca --- /dev/null +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -0,0 +1,259 @@ +/* linux/arch/arm/plat-s3c24xx/gpiolib.c + * + * Copyright (c) 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C24XX GPIOlib support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +struct s3c24xx_gpio_chip { + struct gpio_chip chip; + void __iomem *base; +}; + +static inline struct s3c24xx_gpio_chip *to_s3c_chip(struct gpio_chip *gpc) +{ + return container_of(gpc, struct s3c24xx_gpio_chip, chip); +} + +/* these routines are exported for use by other parts of the platform + * and system support, but are not intended to be used directly by the + * drivers themsevles. + */ + +int s3c24xx_gpiolib_input(struct gpio_chip *chip, unsigned offset) +{ + struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); + void __iomem *base = ourchip->base; + unsigned long flags; + unsigned long con; + + local_irq_save(flags); + + con = __raw_readl(base + 0x00); + con &= ~(3 << (offset * 2)); + con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2); + + __raw_writel(con, base + 0x00); + + local_irq_restore(flags); + return 0; +} + +int s3c24xx_gpiolib_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); + void __iomem *base = ourchip->base; + unsigned long flags; + unsigned long dat; + unsigned long con; + + local_irq_save(flags); + + dat = __raw_readl(base + 0x04); + dat &= ~(1 << offset); + if (value) + dat |= 1 << offset; + __raw_writel(dat, base + 0x04); + + con = __raw_readl(base + 0x00); + con &= ~(3 << (offset * 2)); + con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2); + + __raw_writel(con, base + 0x00); + __raw_writel(dat, base + 0x04); + + local_irq_restore(flags); + return 0; +} + +void s3c24xx_gpiolib_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); + void __iomem *base = ourchip->base; + unsigned long flags; + unsigned long dat; + + local_irq_save(flags); + + dat = __raw_readl(base + 0x04); + dat &= ~(1 << offset); + if (value) + dat |= 1 << offset; + __raw_writel(dat, base + 0x04); + + local_irq_restore(flags); +} + +int s3c24xx_gpiolib_get(struct gpio_chip *chip, unsigned offset) +{ + struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); + unsigned long val; + + val = __raw_readl(ourchip->base + 0x04); + val >>= offset; + val &= 1; + + return val; +} + +static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) +{ + return -EINVAL; +} + +static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); + void __iomem *base = ourchip->base; + unsigned long flags; + unsigned long dat; + unsigned long con; + + local_irq_save(flags); + + con = __raw_readl(base + 0x00); + dat = __raw_readl(base + 0x04); + + dat &= ~(1 << offset); + if (value) + dat |= 1 << offset; + + __raw_writel(dat, base + 0x04); + + con &= ~(1 << offset); + + __raw_writel(con, base + 0x00); + __raw_writel(dat, base + 0x04); + + local_irq_restore(flags); + return 0; +} + + +struct s3c24xx_gpio_chip gpios[] = { + [0] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPA0), + .chip = { + .base = S3C2410_GPA0, + .owner = THIS_MODULE, + .label = "GPIOA", + .ngpio = 24, + .direction_input = s3c24xx_gpiolib_banka_input, + .direction_output = s3c24xx_gpiolib_banka_output, + .set = s3c24xx_gpiolib_set, + .get = s3c24xx_gpiolib_get, + }, + }, + [1] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPB0), + .chip = { + .base = S3C2410_GPB0, + .owner = THIS_MODULE, + .label = "GPIOB", + .ngpio = 16, + .direction_input = s3c24xx_gpiolib_input, + .direction_output = s3c24xx_gpiolib_output, + .set = s3c24xx_gpiolib_set, + .get = s3c24xx_gpiolib_get, + }, + }, + [2] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPC0), + .chip = { + .base = S3C2410_GPC0, + .owner = THIS_MODULE, + .label = "GPIOC", + .ngpio = 16, + .direction_input = s3c24xx_gpiolib_input, + .direction_output = s3c24xx_gpiolib_output, + .set = s3c24xx_gpiolib_set, + .get = s3c24xx_gpiolib_get, + }, + }, + [3] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPD0), + .chip = { + .base = S3C2410_GPD0, + .owner = THIS_MODULE, + .label = "GPIOD", + .ngpio = 16, + .direction_input = s3c24xx_gpiolib_input, + .direction_output = s3c24xx_gpiolib_output, + .set = s3c24xx_gpiolib_set, + .get = s3c24xx_gpiolib_get, + }, + }, + [4] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPE0), + .chip = { + .base = S3C2410_GPE0, + .label = "GPIOE", + .owner = THIS_MODULE, + .ngpio = 16, + .direction_input = s3c24xx_gpiolib_input, + .direction_output = s3c24xx_gpiolib_output, + .set = s3c24xx_gpiolib_set, + .get = s3c24xx_gpiolib_get, + }, + }, + [5] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPF0), + .chip = { + .base = S3C2410_GPF0, + .owner = THIS_MODULE, + .label = "GPIOF", + .ngpio = 8, + .direction_input = s3c24xx_gpiolib_input, + .direction_output = s3c24xx_gpiolib_output, + .set = s3c24xx_gpiolib_set, + .get = s3c24xx_gpiolib_get, + }, + }, + [6] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPG0), + .chip = { + .base = S3C2410_GPG0, + .owner = THIS_MODULE, + .label = "GPIOG", + .ngpio = 10, + .direction_input = s3c24xx_gpiolib_input, + .direction_output = s3c24xx_gpiolib_output, + .set = s3c24xx_gpiolib_set, + .get = s3c24xx_gpiolib_get, + }, + }, +}; + +static __init int s3c24xx_gpiolib_init(void) +{ + struct s3c24xx_gpio_chip *chip = gpios; + int gpn; + + for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++) + gpiochip_add(&chip->chip); + + return 0; +} + +arch_initcall(s3c24xx_gpiolib_init); diff --git a/include/asm-arm/arch-s3c2410/gpio.h b/include/asm-arm/arch-s3c2410/gpio.h index 7583895fd33..18e10d2c35e 100644 --- a/include/asm-arm/arch-s3c2410/gpio.h +++ b/include/asm-arm/arch-s3c2410/gpio.h @@ -1,68 +1,18 @@ -/* - * linux/include/asm-arm/arch-s3c2410/gpio.h +/* linux/include/asm-arm/arch-s3c2410/gpio.h * - * S3C2410 GPIO wrappers for arch-neutral GPIO calls + * Copyright (c) 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks * - * Written by Philipp Zabel + * S3C2410 - GPIO lib support * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASM_ARCH_S3C2410_GPIO_H -#define __ASM_ARCH_S3C2410_GPIO_H - -#include -#include -#include - -static inline int gpio_request(unsigned gpio, const char *label) -{ - return 0; -} - -static inline void gpio_free(unsigned gpio) -{ - return; -} - -static inline int gpio_direction_input(unsigned gpio) -{ - s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_INPUT); - return 0; -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT); - /* REVISIT can we write the value first, to avoid glitching? */ - s3c2410_gpio_setpin(gpio, value); - return 0; -} - -#define gpio_get_value(gpio) s3c2410_gpio_getpin(gpio) -#define gpio_set_value(gpio,value) s3c2410_gpio_setpin(gpio, value) - -#include /* cansleep wrappers */ - -#ifdef CONFIG_CPU_S3C2400 -#define gpio_to_irq(gpio) s3c2400_gpio_getirq(gpio) -#else -#define gpio_to_irq(gpio) s3c2410_gpio_getirq(gpio) -#endif + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ -/* FIXME implement irq_to_gpio() */ +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep -#endif +#include -- cgit v1.2.3-70-g09d2 From b4b68f8cfaf583945019e41674cfa858c83316c3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 3 Jul 2008 11:24:26 +0100 Subject: [ARM] S3C24XX: Add PWM timer MUX defines Add timer defines for the MUX settings for each of the PWM timers to add to the per-timer defines already in the file. Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c/regs-timer.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/asm-arm') diff --git a/include/asm-arm/plat-s3c/regs-timer.h b/include/asm-arm/plat-s3c/regs-timer.h index 8b0d594397b..b5bc692f348 100644 --- a/include/asm-arm/plat-s3c/regs-timer.h +++ b/include/asm-arm/plat-s3c/regs-timer.h @@ -65,6 +65,15 @@ #define S3C2410_TCFG1_MUX0_TCLK0 (4<<0) #define S3C2410_TCFG1_MUX0_MASK (15<<0) +#define S3C2410_TCFG1_MUX_DIV2 (0<<0) +#define S3C2410_TCFG1_MUX_DIV4 (1<<0) +#define S3C2410_TCFG1_MUX_DIV8 (2<<0) +#define S3C2410_TCFG1_MUX_DIV16 (3<<0) +#define S3C2410_TCFG1_MUX_TCLK (4<<0) +#define S3C2410_TCFG1_MUX_MASK (15<<0) + +#define S3C2410_TCFG1_SHIFT(x) ((x) * 4) + /* for each timer, we have an count buffer, an compare buffer and * an observation buffer */ -- cgit v1.2.3-70-g09d2 From d5c52922b618aa6ddd6b5ebebc8d0a5ec9a20f10 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Thu, 3 Jul 2008 11:24:45 +0100 Subject: [ARM] S3C2412: Correct parents for EREFCLK and UREFCLK For s3c2412, set parent for clk_erefclk and clk_urefclk. This allow for example to use xtal or extclk for i2s clock. Signed-off-by: Ben Dooks Signed-off-by: Matthieu Castet --- arch/arm/mach-s3c2412/clock.c | 13 +++++++++++-- include/asm-arm/arch-s3c2410/regs-clock.h | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c index 2697a65ba72..1157b5a1626 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c2412/clock.c @@ -631,6 +631,17 @@ static struct clk_init clks_src[] __initdata = { .bit = S3C2412_CLKSRC_USBCLK_HCLK, .src_0 = &clk_usysclk, .src_1 = &clk_h, + /* here we assume OM[4] select xtal */ + }, { + .clk = &clk_erefclk, + .bit = S3C2412_CLKSRC_EREFCLK_EXTCLK, + .src_0 = &clk_xtal, + .src_1 = &clk_ext, + }, { + .clk = &clk_urefclk, + .bit = S3C2412_CLKSRC_UREFCLK_EXTCLK, + .src_0 = &clk_xtal, + .src_1 = &clk_ext, }, }; @@ -666,8 +677,6 @@ static void __init s3c2412_clk_initparents(void) static struct clk *clks[] __initdata = { &clk_ext, &clk_usb_bus, - &clk_erefclk, - &clk_urefclk, &clk_mrefclk, &clk_armclk, }; diff --git a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h index ecae9e7f5e4..37661358b42 100644 --- a/include/asm-arm/arch-s3c2410/regs-clock.h +++ b/include/asm-arm/arch-s3c2410/regs-clock.h @@ -189,6 +189,8 @@ s3c2410_get_pll(unsigned int pllval, unsigned int baseclk) #define S3C2412_CLKSRC_I2SCLK_MPLL (1<<9) #define S3C2412_CLKSRC_USBCLK_HCLK (1<<10) #define S3C2412_CLKSRC_CAMCLK_HCLK (1<<11) +#define S3C2412_CLKSRC_UREFCLK_EXTCLK (1<<12) +#define S3C2412_CLKSRC_EREFCLK_EXTCLK (1<<14) #endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */ -- cgit v1.2.3-70-g09d2 From 6fc601e37bbb4045ee0afefc76b64284ea800c89 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 1 Jul 2008 13:17:24 +0100 Subject: [ARM] S3C24XX: PWM API support. Add support for PWM in the S3C24XX series of SoC via the PWM API. Signed-off-by: Ben Dooks --- arch/arm/plat-s3c24xx/Kconfig | 7 + arch/arm/plat-s3c24xx/Makefile | 1 + arch/arm/plat-s3c24xx/devs.c | 100 --------- arch/arm/plat-s3c24xx/pwm.c | 402 ++++++++++++++++++++++++++++++++++++ include/asm-arm/plat-s3c24xx/devs.h | 7 +- 5 files changed, 412 insertions(+), 105 deletions(-) create mode 100644 arch/arm/plat-s3c24xx/pwm.c (limited to 'include/asm-arm') diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 1521f1ce3b2..5e28c217b8c 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -21,6 +21,13 @@ config CPU_S3C244X help Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems. +config S3C24XX_PWM + bool "PWM device support" + select HAVE_PWM + help + Support for exporting the PWM timer blocks via the pwm device + system. + config PM_SIMTEC bool help diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index c925d577fef..d82767b2b83 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -29,5 +29,6 @@ obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += sleep.o +obj-$(CONFIG_HAVE_PWM) += pwm.o obj-$(CONFIG_S3C2410_DMA) += dma.o obj-$(CONFIG_MACH_SMDK) += common-smdk.o diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index e546e933b3f..eea3b32ff79 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -495,106 +495,6 @@ struct platform_device s3c_device_spi1 = { EXPORT_SYMBOL(s3c_device_spi1); -/* pwm timer blocks */ - -static struct resource s3c_timer0_resource[] = { - [0] = { - .start = S3C24XX_PA_TIMER + 0x0C, - .end = S3C24XX_PA_TIMER + 0x0C + 0xB, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TIMER0, - .end = IRQ_TIMER0, - .flags = IORESOURCE_IRQ, - } - -}; - -struct platform_device s3c_device_timer0 = { - .name = "s3c2410-timer", - .id = 0, - .num_resources = ARRAY_SIZE(s3c_timer0_resource), - .resource = s3c_timer0_resource, -}; - -EXPORT_SYMBOL(s3c_device_timer0); - -/* timer 1 */ - -static struct resource s3c_timer1_resource[] = { - [0] = { - .start = S3C24XX_PA_TIMER + 0x18, - .end = S3C24XX_PA_TIMER + 0x23, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TIMER1, - .end = IRQ_TIMER1, - .flags = IORESOURCE_IRQ, - } - -}; - -struct platform_device s3c_device_timer1 = { - .name = "s3c2410-timer", - .id = 1, - .num_resources = ARRAY_SIZE(s3c_timer1_resource), - .resource = s3c_timer1_resource, -}; - -EXPORT_SYMBOL(s3c_device_timer1); - -/* timer 2 */ - -static struct resource s3c_timer2_resource[] = { - [0] = { - .start = S3C24XX_PA_TIMER + 0x24, - .end = S3C24XX_PA_TIMER + 0x2F, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TIMER2, - .end = IRQ_TIMER2, - .flags = IORESOURCE_IRQ, - } - -}; - -struct platform_device s3c_device_timer2 = { - .name = "s3c2410-timer", - .id = 2, - .num_resources = ARRAY_SIZE(s3c_timer2_resource), - .resource = s3c_timer2_resource, -}; - -EXPORT_SYMBOL(s3c_device_timer2); - -/* timer 3 */ - -static struct resource s3c_timer3_resource[] = { - [0] = { - .start = S3C24XX_PA_TIMER + 0x30, - .end = S3C24XX_PA_TIMER + 0x3B, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_TIMER3, - .end = IRQ_TIMER3, - .flags = IORESOURCE_IRQ, - } - -}; - -struct platform_device s3c_device_timer3 = { - .name = "s3c2410-timer", - .id = 3, - .num_resources = ARRAY_SIZE(s3c_timer3_resource), - .resource = s3c_timer3_resource, -}; - -EXPORT_SYMBOL(s3c_device_timer3); - #ifdef CONFIG_CPU_S3C2440 /* Camif Controller */ diff --git a/arch/arm/plat-s3c24xx/pwm.c b/arch/arm/plat-s3c24xx/pwm.c new file mode 100644 index 00000000000..18c4bdc49a0 --- /dev/null +++ b/arch/arm/plat-s3c24xx/pwm.c @@ -0,0 +1,402 @@ +/* arch/arm/plat-s3c24xx/pwm.c + * + * Copyright (c) 2007 Ben Dooks + * Copyright (c) 2008 Simtec Electronics + * Ben Dooks , + * + * S3C24XX PWM device core + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +struct pwm_device { + struct list_head list; + struct platform_device *pdev; + + struct clk *clk_div; + struct clk *clk; + const char *label; + + unsigned int period_ns; + unsigned int duty_ns; + + unsigned char tcon_base; + unsigned char running; + unsigned char use_count; + unsigned char pwm_id; +}; + +#define pwm_dbg(_pwm, msg...) dev_info(&(_pwm)->pdev->dev, msg) + +static struct clk *clk_scaler[2]; + +/* Standard setup for a timer block. */ + +#define TIMER_RESOURCE_SIZE (1) + +#define TIMER_RESOURCE(_tmr, _irq) \ + (struct resource [TIMER_RESOURCE_SIZE]) { \ + [0] = { \ + .start = _irq, \ + .end = _irq, \ + .flags = IORESOURCE_IRQ \ + } \ + } + +#define DEFINE_TIMER(_tmr_no, _irq) \ + .name = "s3c24xx-pwm", \ + .id = _tmr_no, \ + .num_resources = TIMER_RESOURCE_SIZE, \ + .resource = TIMER_RESOURCE(_tmr_no, _irq), \ + +/* since we already have an static mapping for the timer, we do not + * bother setting any IO resource for the base. + */ + +struct platform_device s3c_device_timer[] = { + [0] = { DEFINE_TIMER(0, IRQ_TIMER0) }, + [1] = { DEFINE_TIMER(1, IRQ_TIMER1) }, + [2] = { DEFINE_TIMER(2, IRQ_TIMER2) }, + [3] = { DEFINE_TIMER(3, IRQ_TIMER3) }, + [4] = { DEFINE_TIMER(4, IRQ_TIMER4) }, +}; + +static inline int pwm_is_tdiv(struct pwm_device *pwm) +{ + return clk_get_parent(pwm->clk) == pwm->clk_div; +} + +static DEFINE_MUTEX(pwm_lock); +static LIST_HEAD(pwm_list); + +struct pwm_device *pwm_request(int pwm_id, const char *label) +{ + struct pwm_device *pwm; + int found = 0; + + mutex_lock(&pwm_lock); + + list_for_each_entry(pwm, &pwm_list, list) { + if (pwm->pwm_id == pwm_id) { + found = 1; + break; + } + } + + if (found) { + if (pwm->use_count == 0) { + pwm->use_count = 1; + pwm->label = label; + } else + pwm = ERR_PTR(-EBUSY); + } else + pwm = ERR_PTR(-ENOENT); + + mutex_unlock(&pwm_lock); + return pwm; +} + +EXPORT_SYMBOL(pwm_request); + + +void pwm_free(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + + if (pwm->use_count) { + pwm->use_count--; + pwm->label = NULL; + } else + printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id); + + mutex_unlock(&pwm_lock); +} + +EXPORT_SYMBOL(pwm_free); + +#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0)) +#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2)) +#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3)) +#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1)) + +int pwm_enable(struct pwm_device *pwm) +{ + unsigned long flags; + unsigned long tcon; + + local_irq_save(flags); + + tcon = __raw_readl(S3C2410_TCON); + tcon |= pwm_tcon_start(pwm); + __raw_writel(tcon, S3C2410_TCON); + + local_irq_restore(flags); + + pwm->running = 1; + return 0; +} + +EXPORT_SYMBOL(pwm_enable); + +void pwm_disable(struct pwm_device *pwm) +{ + unsigned long flags; + unsigned long tcon; + + local_irq_save(flags); + + tcon = __raw_readl(S3C2410_TCON); + tcon &= ~pwm_tcon_start(pwm); + __raw_writel(tcon, S3C2410_TCON); + + local_irq_restore(flags); + + pwm->running = 0; +} + +EXPORT_SYMBOL(pwm_disable); + +unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq) +{ + unsigned long tin_parent_rate; + unsigned int div; + + tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div)); + pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate); + + for (div = 2; div <= 16; div *= 2) { + if ((tin_parent_rate / (div << 16)) < freq) + return tin_parent_rate / div; + } + + return tin_parent_rate / 16; +} + +#define NS_IN_HZ (1000000000UL) + +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) +{ + unsigned long tin_rate; + unsigned long tin_ns; + unsigned long period; + unsigned long flags; + unsigned long tcon; + unsigned long tcnt; + long tcmp; + + /* We currently avoid using 64bit arithmetic by using the + * fact that anything faster than 1Hz is easily representable + * by 32bits. */ + + if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ) + return -ERANGE; + + if (duty_ns > period_ns) + return -EINVAL; + + if (period_ns == pwm->period_ns && + duty_ns == pwm->duty_ns) + return 0; + + /* The TCMP and TCNT can be read without a lock, they're not + * shared between the timers. */ + + tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id)); + tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id)); + + period = NS_IN_HZ / period_ns; + + pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n", + duty_ns, period_ns, period); + + /* Check to see if we are changing the clock rate of the PWM */ + + if (pwm->period_ns != period_ns) { + if (pwm_is_tdiv(pwm)) { + tin_rate = pwm_calc_tin(pwm, period); + clk_set_rate(pwm->clk_div, tin_rate); + } else + tin_rate = clk_get_rate(pwm->clk); + + pwm->period_ns = period_ns; + + pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate); + + tin_ns = NS_IN_HZ / tin_rate; + tcnt = period_ns / tin_ns; + } else + tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk); + + /* Note, counters count down */ + + tcmp = duty_ns / tin_ns; + tcmp = tcnt - tcmp; + + pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt); + + if (tcmp < 0) + tcmp = 0; + + /* Update the PWM register block. */ + + local_irq_save(flags); + + __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id)); + __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id)); + + tcon = __raw_readl(S3C2410_TCON); + tcon |= pwm_tcon_manulupdate(pwm); + tcon |= pwm_tcon_autoreload(pwm); + __raw_writel(tcon, S3C2410_TCON); + + tcon &= ~pwm_tcon_manulupdate(pwm); + __raw_writel(tcon, S3C2410_TCON); + + local_irq_restore(flags); + + return 0; +} + +EXPORT_SYMBOL(pwm_config); + +static int pwm_register(struct pwm_device *pwm) +{ + pwm->duty_ns = -1; + pwm->period_ns = -1; + + mutex_lock(&pwm_lock); + list_add_tail(&pwm->list, &pwm_list); + mutex_unlock(&pwm_lock); + + return 0; +} + +static int s3c_pwm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct pwm_device *pwm; + unsigned long flags; + unsigned long tcon; + unsigned int id = pdev->id; + int ret; + + if (id == 4) { + dev_err(dev, "TIMER4 is currently not supported\n"); + return -ENXIO; + } + + pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); + if (pwm == NULL) { + dev_err(dev, "failed to allocate pwm_device\n"); + return -ENOMEM; + } + + pwm->pdev = pdev; + pwm->pwm_id = id; + + /* calculate base of control bits in TCON */ + pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4; + + pwm->clk = clk_get(dev, "pwm-tin"); + if (IS_ERR(pwm->clk)) { + dev_err(dev, "failed to get pwm tin clk\n"); + ret = PTR_ERR(pwm->clk); + goto err_alloc; + } + + pwm->clk_div = clk_get(dev, "pwm-tdiv"); + if (IS_ERR(pwm->clk_div)) { + dev_err(dev, "failed to get pwm tdiv clk\n"); + ret = PTR_ERR(pwm->clk_div); + goto err_clk_tin; + } + + local_irq_save(flags); + + tcon = __raw_readl(S3C2410_TCON); + tcon |= pwm_tcon_invert(pwm); + __raw_writel(tcon, S3C2410_TCON); + + local_irq_restore(flags); + + + ret = pwm_register(pwm); + if (ret) { + dev_err(dev, "failed to register pwm\n"); + goto err_clk_tdiv; + } + + pwm_dbg(pwm, "config bits %02x\n", + (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f); + + dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n", + clk_get_rate(pwm->clk), + clk_get_rate(pwm->clk_div), + pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base); + + platform_set_drvdata(pdev, pwm); + return 0; + + err_clk_tdiv: + clk_put(pwm->clk_div); + + err_clk_tin: + clk_put(pwm->clk); + + err_alloc: + kfree(pwm); + return ret; +} + +static int s3c_pwm_remove(struct platform_device *pdev) +{ + struct pwm_device *pwm = platform_get_drvdata(pdev); + + clk_put(pwm->clk_div); + clk_put(pwm->clk); + kfree(pwm); + + return 0; +} + +static struct platform_driver s3c_pwm_driver = { + .driver = { + .name = "s3c24xx-pwm", + .owner = THIS_MODULE, + }, + .probe = s3c_pwm_probe, + .remove = __devexit_p(s3c_pwm_remove), +}; + +static int __init pwm_init(void) +{ + int ret; + + clk_scaler[0] = clk_get(NULL, "pwm-scaler0"); + clk_scaler[1] = clk_get(NULL, "pwm-scaler1"); + + if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) { + printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__); + return -EINVAL; + } + + ret = platform_driver_register(&s3c_pwm_driver); + if (ret) + printk(KERN_ERR "%s: failed to add pwm driver\n", __func__); + + return ret; +} + +arch_initcall(pwm_init); diff --git a/include/asm-arm/plat-s3c24xx/devs.h b/include/asm-arm/plat-s3c24xx/devs.h index f9d6f0317bc..badaac9d64a 100644 --- a/include/asm-arm/plat-s3c24xx/devs.h +++ b/include/asm-arm/plat-s3c24xx/devs.h @@ -21,6 +21,8 @@ extern struct s3c24xx_uart_resources s3c2410_uart_resources[]; extern struct platform_device *s3c24xx_uart_devs[]; extern struct platform_device *s3c24xx_uart_src[]; +extern struct platform_device s3c_device_timer[]; + extern struct platform_device s3c_device_usb; extern struct platform_device s3c_device_lcd; extern struct platform_device s3c_device_wdt; @@ -36,11 +38,6 @@ extern struct platform_device s3c_device_spi1; extern struct platform_device s3c_device_nand; -extern struct platform_device s3c_device_timer0; -extern struct platform_device s3c_device_timer1; -extern struct platform_device s3c_device_timer2; -extern struct platform_device s3c_device_timer3; - extern struct platform_device s3c_device_usbgadget; /* s3c2440 specific devices */ -- cgit v1.2.3-70-g09d2 From 63dd10846d4917534e9ec7bddf43be786effe8b8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:43 +0200 Subject: MXC: do not include board specific header from architecture include do not include board-mx31ads.h from hardware.h, instead include it directly only where needed. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/mx31ads.c | 1 + include/asm-arm/arch-mxc/hardware.h | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 7e89bdc23a9..5addbb7f711 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c @@ -29,6 +29,7 @@ #include #include #include +#include /*! * @file mx31ads.c diff --git a/include/asm-arm/arch-mxc/hardware.h b/include/asm-arm/arch-mxc/hardware.h index e87ff0679d5..4ed2d8072d0 100644 --- a/include/asm-arm/arch-mxc/hardware.h +++ b/include/asm-arm/arch-mxc/hardware.h @@ -1,11 +1,20 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. */ #ifndef __ASM_ARCH_MXC_HARDWARE_H__ @@ -19,13 +28,4 @@ #include -/* - * --------------------------------------------------------------------------- - * Board specific defines - * --------------------------------------------------------------------------- - */ -#ifdef CONFIG_MACH_MX31ADS -# include -#endif - #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ -- cgit v1.2.3-70-g09d2 From 2582d8c1655f2eda42d5358a242b256fd6e88571 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:45 +0200 Subject: IMX UART: Add board specific init/exit functions Add platform specific init functions. Also rename the struct platform_device dev into pdev. Signed-off-by: Sascha Hauer --- drivers/serial/imx.c | 28 +++++++++++++++++++--------- include/asm-arm/arch-imx/imx-uart.h | 2 ++ 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'include/asm-arm') diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 6226e66c796..77968432b81 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -1078,30 +1078,40 @@ static int serial_imx_resume(struct platform_device *dev) return 0; } -static int serial_imx_probe(struct platform_device *dev) +static int serial_imx_probe(struct platform_device *pdev) { struct imxuart_platform_data *pdata; - imx_ports[dev->id].port.dev = &dev->dev; + imx_ports[pdev->id].port.dev = &pdev->dev; - pdata = (struct imxuart_platform_data *)dev->dev.platform_data; + pdata = pdev->dev.platform_data; if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) - imx_ports[dev->id].have_rtscts = 1; + imx_ports[pdev->id].have_rtscts = 1; + + if (pdata->init) + pdata->init(pdev); + + uart_add_one_port(&imx_reg, &imx_ports[pdev->id].port); + platform_set_drvdata(pdev, &imx_ports[pdev->id]); - uart_add_one_port(&imx_reg, &imx_ports[dev->id].port); - platform_set_drvdata(dev, &imx_ports[dev->id]); return 0; } -static int serial_imx_remove(struct platform_device *dev) +static int serial_imx_remove(struct platform_device *pdev) { - struct imx_port *sport = platform_get_drvdata(dev); + struct imxuart_platform_data *pdata; + struct imx_port *sport = platform_get_drvdata(pdev); - platform_set_drvdata(dev, NULL); + pdata = pdev->dev.platform_data; + + platform_set_drvdata(pdev, NULL); if (sport) uart_remove_one_port(&imx_reg, &sport->port); + if (pdata->exit) + pdata->exit(pdev); + return 0; } diff --git a/include/asm-arm/arch-imx/imx-uart.h b/include/asm-arm/arch-imx/imx-uart.h index 3a685e1780e..d54eb1d4802 100644 --- a/include/asm-arm/arch-imx/imx-uart.h +++ b/include/asm-arm/arch-imx/imx-uart.h @@ -4,6 +4,8 @@ #define IMXUART_HAVE_RTSCTS (1<<0) struct imxuart_platform_data { + int (*init)(struct platform_device *pdev); + void (*exit)(struct platform_device *pdev); unsigned int flags; }; -- cgit v1.2.3-70-g09d2 From 38a41fdf94c449c165213e4665c3f8a0d30f8aba Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:46 +0200 Subject: IMX: introduce clock API This patch introduces the clock API for i.MX and converts all in-Kernel drivers to use it. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/clock.c | 205 ++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/cpufreq.c | 20 +++- arch/arm/mach-imx/generic.c | 76 ------------- arch/arm/mach-imx/time.c | 23 ++-- drivers/mmc/host/imxmmc.c | 19 +++- drivers/serial/imx.c | 25 ++++- drivers/spi/spi_imx.c | 38 +++++-- include/asm-arm/arch-imx/hardware.h | 8 -- 9 files changed, 307 insertions(+), 109 deletions(-) create mode 100644 arch/arm/mach-imx/clock.c (limited to 'include/asm-arm') diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 88d5e61a2e1..b047c7e795a 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y += irq.o time.o dma.o generic.o +obj-y += irq.o time.o dma.o generic.o clock.o obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o diff --git a/arch/arm/mach-imx/clock.c b/arch/arm/mach-imx/clock.c new file mode 100644 index 00000000000..6a90fe5578d --- /dev/null +++ b/arch/arm/mach-imx/clock.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2008 Sascha Hauer , Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include +#include + +/* + * Very simple approach: We can't disable clocks, so we do + * not need refcounting + */ + +struct clk { + struct list_head node; + const char *name; + unsigned long (*get_rate)(void); +}; + +/* + * get the system pll clock in Hz + * + * mfi + mfn / (mfd +1) + * f = 2 * f_ref * -------------------- + * pd + 1 + */ +static unsigned long imx_decode_pll(unsigned int pll, u32 f_ref) +{ + unsigned long long ll; + unsigned long quot; + + u32 mfi = (pll >> 10) & 0xf; + u32 mfn = pll & 0x3ff; + u32 mfd = (pll >> 16) & 0x3ff; + u32 pd = (pll >> 26) & 0xf; + + mfi = mfi <= 5 ? 5 : mfi; + + ll = 2 * (unsigned long long)f_ref * + ((mfi << 16) + (mfn << 16) / (mfd + 1)); + quot = (pd + 1) * (1 << 16); + ll += quot / 2; + do_div(ll, quot); + return (unsigned long)ll; +} + +static unsigned long imx_get_system_clk(void) +{ + u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); + + return imx_decode_pll(SPCTL0, f_ref); +} + +static unsigned long imx_get_mcu_clk(void) +{ + return imx_decode_pll(MPCTL0, CLK32 * 512); +} + +/* + * get peripheral clock 1 ( UART[12], Timer[12], PWM ) + */ +static unsigned long imx_get_perclk1(void) +{ + return imx_get_system_clk() / (((PCDR) & 0xf)+1); +} + +/* + * get peripheral clock 2 ( LCD, SD, SPI[12] ) + */ +static unsigned long imx_get_perclk2(void) +{ + return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); +} + +/* + * get peripheral clock 3 ( SSI ) + */ +static unsigned long imx_get_perclk3(void) +{ + return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); +} + +/* + * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) + */ +static unsigned long imx_get_hclk(void) +{ + return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); +} + +static struct clk clk_system_clk = { + .name = "system_clk", + .get_rate = imx_get_system_clk, +}; + +static struct clk clk_hclk = { + .name = "hclk", + .get_rate = imx_get_hclk, +}; + +static struct clk clk_mcu_clk = { + .name = "mcu_clk", + .get_rate = imx_get_mcu_clk, +}; + +static struct clk clk_perclk1 = { + .name = "perclk1", + .get_rate = imx_get_perclk1, +}; + +static struct clk clk_uart_clk = { + .name = "uart_clk", + .get_rate = imx_get_perclk1, +}; + +static struct clk clk_perclk2 = { + .name = "perclk2", + .get_rate = imx_get_perclk2, +}; + +static struct clk clk_perclk3 = { + .name = "perclk3", + .get_rate = imx_get_perclk3, +}; + +static struct clk *clks[] = { + &clk_perclk1, + &clk_perclk2, + &clk_perclk3, + &clk_system_clk, + &clk_hclk, + &clk_mcu_clk, + &clk_uart_clk, +}; + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + + mutex_lock(&clocks_mutex); + list_for_each_entry(p, &clocks, node) { + if (!strcmp(p->name, id)) { + clk = p; + goto found; + } + } + +found: + mutex_unlock(&clocks_mutex); + + return clk; +} + +void clk_put(struct clk *clk) +{ +} + +int clk_enable(struct clk *clk) +{ + return 0; +} + +void clk_disable(struct clk *clk) +{ +} + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->get_rate(); +} + +int imx_clocks_init(void) +{ + int i; + + mutex_lock(&clocks_mutex); + for (i = 0; i < ARRAY_SIZE(clks); i++) + list_add(&clks[i]->node, &clocks); + mutex_unlock(&clocks_mutex); + + return 0; +} + diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c index e548ba74a4d..be0809b33e0 100644 --- a/arch/arm/mach-imx/cpufreq.c +++ b/arch/arm/mach-imx/cpufreq.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include @@ -52,6 +54,8 @@ static u32 mpctl0_at_boot; static u32 bclk_div_at_boot; +static struct clk *system_clk, *mcu_clk; + static void imx_set_async_mode(void) { adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE); @@ -160,10 +164,10 @@ static unsigned int imx_get_speed(unsigned int cpu) cr = get_cr(); if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) { - freq = imx_get_system_clk(); + freq = clk_get_rate(system_clk); freq = (freq + bclk_div/2) / bclk_div; } else { - freq = imx_get_mcu_clk(); + freq = clk_get_rate(mcu_clk); if (cscr & CSCR_MPU_PRESC) freq /= 2; } @@ -201,7 +205,7 @@ static int imx_set_target(struct cpufreq_policy *policy, pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n", freq, mpctl0_at_boot); - sysclk = imx_get_system_clk(); + sysclk = clk_get_rate(system_clk); if (freq > sysclk / bclk_div_at_boot + 1000000) { freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation); @@ -290,6 +294,16 @@ static int __init imx_cpufreq_init(void) bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1; mpctl0_at_boot = 0; + system_clk = clk_get(NULL, "system_clk"); + if (IS_ERR(system_clk)) + return PTR_ERR(system_clk); + + mcu_clk = clk_get(NULL, "mcu_clk"); + if (IS_ERR(mcu_clk)) { + clk_put(system_clk); + return PTR_ERR(mcu_clk); + } + if((CSCR & CSCR_MPEN) && ((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE)) mpctl0_at_boot = MPCTL0; diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 4cfc9d3af28..98ddd8a6d05 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c @@ -214,82 +214,6 @@ int imx_irq_to_gpio(unsigned irq) EXPORT_SYMBOL(imx_irq_to_gpio); -/* - * get the system pll clock in Hz - * - * mfi + mfn / (mfd +1) - * f = 2 * f_ref * -------------------- - * pd + 1 - */ -static unsigned int imx_decode_pll(unsigned int pll, u32 f_ref) -{ - unsigned long long ll; - unsigned long quot; - - u32 mfi = (pll >> 10) & 0xf; - u32 mfn = pll & 0x3ff; - u32 mfd = (pll >> 16) & 0x3ff; - u32 pd = (pll >> 26) & 0xf; - - mfi = mfi <= 5 ? 5 : mfi; - - ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) ); - quot = (pd+1) * (1<<16); - ll += quot / 2; - do_div(ll, quot); - return (unsigned int) ll; -} - -unsigned int imx_get_system_clk(void) -{ - u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); - - return imx_decode_pll(SPCTL0, f_ref); -} -EXPORT_SYMBOL(imx_get_system_clk); - -unsigned int imx_get_mcu_clk(void) -{ - return imx_decode_pll(MPCTL0, CLK32 * 512); -} -EXPORT_SYMBOL(imx_get_mcu_clk); - -/* - * get peripheral clock 1 ( UART[12], Timer[12], PWM ) - */ -unsigned int imx_get_perclk1(void) -{ - return imx_get_system_clk() / (((PCDR) & 0xf)+1); -} -EXPORT_SYMBOL(imx_get_perclk1); - -/* - * get peripheral clock 2 ( LCD, SD, SPI[12] ) - */ -unsigned int imx_get_perclk2(void) -{ - return imx_get_system_clk() / (((PCDR>>4) & 0xf)+1); -} -EXPORT_SYMBOL(imx_get_perclk2); - -/* - * get peripheral clock 3 ( SSI ) - */ -unsigned int imx_get_perclk3(void) -{ - return imx_get_system_clk() / (((PCDR>>16) & 0x7f)+1); -} -EXPORT_SYMBOL(imx_get_perclk3); - -/* - * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA ) - */ -unsigned int imx_get_hclk(void) -{ - return imx_get_system_clk() / (((CSCR>>10) & 0xf)+1); -} -EXPORT_SYMBOL(imx_get_hclk); - static struct resource imx_mmc_resources[] = { [0] = { .start = 0x00214000, diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index d86d124aea2..5a41e96e858 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -86,10 +87,10 @@ static struct clocksource clocksource_imx = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static int __init imx_clocksource_init(void) +static int __init imx_clocksource_init(unsigned long rate) { clocksource_imx.mult = - clocksource_hz2mult(imx_get_perclk1(), clocksource_imx.shift); + clocksource_hz2mult(rate, clocksource_imx.shift); clocksource_register(&clocksource_imx); return 0; @@ -174,9 +175,9 @@ static struct clock_event_device clockevent_imx = { .rating = 200, }; -static int __init imx_clockevent_init(void) +static int __init imx_clockevent_init(unsigned long rate) { - clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC, + clockevent_imx.mult = div_sc(rate, NSEC_PER_SEC, clockevent_imx.shift); clockevent_imx.max_delta_ns = clockevent_delta2ns(0xfffffffe, &clockevent_imx); @@ -190,13 +191,23 @@ static int __init imx_clockevent_init(void) return 0; } +extern int imx_clocks_init(void); static void __init imx_timer_init(void) { + struct clk *clk; + unsigned long rate; + + imx_clocks_init(); + + clk = clk_get(NULL, "perclk1"); + clk_enable(clk); + rate = clk_get_rate(clk); + imx_timer_hardware_init(); - imx_clocksource_init(); + imx_clocksource_init(rate); - imx_clockevent_init(); + imx_clockevent_init(rate); /* * Make irqs happen for the system timer diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 95f33e87a99..ef2f6fc8654 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -92,6 +93,8 @@ struct imxmci_host { unsigned char actual_bus_width; int prev_cmd_code; + + struct clk *clk; }; #define IMXMCI_PEND_IRQ_b 0 @@ -841,7 +844,7 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* The prescaler is 5 for PERCLK2 equal to 96MHz * then 96MHz / 5 = 19.2 MHz */ - clk=imx_get_perclk2(); + clk = clk_get_rate(host->clk); prescaler=(clk+(CLK_RATE*7)/8)/CLK_RATE; switch(prescaler) { case 0: @@ -994,6 +997,13 @@ static int imxmci_probe(struct platform_device *pdev) host->res = r; host->irq = irq; + host->clk = clk_get(&pdev->dev, "perclk2"); + if (IS_ERR(host->clk)) { + ret = PTR_ERR(host->clk); + goto out; + } + clk_enable(host->clk); + imx_gpio_mode(PB8_PF_SD_DAT0); imx_gpio_mode(PB9_PF_SD_DAT1); imx_gpio_mode(PB10_PF_SD_DAT2); @@ -1053,6 +1063,10 @@ out: imx_dma_free(host->dma); host->dma_allocated=0; } + if (host->clk) { + clk_disable(host->clk); + clk_put(host->clk); + } } if (mmc) mmc_free_host(mmc); @@ -1082,6 +1096,9 @@ static int imxmci_remove(struct platform_device *pdev) tasklet_kill(&host->tasklet); + clk_disable(host->clk); + clk_put(host->clk); + release_resource(host->res); mmc_free_host(mmc); diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 8d6cb745bd9..9e2162ebf1b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -184,6 +185,7 @@ struct imx_port { unsigned int old_status; int txirq,rxirq,rtsirq; int have_rtscts:1; + struct clk *clk; }; /* @@ -479,7 +481,8 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) * RFDIV is set such way to satisfy requested uartclk value */ val = TXTL << 10 | RXTL; - ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; + ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2) + / sport->port.uartclk; if(!ufcr_rfdiv) ufcr_rfdiv = 1; @@ -916,7 +919,7 @@ imx_console_get_options(struct imx_port *sport, int *baud, else ucfr_rfdiv = 6 - ucfr_rfdiv; - uartclk = imx_get_perclk1(); + uartclk = clk_get_rate(sport->clk); uartclk /= ucfr_rfdiv; { /* @@ -1054,7 +1057,15 @@ static int serial_imx_probe(struct platform_device *pdev) init_timer(&sport->timer); sport->timer.function = imx_timeout; sport->timer.data = (unsigned long)sport; - sport->port.uartclk = imx_get_perclk1(); + + sport->clk = clk_get(&pdev->dev, "uart_clk"); + if (IS_ERR(sport->clk)) { + ret = PTR_ERR(sport->clk); + goto unmap; + } + clk_enable(sport->clk); + + sport->port.uartclk = clk_get_rate(sport->clk); imx_ports[pdev->id] = sport; @@ -1069,6 +1080,8 @@ static int serial_imx_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &sport->port); return 0; +unmap: + iounmap(sport->port.membase); free: kfree(sport); @@ -1084,8 +1097,12 @@ static int serial_imx_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - if (sport) + if (sport) { uart_remove_one_port(&imx_reg, &sport->port); + clk_put(sport->clk); + } + + clk_disable(sport->clk); if (pdata->exit) pdata->exit(pdev); diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index c730d05bfeb..bd0729b6b6e 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -250,6 +251,8 @@ struct driver_data { int tx_dma_needs_unmap; size_t tx_map_len; u32 dummy_dma_buf ____cacheline_aligned; + + struct clk *clk; }; /* Runtime state */ @@ -855,15 +858,15 @@ static irqreturn_t spi_int(int irq, void *dev_id) return drv_data->transfer_handler(drv_data); } -static inline u32 spi_speed_hz(u32 data_rate) +static inline u32 spi_speed_hz(struct driver_data *drv_data, u32 data_rate) { - return imx_get_perclk2() / (4 << ((data_rate) >> 13)); + return clk_get_rate(drv_data->clk) / (4 << ((data_rate) >> 13)); } -static u32 spi_data_rate(u32 speed_hz) +static u32 spi_data_rate(struct driver_data *drv_data, u32 speed_hz) { u32 div; - u32 quantized_hz = imx_get_perclk2() >> 2; + u32 quantized_hz = clk_get_rate(drv_data->clk) >> 2; for (div = SPI_PERCLK2_DIV_MIN; div <= SPI_PERCLK2_DIV_MAX; @@ -947,7 +950,7 @@ static void pump_transfers(unsigned long data) tmp = transfer->speed_hz; if (tmp == 0) tmp = chip->max_speed_hz; - tmp = spi_data_rate(tmp); + tmp = spi_data_rate(drv_data, tmp); u32_EDIT(control, SPI_CONTROL_DATARATE, tmp); writel(control, regs + SPI_CONTROL); @@ -1109,7 +1112,7 @@ static int transfer(struct spi_device *spi, struct spi_message *msg) msg->actual_length = 0; /* Per transfer setup check */ - min_speed_hz = spi_speed_hz(SPI_CONTROL_DATARATE_MIN); + min_speed_hz = spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN); max_speed_hz = spi->max_speed_hz; list_for_each_entry(trans, &msg->transfers, transfer_list) { tmp = trans->bits_per_word; @@ -1176,6 +1179,7 @@ msg_rejected: applied and notified to the calling driver. */ static int setup(struct spi_device *spi) { + struct driver_data *drv_data = spi_master_get_devdata(spi->master); struct spi_imx_chip *chip_info; struct chip_data *chip; int first_setup = 0; @@ -1304,14 +1308,14 @@ static int setup(struct spi_device *spi) chip->n_bytes = (tmp <= 8) ? 1 : 2; /* SPI datarate */ - tmp = spi_data_rate(spi->max_speed_hz); + tmp = spi_data_rate(drv_data, spi->max_speed_hz); if (tmp == SPI_CONTROL_DATARATE_BAD) { status = -EINVAL; dev_err(&spi->dev, "setup - " "HW min speed (%d Hz) exceeds required " "max speed (%d Hz)\n", - spi_speed_hz(SPI_CONTROL_DATARATE_MIN), + spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN), spi->max_speed_hz); if (first_setup) goto err_first_setup; @@ -1321,7 +1325,7 @@ static int setup(struct spi_device *spi) } else { u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp); /* Actual rounded max_speed_hz */ - tmp = spi_speed_hz(tmp); + tmp = spi_speed_hz(drv_data, tmp); spi->max_speed_hz = tmp; chip->max_speed_hz = tmp; } @@ -1352,7 +1356,7 @@ static int setup(struct spi_device *spi) chip->period & SPI_PERIOD_WAIT, spi->mode, spi->bits_per_word, - spi_speed_hz(SPI_CONTROL_DATARATE_MIN), + spi_speed_hz(drv_data, SPI_CONTROL_DATARATE_MIN), spi->max_speed_hz); return status; @@ -1465,6 +1469,14 @@ static int __init spi_imx_probe(struct platform_device *pdev) goto err_no_pdata; } + drv_data->clk = clk_get(&pdev->dev, "perclk2"); + if (IS_ERR(drv_data->clk)) { + dev_err(&pdev->dev, "probe - cannot get get\n"); + status = PTR_ERR(drv_data->clk); + goto err_no_clk; + } + clk_enable(drv_data->clk); + /* Allocate master with space for drv_data */ master = spi_alloc_master(dev, sizeof(struct driver_data)); if (!master) { @@ -1623,6 +1635,9 @@ err_no_iores: spi_master_put(master); err_no_pdata: + clk_disable(drv_data->clk); + clk_put(drv_data->clk); +err_no_clk: err_no_mem: return status; } @@ -1662,6 +1677,9 @@ static int __exit spi_imx_remove(struct platform_device *pdev) if (irq >= 0) free_irq(irq, drv_data); + clk_disable(drv_data->clk); + clk_put(drv_data->clk); + /* Release map resources */ iounmap(drv_data->regs); release_resource(drv_data->ioarea); diff --git a/include/asm-arm/arch-imx/hardware.h b/include/asm-arm/arch-imx/hardware.h index adffb6acf42..6542ca5e8c3 100644 --- a/include/asm-arm/arch-imx/hardware.h +++ b/include/asm-arm/arch-imx/hardware.h @@ -73,14 +73,6 @@ */ extern void imx_gpio_mode( int gpio_mode ); -/* get frequencies in Hz */ -extern unsigned int imx_get_system_clk(void); -extern unsigned int imx_get_mcu_clk(void); -extern unsigned int imx_get_perclk1(void); /* UART[12], Timer[12], PWM */ -extern unsigned int imx_get_perclk2(void); /* LCD, SD, SPI[12] */ -extern unsigned int imx_get_perclk3(void); /* SSI */ -extern unsigned int imx_get_hclk(void); /* SDRAM, CSI, Memory Stick,*/ - /* I2C, DMA */ #endif #define MAXIRQNUM 62 -- cgit v1.2.3-70-g09d2 From c0db2ea4e366c94dd3f880928c02534156e3d1b9 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:47 +0200 Subject: MXC family: Add clock handling Internal clock path handling for the mxc CPUs. Changed against the original Freescale code (and against clocklib for example): - clock rate is always calculated whenever one ask for the current rate (means struct clk has no more a member called "rate"). So switching the PLL base frequency will propagate immediately to all other clocks that are depending on this frequency. Signed-off-by: Juergen Beisert --- arch/arm/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/clock.c | 331 +++++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-mxc/clock.h | 67 ++++++++ 3 files changed, 399 insertions(+), 1 deletion(-) create mode 100644 arch/arm/plat-mxc/clock.c create mode 100644 include/asm-arm/arch-mxc/clock.h (limited to 'include/asm-arm') diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index f96dc036206..3eb181cb7af 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,4 +3,4 @@ # # Common support -obj-y := irq.o +obj-y := irq.o clock.o diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c new file mode 100644 index 00000000000..1aa86fd60d7 --- /dev/null +++ b/arch/arm/plat-mxc/clock.c @@ -0,0 +1,331 @@ +/* + * Based on arch/arm/plat-omap/clock.c + * + * Copyright (C) 2004 - 2005 Nokia corporation + * Written by Tuukka Tikkanen + * Modified for omap shared clock framework by Tony Lindgren + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* #define DEBUG */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static LIST_HEAD(clocks); +static DEFINE_MUTEX(clocks_mutex); + +/*------------------------------------------------------------------------- + * Standard clock functions defined in include/linux/clk.h + *-------------------------------------------------------------------------*/ + +/* + * Retrieve a clock by name. + * + * Note that we first try to use device id on the bus + * and clock name. If this fails, we try to use ".". If this fails, + * we try to use clock name only. + * The reference count to the clock's module owner ref count is incremented. + */ +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p, *clk = ERR_PTR(-ENOENT); + int idno; + const char *str; + + if (id == NULL) + return clk; + + 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; + } + } + + str = strrchr(id, '.'); + if (str) { + int cnt = str - id; + str++; + idno = simple_strtol(str, NULL, 10); + list_for_each_entry(p, &clocks, node) { + if (p->id == idno && + strlen(p->name) == cnt && + strncmp(id, p->name, cnt) == 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; + goto found; + } + } + + printk(KERN_WARNING "clk: Unable to get requested clock: %s\n", id); + +found: + mutex_unlock(&clocks_mutex); + + return clk; +} +EXPORT_SYMBOL(clk_get); + +static void __clk_disable(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return; + + __clk_disable(clk->parent); + __clk_disable(clk->secondary); + + if (!(--clk->usecount) && clk->disable) + clk->disable(clk); +} + +static int __clk_enable(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + __clk_enable(clk->parent); + __clk_enable(clk->secondary); + + if (clk->usecount++ == 0 && clk->enable) + clk->enable(clk); + + return 0; +} + +/* This function increments the reference count on the clock and enables the + * clock if not already enabled. The parent clock tree is recursively enabled + */ +int clk_enable(struct clk *clk) +{ + int ret = 0; + + if (clk == NULL || IS_ERR(clk)) + return -EINVAL; + + mutex_lock(&clocks_mutex); + ret = __clk_enable(clk); + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL(clk_enable); + +/* This function decrements the reference count on the clock and disables + * the clock when reference count is 0. The parent clock tree is + * recursively disabled + */ +void clk_disable(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return; + + mutex_lock(&clocks_mutex); + __clk_disable(clk); + mutex_unlock(&clocks_mutex); +} +EXPORT_SYMBOL(clk_disable); + +/* Retrieve the *current* clock rate. If the clock itself + * does not provide a special calculation routine, ask + * its parent and so on, until one is able to return + * a valid clock rate + */ +unsigned long clk_get_rate(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return 0UL; + + if (clk->get_rate) + return clk->get_rate(clk); + + return clk_get_rate(clk->parent); +} +EXPORT_SYMBOL(clk_get_rate); + +/* Decrement the clock's module reference count */ +void clk_put(struct clk *clk) +{ + if (clk && !IS_ERR(clk)) + module_put(clk->owner); +} +EXPORT_SYMBOL(clk_put); + +/* Round the requested clock rate to the nearest supported + * rate that is less than or equal to the requested rate. + * This is dependent on the clock's current parent. + */ +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (clk == NULL || IS_ERR(clk) || !clk->round_rate) + return 0; + + return clk->round_rate(clk, rate); +} +EXPORT_SYMBOL(clk_round_rate); + +/* Set the clock to the requested clock rate. The rate must + * match a supported rate exactly based on what clk_round_rate returns + */ +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EINVAL; + + if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0) + return ret; + + mutex_lock(&clocks_mutex); + ret = clk->set_rate(clk, rate); + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +/* Set the clock's parent to another clock source */ +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + int ret = -EINVAL; + + if (clk == NULL || IS_ERR(clk) || parent == NULL || + IS_ERR(parent) || clk->set_parent == NULL) + return ret; + + mutex_lock(&clocks_mutex); + ret = clk->set_parent(clk, parent); + if (ret == 0) + clk->parent = parent; + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL(clk_set_parent); + +/* Retrieve the clock's parent clock source */ +struct clk *clk_get_parent(struct clk *clk) +{ + struct clk *ret = NULL; + + if (clk == NULL || IS_ERR(clk)) + return ret; + + return clk->parent; +} +EXPORT_SYMBOL(clk_get_parent); + +/* + * Add a new clock to the clock tree. + */ +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); + +/* Remove a clock from the clock tree */ +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); + +#ifdef CONFIG_PROC_FS +static int mxc_clock_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct clk *clkp; + char *p = page; + int len; + + list_for_each_entry(clkp, &clocks, node) { + p += sprintf(p, "%s-%d:\t\t%lu, %d", clkp->name, clkp->id, + clk_get_rate(clkp), clkp->usecount); + if (clkp->parent) + p += sprintf(p, ", %s-%d\n", clkp->parent->name, + clkp->parent->id); + else + p += sprintf(p, "\n"); + } + + len = (p - page) - off; + if (len < 0) + len = 0; + + *eof = (len <= count) ? 1 : 0; + *start = page + off; + + return len; +} + +static int __init mxc_setup_proc_entry(void) +{ + struct proc_dir_entry *res; + + res = create_proc_read_entry("cpu/clocks", 0, NULL, + mxc_clock_read_proc, NULL); + if (!res) { + printk(KERN_ERR "Failed to create proc/cpu/clocks\n"); + return -ENOMEM; + } + return 0; +} + +late_initcall(mxc_setup_proc_entry); +#endif diff --git a/include/asm-arm/arch-mxc/clock.h b/include/asm-arm/arch-mxc/clock.h new file mode 100644 index 00000000000..24caa2b7c91 --- /dev/null +++ b/include/asm-arm/arch-mxc/clock.h @@ -0,0 +1,67 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_CLOCK_H__ +#define __ASM_ARCH_MXC_CLOCK_H__ + +#ifndef __ASSEMBLY__ +#include + +struct module; + +struct clk { + struct list_head node; + struct module *owner; + const char *name; + int id; + /* Source clock this clk depends on */ + struct clk *parent; + /* Secondary clock to enable/disable with this clock */ + struct clk *secondary; + /* Reference count of clock enable/disable */ + __s8 usecount; + /* Register bit position for clock's enable/disable control. */ + u8 enable_shift; + /* Register address for clock's enable/disable control. */ + u32 enable_reg; + u32 flags; + /* get the current clock rate (always a fresh value) */ + unsigned long (*get_rate) (struct clk *); + /* Function ptr to set the clock to a new rate. The rate must match a + supported rate returned from round_rate. Leave blank if clock is not + programmable */ + int (*set_rate) (struct clk *, unsigned long); + /* Function ptr to round the requested clock rate to the nearest + supported rate that is less than or equal to the requested rate. */ + unsigned long (*round_rate) (struct clk *, unsigned long); + /* Function ptr to enable the clock. Leave blank if clock can not + be gated. */ + int (*enable) (struct clk *); + /* Function ptr to disable the clock. Leave blank if clock can not + be gated. */ + void (*disable) (struct clk *); + /* Function ptr to set the parent clock of the clock. */ + int (*set_parent) (struct clk *, struct clk *); +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_ARCH_MXC_CLOCK_H__ */ -- cgit v1.2.3-70-g09d2 From df1bf4bdb2a3a26d4bde8ae1aefc16385dd4898f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:48 +0200 Subject: i.MX3: introduce clock API This patch introduces the clock API for for arch-mxc Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/clock.c | 1147 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-mx3/crm_regs.h | 401 +++++++++++++ include/asm-arm/arch-mxc/common.h | 1 + 4 files changed, 1550 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mx3/clock.c create mode 100644 arch/arm/mach-mx3/crm_regs.h (limited to 'include/asm-arm') diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index cbec997f332..febb37f2393 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o +obj-y := mm.o time.o clock.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c new file mode 100644 index 00000000000..2f3635943e7 --- /dev/null +++ b/arch/arm/mach-mx3/clock.c @@ -0,0 +1,1147 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crm_regs.h" + +#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */ + +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) +{ + u32 min_pre, temp_pre, old_err, err; + + if (div >= 512) { + *pre = 8; + *post = 64; + } else if (div >= 64) { + min_pre = (div - 1) / 64 + 1; + old_err = 8; + for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { + err = div % temp_pre; + if (err == 0) { + *pre = temp_pre; + break; + } + err = temp_pre - err; + if (err < old_err) { + old_err = err; + *pre = temp_pre; + } + } + *post = (div + *pre - 1) / *pre; + } else if (div <= 8) { + *pre = div; + *post = 1; + } else { + *pre = 1; + *post = div; + } +} + +static struct clk mcu_pll_clk; +static struct clk mcu_main_clk; +static struct clk usb_pll_clk; +static struct clk serial_pll_clk; +static struct clk ipg_clk; +static struct clk ckih_clk; +static struct clk ahb_clk; + +static int _clk_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg |= 3 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); + + return 0; +} + +static void _clk_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(3 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static void _clk_emi_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(3 << clk->enable_shift); + reg |= (1 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + signed long pd = 1; /* Pre-divider */ + signed long mfi; /* Multiplication Factor (Integer part) */ + signed long mfn; /* Multiplication Factor (Integer part) */ + signed long mfd; /* Multiplication Factor (Denominator Part) */ + signed long tmp; + u32 ref_freq = clk_get_rate(clk->parent); + + while (((ref_freq / pd) * 10) > rate) + pd++; + + if ((ref_freq / pd) < PRE_DIV_MIN_FREQ) + return -EINVAL; + + /* the ref_freq/2 in the following is to round up */ + mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq; + if (mfi < 5 || mfi > 15) + return -EINVAL; + + /* pick a mfd value that will work + * then solve for mfn */ + mfd = ref_freq / 50000; + + /* + * pll_freq * pd * mfd + * mfn = -------------------- - (mfi * mfd) + * 2 * ref_freq + */ + /* the tmp/2 is for rounding */ + tmp = ref_freq / 10000; + mfn = + ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) - + (mfi * mfd); + + mfn = mfn & 0x3ff; + pd--; + mfd--; + + /* Change the Pll value */ + reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) | + (mfn << MXC_CCM_PCTL_MFN_OFFSET) | + (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET); + + if (clk == &mcu_pll_clk) + __raw_writel(reg, MXC_CCM_MPCTL); + else if (clk == &usb_pll_clk) + __raw_writel(reg, MXC_CCM_UPCTL); + else if (clk == &serial_pll_clk) + __raw_writel(reg, MXC_CCM_SRPCTL); + + return 0; +} + +static unsigned long _clk_pll_get_rate(struct clk *clk) +{ + long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; + unsigned long reg, ccmr; + s64 temp; + unsigned int prcs; + + ccmr = __raw_readl(MXC_CCM_CCMR); + prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; + if (prcs == 0x1) + ref_clk = CKIL_CLK_FREQ * 1024; + else + ref_clk = clk_get_rate(&ckih_clk); + + if (clk == &mcu_pll_clk) { + if ((ccmr & MXC_CCM_CCMR_MPE) == 0) + return ref_clk; + if ((ccmr & MXC_CCM_CCMR_MDS) != 0) + return ref_clk; + reg = __raw_readl(MXC_CCM_MPCTL); + } else if (clk == &usb_pll_clk) + reg = __raw_readl(MXC_CCM_UPCTL); + else if (clk == &serial_pll_clk) + reg = __raw_readl(MXC_CCM_SRPCTL); + else { + BUG(); + return 0; + } + + pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET; + mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET; + mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET; + mfi = (mfi <= 5) ? 5 : mfi; + mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK; + + if (mfn >= 0x200) { + mfn |= 0xFFFFFE00; + mfn_abs = -mfn; + } + + ref_clk *= 2; + ref_clk /= pdf + 1; + + temp = (u64) ref_clk * mfn_abs; + do_div(temp, mfd + 1); + if (mfn < 0) + temp = -temp; + temp = (ref_clk * mfi) + temp; + + return temp; +} + +static int _clk_usb_pll_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCMR); + reg |= MXC_CCM_CCMR_UPE; + __raw_writel(reg, MXC_CCM_CCMR); + + /* No lock bit on MX31, so using max time from spec */ + udelay(80); + + return 0; +} + +static void _clk_usb_pll_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCMR); + reg &= ~MXC_CCM_CCMR_UPE; + __raw_writel(reg, MXC_CCM_CCMR); +} + +static int _clk_serial_pll_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCMR); + reg |= MXC_CCM_CCMR_SPE; + __raw_writel(reg, MXC_CCM_CCMR); + + /* No lock bit on MX31, so using max time from spec */ + udelay(80); + + return 0; +} + +static void _clk_serial_pll_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCMR); + reg &= ~MXC_CCM_CCMR_SPE; + __raw_writel(reg, MXC_CCM_CCMR); +} + +#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off) +#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) +#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) + +static unsigned long _clk_mcu_main_get_rate(struct clk *clk) +{ + u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); + + if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) + return clk_get_rate(&serial_pll_clk); + else + return clk_get_rate(&mcu_pll_clk); +} + +static unsigned long _clk_hclk_get_rate(struct clk *clk) +{ + unsigned long max_pdf; + + max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK, + MXC_CCM_PDR0_MAX_PODF_OFFSET); + return clk_get_rate(clk->parent) / (max_pdf + 1); +} + +static unsigned long _clk_ipg_get_rate(struct clk *clk) +{ + unsigned long ipg_pdf; + + ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK, + MXC_CCM_PDR0_IPG_PODF_OFFSET); + return clk_get_rate(clk->parent) / (ipg_pdf + 1); +} + +static unsigned long _clk_nfc_get_rate(struct clk *clk) +{ + unsigned long nfc_pdf; + + nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK, + MXC_CCM_PDR0_NFC_PODF_OFFSET); + return clk_get_rate(clk->parent) / (nfc_pdf + 1); +} + +static unsigned long _clk_hsp_get_rate(struct clk *clk) +{ + unsigned long hsp_pdf; + + hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK, + MXC_CCM_PDR0_HSP_PODF_OFFSET); + return clk_get_rate(clk->parent) / (hsp_pdf + 1); +} + +static unsigned long _clk_usb_get_rate(struct clk *clk) +{ + unsigned long usb_pdf, usb_prepdf; + + usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK, + MXC_CCM_PDR1_USB_PODF_OFFSET); + usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK, + MXC_CCM_PDR1_USB_PRDF_OFFSET); + return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); +} + +static unsigned long _clk_csi_get_rate(struct clk *clk) +{ + u32 reg, pre, post; + + reg = __raw_readl(MXC_CCM_PDR0); + pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >> + MXC_CCM_PDR0_CSI_PRDF_OFFSET; + pre++; + post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >> + MXC_CCM_PDR0_CSI_PODF_OFFSET; + post++; + return clk_get_rate(clk->parent) / (pre * post); +} + +static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate) +{ + u32 pre, post, parent = clk_get_rate(clk->parent); + u32 div = parent / rate; + + if (parent % rate) + div++; + + __calc_pre_post_dividers(div, &pre, &post); + + return parent / (pre * post); +} + +static int _clk_csi_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); + + div = parent / rate; + + if ((parent / div) != rate) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + /* Set CSI clock divider */ + reg = __raw_readl(MXC_CCM_PDR0) & + ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK); + reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET; + __raw_writel(reg, MXC_CCM_PDR0); + + return 0; +} + +static unsigned long _clk_per_get_rate(struct clk *clk) +{ + unsigned long per_pdf; + + per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK, + MXC_CCM_PDR0_PER_PODF_OFFSET); + return clk_get_rate(clk->parent) / (per_pdf + 1); +} + +static unsigned long _clk_ssi1_get_rate(struct clk *clk) +{ + unsigned long ssi1_pdf, ssi1_prepdf; + + ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK, + MXC_CCM_PDR1_SSI1_PODF_OFFSET); + ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK, + MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET); + return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); +} + +static unsigned long _clk_ssi2_get_rate(struct clk *clk) +{ + unsigned long ssi2_pdf, ssi2_prepdf; + + ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK, + MXC_CCM_PDR1_SSI2_PODF_OFFSET); + ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK, + MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET); + return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); +} + +static unsigned long _clk_firi_get_rate(struct clk *clk) +{ + unsigned long firi_pdf, firi_prepdf; + + firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK, + MXC_CCM_PDR1_FIRI_PODF_OFFSET); + firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK, + MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET); + return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); +} + +static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate) +{ + u32 pre, post; + u32 parent = clk_get_rate(clk->parent); + u32 div = parent / rate; + + if (parent % rate) + div++; + + __calc_pre_post_dividers(div, &pre, &post); + + return parent / (pre * post); + +} + +static int _clk_firi_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); + + div = parent / rate; + + if ((parent / div) != rate) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + /* Set FIRI clock divider */ + reg = __raw_readl(MXC_CCM_PDR1) & + ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK); + reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET; + reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_PDR1); + + return 0; +} + +static unsigned long _clk_mbx_get_rate(struct clk *clk) +{ + return clk_get_rate(clk->parent) / 2; +} + +static unsigned long _clk_mstick1_get_rate(struct clk *clk) +{ + unsigned long msti_pdf; + + msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK, + MXC_CCM_PDR2_MST1_PDF_OFFSET); + return clk_get_rate(clk->parent) / (msti_pdf + 1); +} + +static unsigned long _clk_mstick2_get_rate(struct clk *clk) +{ + unsigned long msti_pdf; + + msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK, + MXC_CCM_PDR2_MST2_PDF_OFFSET); + return clk_get_rate(clk->parent) / (msti_pdf + 1); +} + +static unsigned long ckih_rate; + +static unsigned long clk_ckih_get_rate(struct clk *clk) +{ + return ckih_rate; +} + +static struct clk ckih_clk = { + .name = "ckih", + .get_rate = clk_ckih_get_rate, +}; + +static unsigned long clk_ckil_get_rate(struct clk *clk) +{ + return CKIL_CLK_FREQ; +} + +static struct clk ckil_clk = { + .name = "ckil", + .get_rate = clk_ckil_get_rate, +}; + +static struct clk mcu_pll_clk = { + .name = "mcu_pll", + .parent = &ckih_clk, + .set_rate = _clk_pll_set_rate, + .get_rate = _clk_pll_get_rate, +}; + +static struct clk mcu_main_clk = { + .name = "mcu_main_clk", + .parent = &mcu_pll_clk, + .get_rate = _clk_mcu_main_get_rate, +}; + +static struct clk serial_pll_clk = { + .name = "serial_pll", + .parent = &ckih_clk, + .set_rate = _clk_pll_set_rate, + .get_rate = _clk_pll_get_rate, + .enable = _clk_serial_pll_enable, + .disable = _clk_serial_pll_disable, +}; + +static struct clk usb_pll_clk = { + .name = "usb_pll", + .parent = &ckih_clk, + .set_rate = _clk_pll_set_rate, + .get_rate = _clk_pll_get_rate, + .enable = _clk_usb_pll_enable, + .disable = _clk_usb_pll_disable, +}; + +static struct clk ahb_clk = { + .name = "ahb_clk", + .parent = &mcu_main_clk, + .get_rate = _clk_hclk_get_rate, +}; + +static struct clk per_clk = { + .name = "per_clk", + .parent = &usb_pll_clk, + .get_rate = _clk_per_get_rate, +}; + +static struct clk perclk_clk = { + .name = "perclk_clk", + .parent = &ipg_clk, +}; + +static struct clk cspi_clk[] = { + { + .name = "cspi_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET, + .disable = _clk_disable,}, + { + .name = "cspi_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET, + .disable = _clk_disable,}, + { + .name = "cspi_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk ipg_clk = { + .name = "ipg_clk", + .parent = &ahb_clk, + .get_rate = _clk_ipg_get_rate, +}; + +static struct clk emi_clk = { + .name = "emi_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_EMI_OFFSET, + .disable = _clk_emi_disable, +}; + +static struct clk gpt_clk = { + .name = "gpt_clk", + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_GPT_OFFSET, + .disable = _clk_disable, +}; + +static struct clk pwm_clk = { + .name = "pwm_clk", + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR1_PWM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk epit_clk[] = { + { + .name = "epit_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET, + .disable = _clk_disable,}, + { + .name = "epit_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk nfc_clk = { + .name = "nfc_clk", + .parent = &ahb_clk, + .get_rate = _clk_nfc_get_rate, +}; + +static struct clk scc_clk = { + .name = "scc_clk", + .parent = &ipg_clk, +}; + +static struct clk ipu_clk = { + .name = "ipu_clk", + .parent = &mcu_main_clk, + .get_rate = _clk_hsp_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_IPU_OFFSET, + .disable = _clk_disable, +}; + +static struct clk kpp_clk = { + .name = "kpp_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_KPP_OFFSET, + .disable = _clk_disable, +}; + +static struct clk wdog_clk = { + .name = "wdog_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_WDOG_OFFSET, + .disable = _clk_disable, +}; +static struct clk rtc_clk = { + .name = "rtc_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_RTC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk usb_clk[] = { + { + .name = "usb_clk", + .parent = &usb_pll_clk, + .get_rate = _clk_usb_get_rate,}, + { + .name = "usb_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk csi_clk = { + .name = "csi_clk", + .parent = &serial_pll_clk, + .get_rate = _clk_csi_get_rate, + .round_rate = _clk_csi_round_rate, + .set_rate = _clk_csi_set_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_CSI_OFFSET, + .disable = _clk_disable, +}; + +static struct clk uart_clk[] = { + { + .name = "uart_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_UART1_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_UART2_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 2, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART3_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 3, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART4_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 4, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART5_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk i2c_clk[] = { + { + .name = "i2c_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET, + .disable = _clk_disable,}, + { + .name = "i2c_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET, + .disable = _clk_disable,}, + { + .name = "i2c_clk", + .id = 2, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk owire_clk = { + .name = "owire_clk", + .parent = &perclk_clk, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static struct clk sdhc_clk[] = { + { + .name = "sdhc_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET, + .disable = _clk_disable,}, + { + .name = "sdhc_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk ssi_clk[] = { + { + .name = "ssi_clk", + .parent = &serial_pll_clk, + .get_rate = _clk_ssi1_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET, + .disable = _clk_disable,}, + { + .name = "ssi_clk", + .id = 1, + .parent = &serial_pll_clk, + .get_rate = _clk_ssi2_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk firi_clk = { + .name = "firi_clk", + .parent = &usb_pll_clk, + .round_rate = _clk_firi_round_rate, + .set_rate = _clk_firi_set_rate, + .get_rate = _clk_firi_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_FIRI_OFFSET, + .disable = _clk_disable, +}; + +static struct clk ata_clk = { + .name = "ata_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_ATA_OFFSET, + .disable = _clk_disable, +}; + +static struct clk mbx_clk = { + .name = "mbx_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, + .get_rate = _clk_mbx_get_rate, +}; + +static struct clk vpu_clk = { + .name = "vpu_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, + .get_rate = _clk_mbx_get_rate, +}; + +static struct clk rtic_clk = { + .name = "rtic_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk rng_clk = { + .name = "rng_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_RNG_OFFSET, + .disable = _clk_disable, +}; + +static struct clk sdma_clk[] = { + { + .name = "sdma_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET, + .disable = _clk_disable,}, + { + .name = "sdma_ipg_clk", + .parent = &ipg_clk,} +}; + +static struct clk mpeg4_clk = { + .name = "mpeg4_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk vl2cc_clk = { + .name = "vl2cc_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk mstick_clk[] = { + { + .name = "mstick_clk", + .id = 0, + .parent = &usb_pll_clk, + .get_rate = _clk_mstick1_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET, + .disable = _clk_disable,}, + { + .name = "mstick_clk", + .id = 1, + .parent = &usb_pll_clk, + .get_rate = _clk_mstick2_get_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk iim_clk = { + .name = "iim_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_IIM_OFFSET, + .disable = _clk_disable, +}; + +static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div, parent = clk_get_rate(clk->parent); + + div = parent / rate; + if (parent % rate) + div++; + + if (div > 8) + div = 16; + else if (div > 4) + div = 8; + else if (div > 2) + div = 4; + + return parent / div; +} + +static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div, parent = clk_get_rate(clk->parent); + + div = parent / rate; + + if (div == 16) + div = 4; + else if (div == 8) + div = 3; + else if (div == 4) + div = 2; + else if (div == 2) + div = 1; + else if (div == 1) + div = 0; + else + return -EINVAL; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK; + reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET; + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static unsigned long _clk_cko1_get_rate(struct clk *clk) +{ + u32 div; + + div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >> + MXC_CCM_COSR_CLKOUTDIV_OFFSET; + + return clk_get_rate(clk->parent) / (1 << div); +} + +static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK; + + if (parent == &mcu_main_clk) + reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ipg_clk) + reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &usb_pll_clk) + reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == mcu_main_clk.parent) + reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ahb_clk) + reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &serial_pll_clk) + reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ckih_clk) + reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &emi_clk) + reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ipu_clk) + reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &nfc_clk) + reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &uart_clk[0]) + reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET; + else + return -EINVAL; + + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static int _clk_cko1_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN; + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static void _clk_cko1_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN; + __raw_writel(reg, MXC_CCM_COSR); +} + +static struct clk cko1_clk = { + .name = "cko1_clk", + .get_rate = _clk_cko1_get_rate, + .set_rate = _clk_cko1_set_rate, + .round_rate = _clk_cko1_round_rate, + .set_parent = _clk_cko1_set_parent, + .enable = _clk_cko1_enable, + .disable = _clk_cko1_disable, +}; + +static struct clk *mxc_clks[] = { + &ckih_clk, + &ckil_clk, + &mcu_pll_clk, + &usb_pll_clk, + &serial_pll_clk, + &mcu_main_clk, + &ahb_clk, + &per_clk, + &perclk_clk, + &cko1_clk, + &emi_clk, + &cspi_clk[0], + &cspi_clk[1], + &cspi_clk[2], + &ipg_clk, + &gpt_clk, + &pwm_clk, + &wdog_clk, + &rtc_clk, + &epit_clk[0], + &epit_clk[1], + &nfc_clk, + &ipu_clk, + &kpp_clk, + &usb_clk[0], + &usb_clk[1], + &csi_clk, + &uart_clk[0], + &uart_clk[1], + &uart_clk[2], + &uart_clk[3], + &uart_clk[4], + &i2c_clk[0], + &i2c_clk[1], + &i2c_clk[2], + &owire_clk, + &sdhc_clk[0], + &sdhc_clk[1], + &ssi_clk[0], + &ssi_clk[1], + &firi_clk, + &ata_clk, + &rtic_clk, + &rng_clk, + &sdma_clk[0], + &sdma_clk[1], + &mstick_clk[0], + &mstick_clk[1], + &scc_clk, + &iim_clk, +}; + +int __init mxc_clocks_init(unsigned long fref) +{ + u32 reg; + struct clk **clkp; + + ckih_rate = fref; + + for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) + clk_register(*clkp); + + if (cpu_is_mx31()) { + clk_register(&mpeg4_clk); + clk_register(&mbx_clk); + } else { + clk_register(&vpu_clk); + clk_register(&vl2cc_clk); + } + + /* Turn off all possible clocks */ + __raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0); + __raw_writel(0, MXC_CCM_CGR1); + + __raw_writel(MXC_CCM_CGR2_EMI_MASK | + MXC_CCM_CGR2_IPMUX1_MASK | + MXC_CCM_CGR2_IPMUX2_MASK | + MXC_CCM_CGR2_MXCCLKENSEL_MASK | /* for MX32 */ + MXC_CCM_CGR2_CHIKCAMPEN_MASK | /* for MX32 */ + MXC_CCM_CGR2_OVRVPUBUSY_MASK | /* for MX32 */ + 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for + MX32, but still required to be set */ + MXC_CCM_CGR2); + + clk_disable(&cko1_clk); + clk_disable(&usb_pll_clk); + + pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); + + clk_enable(&gpt_clk); + clk_enable(&emi_clk); + clk_enable(&iim_clk); + + clk_enable(&serial_pll_clk); + + if (mx31_revision() >= CHIP_REV_2_0) { + reg = __raw_readl(MXC_CCM_PMCR1); + /* No PLL restart on DVFS switch; enable auto EMI handshake */ + reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN; + __raw_writel(reg, MXC_CCM_PMCR1); + } + + return 0; +} + diff --git a/arch/arm/mach-mx3/crm_regs.h b/arch/arm/mach-mx3/crm_regs.h new file mode 100644 index 00000000000..4a0e0ede23b --- /dev/null +++ b/arch/arm/mach-mx3/crm_regs.h @@ -0,0 +1,401 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX3_CRM_REGS_H__ + +#define CKIH_CLK_FREQ 26000000 +#define CKIH_CLK_FREQ_27MHZ 27000000 +#define CKIL_CLK_FREQ 32768 + +#define MXC_CCM_BASE IO_ADDRESS(CCM_BASE_ADDR) + +/* Register addresses */ +#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00) +#define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04) +#define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08) +#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C) +#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10) +#define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14) +#define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18) +#define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C) +#define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20) +#define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24) +#define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28) +#define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C) +#define MXC_CCM_LDC (MXC_CCM_BASE + 0x30) +#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34) +#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38) +#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C) +#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40) +#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x44) +#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x48) +#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x4C) +#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x50) +#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x54) +#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x58) +#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x5C) +#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x60) +#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64) + +/* Register bit definitions */ +#define MXC_CCM_CCMR_WBEN (1 << 27) +#define MXC_CCM_CCMR_CSCS (1 << 25) +#define MXC_CCM_CCMR_PERCS (1 << 24) +#define MXC_CCM_CCMR_SSI1S_OFFSET 18 +#define MXC_CCM_CCMR_SSI1S_MASK (0x3 << 18) +#define MXC_CCM_CCMR_SSI2S_OFFSET 21 +#define MXC_CCM_CCMR_SSI2S_MASK (0x3 << 21) +#define MXC_CCM_CCMR_LPM_OFFSET 14 +#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14) +#define MXC_CCM_CCMR_FIRS_OFFSET 11 +#define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11) +#define MXC_CCM_CCMR_UPE (1 << 9) +#define MXC_CCM_CCMR_SPE (1 << 8) +#define MXC_CCM_CCMR_MDS (1 << 7) +#define MXC_CCM_CCMR_SBYCS (1 << 4) +#define MXC_CCM_CCMR_MPE (1 << 3) +#define MXC_CCM_CCMR_PRCS_OFFSET 1 +#define MXC_CCM_CCMR_PRCS_MASK (0x3 << 1) + +#define MXC_CCM_PDR0_CSI_PODF_OFFSET 26 +#define MXC_CCM_PDR0_CSI_PODF_MASK (0x3F << 26) +#define MXC_CCM_PDR0_CSI_PRDF_OFFSET 23 +#define MXC_CCM_PDR0_CSI_PRDF_MASK (0x7 << 23) +#define MXC_CCM_PDR0_PER_PODF_OFFSET 16 +#define MXC_CCM_PDR0_PER_PODF_MASK (0x1F << 16) +#define MXC_CCM_PDR0_HSP_PODF_OFFSET 11 +#define MXC_CCM_PDR0_HSP_PODF_MASK (0x7 << 11) +#define MXC_CCM_PDR0_NFC_PODF_OFFSET 8 +#define MXC_CCM_PDR0_NFC_PODF_MASK (0x7 << 8) +#define MXC_CCM_PDR0_IPG_PODF_OFFSET 6 +#define MXC_CCM_PDR0_IPG_PODF_MASK (0x3 << 6) +#define MXC_CCM_PDR0_MAX_PODF_OFFSET 3 +#define MXC_CCM_PDR0_MAX_PODF_MASK (0x7 << 3) +#define MXC_CCM_PDR0_MCU_PODF_OFFSET 0 +#define MXC_CCM_PDR0_MCU_PODF_MASK 0x7 + +#define MXC_CCM_PDR0_HSP_DIV_1 (0x0 << 11) +#define MXC_CCM_PDR0_HSP_DIV_2 (0x1 << 11) +#define MXC_CCM_PDR0_HSP_DIV_3 (0x2 << 11) +#define MXC_CCM_PDR0_HSP_DIV_4 (0x3 << 11) +#define MXC_CCM_PDR0_HSP_DIV_5 (0x4 << 11) +#define MXC_CCM_PDR0_HSP_DIV_6 (0x5 << 11) +#define MXC_CCM_PDR0_HSP_DIV_7 (0x6 << 11) +#define MXC_CCM_PDR0_HSP_DIV_8 (0x7 << 11) + +#define MXC_CCM_PDR0_IPG_DIV_1 (0x0 << 6) +#define MXC_CCM_PDR0_IPG_DIV_2 (0x1 << 6) +#define MXC_CCM_PDR0_IPG_DIV_3 (0x2 << 6) +#define MXC_CCM_PDR0_IPG_DIV_4 (0x3 << 6) + +#define MXC_CCM_PDR0_MAX_DIV_1 (0x0 << 3) +#define MXC_CCM_PDR0_MAX_DIV_2 (0x1 << 3) +#define MXC_CCM_PDR0_MAX_DIV_3 (0x2 << 3) +#define MXC_CCM_PDR0_MAX_DIV_4 (0x3 << 3) +#define MXC_CCM_PDR0_MAX_DIV_5 (0x4 << 3) +#define MXC_CCM_PDR0_MAX_DIV_6 (0x5 << 3) +#define MXC_CCM_PDR0_MAX_DIV_7 (0x6 << 3) +#define MXC_CCM_PDR0_MAX_DIV_8 (0x7 << 3) + +#define MXC_CCM_PDR0_NFC_DIV_1 (0x0 << 8) +#define MXC_CCM_PDR0_NFC_DIV_2 (0x1 << 8) +#define MXC_CCM_PDR0_NFC_DIV_3 (0x2 << 8) +#define MXC_CCM_PDR0_NFC_DIV_4 (0x3 << 8) +#define MXC_CCM_PDR0_NFC_DIV_5 (0x4 << 8) +#define MXC_CCM_PDR0_NFC_DIV_6 (0x5 << 8) +#define MXC_CCM_PDR0_NFC_DIV_7 (0x6 << 8) +#define MXC_CCM_PDR0_NFC_DIV_8 (0x7 << 8) + +#define MXC_CCM_PDR0_MCU_DIV_1 0x0 +#define MXC_CCM_PDR0_MCU_DIV_2 0x1 +#define MXC_CCM_PDR0_MCU_DIV_3 0x2 +#define MXC_CCM_PDR0_MCU_DIV_4 0x3 +#define MXC_CCM_PDR0_MCU_DIV_5 0x4 +#define MXC_CCM_PDR0_MCU_DIV_6 0x5 +#define MXC_CCM_PDR0_MCU_DIV_7 0x6 +#define MXC_CCM_PDR0_MCU_DIV_8 0x7 + +#define MXC_CCM_PDR1_USB_PRDF_OFFSET 30 +#define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30) +#define MXC_CCM_PDR1_USB_PODF_OFFSET 27 +#define MXC_CCM_PDR1_USB_PODF_MASK (0x7 << 27) +#define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET 24 +#define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK (0x7 << 24) +#define MXC_CCM_PDR1_FIRI_PODF_OFFSET 18 +#define MXC_CCM_PDR1_FIRI_PODF_MASK (0x3F << 18) +#define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET 15 +#define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK (0x7 << 15) +#define MXC_CCM_PDR1_SSI2_PODF_OFFSET 9 +#define MXC_CCM_PDR1_SSI2_PODF_MASK (0x3F << 9) +#define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET 6 +#define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK (0x7 << 6) +#define MXC_CCM_PDR1_SSI1_PODF_OFFSET 0 +#define MXC_CCM_PDR1_SSI1_PODF_MASK 0x3F + +/* Bit definitions for RCSR */ +#define MXC_CCM_RCSR_NF16B 0x80000000 + +/* Bit definitions for both MCU, USB and SR PLL control registers */ +#define MXC_CCM_PCTL_BRM 0x80000000 +#define MXC_CCM_PCTL_PD_OFFSET 26 +#define MXC_CCM_PCTL_PD_MASK (0xF << 26) +#define MXC_CCM_PCTL_MFD_OFFSET 16 +#define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16) +#define MXC_CCM_PCTL_MFI_OFFSET 10 +#define MXC_CCM_PCTL_MFI_MASK (0xF << 10) +#define MXC_CCM_PCTL_MFN_OFFSET 0 +#define MXC_CCM_PCTL_MFN_MASK 0x3FF + +#define MXC_CCM_CGR0_SD_MMC1_OFFSET 0 +#define MXC_CCM_CGR0_SD_MMC1_MASK (0x3 << 0) +#define MXC_CCM_CGR0_SD_MMC2_OFFSET 2 +#define MXC_CCM_CGR0_SD_MMC2_MASK (0x3 << 2) +#define MXC_CCM_CGR0_GPT_OFFSET 4 +#define MXC_CCM_CGR0_GPT_MASK (0x3 << 4) +#define MXC_CCM_CGR0_EPIT1_OFFSET 6 +#define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 6) +#define MXC_CCM_CGR0_EPIT2_OFFSET 8 +#define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 8) +#define MXC_CCM_CGR0_IIM_OFFSET 10 +#define MXC_CCM_CGR0_IIM_MASK (0x3 << 10) +#define MXC_CCM_CGR0_ATA_OFFSET 12 +#define MXC_CCM_CGR0_ATA_MASK (0x3 << 12) +#define MXC_CCM_CGR0_SDMA_OFFSET 14 +#define MXC_CCM_CGR0_SDMA_MASK (0x3 << 14) +#define MXC_CCM_CGR0_CSPI3_OFFSET 16 +#define MXC_CCM_CGR0_CSPI3_MASK (0x3 << 16) +#define MXC_CCM_CGR0_RNG_OFFSET 18 +#define MXC_CCM_CGR0_RNG_MASK (0x3 << 18) +#define MXC_CCM_CGR0_UART1_OFFSET 20 +#define MXC_CCM_CGR0_UART1_MASK (0x3 << 20) +#define MXC_CCM_CGR0_UART2_OFFSET 22 +#define MXC_CCM_CGR0_UART2_MASK (0x3 << 22) +#define MXC_CCM_CGR0_SSI1_OFFSET 24 +#define MXC_CCM_CGR0_SSI1_MASK (0x3 << 24) +#define MXC_CCM_CGR0_I2C1_OFFSET 26 +#define MXC_CCM_CGR0_I2C1_MASK (0x3 << 26) +#define MXC_CCM_CGR0_I2C2_OFFSET 28 +#define MXC_CCM_CGR0_I2C2_MASK (0x3 << 28) +#define MXC_CCM_CGR0_I2C3_OFFSET 30 +#define MXC_CCM_CGR0_I2C3_MASK (0x3 << 30) + +#define MXC_CCM_CGR1_HANTRO_OFFSET 0 +#define MXC_CCM_CGR1_HANTRO_MASK (0x3 << 0) +#define MXC_CCM_CGR1_MEMSTICK1_OFFSET 2 +#define MXC_CCM_CGR1_MEMSTICK1_MASK (0x3 << 2) +#define MXC_CCM_CGR1_MEMSTICK2_OFFSET 4 +#define MXC_CCM_CGR1_MEMSTICK2_MASK (0x3 << 4) +#define MXC_CCM_CGR1_CSI_OFFSET 6 +#define MXC_CCM_CGR1_CSI_MASK (0x3 << 6) +#define MXC_CCM_CGR1_RTC_OFFSET 8 +#define MXC_CCM_CGR1_RTC_MASK (0x3 << 8) +#define MXC_CCM_CGR1_WDOG_OFFSET 10 +#define MXC_CCM_CGR1_WDOG_MASK (0x3 << 10) +#define MXC_CCM_CGR1_PWM_OFFSET 12 +#define MXC_CCM_CGR1_PWM_MASK (0x3 << 12) +#define MXC_CCM_CGR1_SIM_OFFSET 14 +#define MXC_CCM_CGR1_SIM_MASK (0x3 << 14) +#define MXC_CCM_CGR1_ECT_OFFSET 16 +#define MXC_CCM_CGR1_ECT_MASK (0x3 << 16) +#define MXC_CCM_CGR1_USBOTG_OFFSET 18 +#define MXC_CCM_CGR1_USBOTG_MASK (0x3 << 18) +#define MXC_CCM_CGR1_KPP_OFFSET 20 +#define MXC_CCM_CGR1_KPP_MASK (0x3 << 20) +#define MXC_CCM_CGR1_IPU_OFFSET 22 +#define MXC_CCM_CGR1_IPU_MASK (0x3 << 22) +#define MXC_CCM_CGR1_UART3_OFFSET 24 +#define MXC_CCM_CGR1_UART3_MASK (0x3 << 24) +#define MXC_CCM_CGR1_UART4_OFFSET 26 +#define MXC_CCM_CGR1_UART4_MASK (0x3 << 26) +#define MXC_CCM_CGR1_UART5_OFFSET 28 +#define MXC_CCM_CGR1_UART5_MASK (0x3 << 28) +#define MXC_CCM_CGR1_OWIRE_OFFSET 30 +#define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 30) + +#define MXC_CCM_CGR2_SSI2_OFFSET 0 +#define MXC_CCM_CGR2_SSI2_MASK (0x3 << 0) +#define MXC_CCM_CGR2_CSPI1_OFFSET 2 +#define MXC_CCM_CGR2_CSPI1_MASK (0x3 << 2) +#define MXC_CCM_CGR2_CSPI2_OFFSET 4 +#define MXC_CCM_CGR2_CSPI2_MASK (0x3 << 4) +#define MXC_CCM_CGR2_GACC_OFFSET 6 +#define MXC_CCM_CGR2_GACC_MASK (0x3 << 6) +#define MXC_CCM_CGR2_EMI_OFFSET 8 +#define MXC_CCM_CGR2_EMI_MASK (0x3 << 8) +#define MXC_CCM_CGR2_RTIC_OFFSET 10 +#define MXC_CCM_CGR2_RTIC_MASK (0x3 << 10) +#define MXC_CCM_CGR2_FIRI_OFFSET 12 +#define MXC_CCM_CGR2_FIRI_MASK (0x3 << 12) +#define MXC_CCM_CGR2_IPMUX1_OFFSET 14 +#define MXC_CCM_CGR2_IPMUX1_MASK (0x3 << 14) +#define MXC_CCM_CGR2_IPMUX2_OFFSET 16 +#define MXC_CCM_CGR2_IPMUX2_MASK (0x3 << 16) + +/* These new CGR2 bits are added in MX32 */ +#define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET 18 +#define MXC_CCM_CGR2_APMSYSCLKSEL_MASK (0x3 << 18) +#define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET 20 +#define MXC_CCM_CGR2_APMSSICLKSEL_MASK (0x3 << 20) +#define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET 22 +#define MXC_CCM_CGR2_APMPERCLKSEL_MASK (0x3 << 22) +#define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET 24 +#define MXC_CCM_CGR2_MXCCLKENSEL_MASK (0x1 << 24) +#define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET 25 +#define MXC_CCM_CGR2_CHIKCAMPEN_MASK (0x1 << 25) +#define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET 26 +#define MXC_CCM_CGR2_OVRVPUBUSY_MASK (0x1 << 26) +#define MXC_CCM_CGR2_APMENA_OFFSET 30 +#define MXC_CCM_CGR2_AOMENA_MASK (0x1 << 30) + +/* + * LTR0 register offsets + */ +#define MXC_CCM_LTR0_DIV3CK_OFFSET 1 +#define MXC_CCM_LTR0_DIV3CK_MASK (0x3 << 1) +#define MXC_CCM_LTR0_DNTHR_OFFSET 16 +#define MXC_CCM_LTR0_DNTHR_MASK (0x3F << 16) +#define MXC_CCM_LTR0_UPTHR_OFFSET 22 +#define MXC_CCM_LTR0_UPTHR_MASK (0x3F << 22) + +/* + * LTR1 register offsets + */ +#define MXC_CCM_LTR1_PNCTHR_OFFSET 0 +#define MXC_CCM_LTR1_PNCTHR_MASK 0x3F +#define MXC_CCM_LTR1_UPCNT_OFFSET 6 +#define MXC_CCM_LTR1_UPCNT_MASK (0xFF << 6) +#define MXC_CCM_LTR1_DNCNT_OFFSET 14 +#define MXC_CCM_LTR1_DNCNT_MASK (0xFF << 14) +#define MXC_CCM_LTR1_LTBRSR_MASK 0x400000 +#define MXC_CCM_LTR1_LTBRSR_OFFSET 22 +#define MXC_CCM_LTR1_LTBRSR 0x400000 +#define MXC_CCM_LTR1_LTBRSH 0x800000 + +/* + * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15 + */ +#define MXC_CCM_LTR2_WSW_OFFSET(x) (11 + (x) * 3) +#define MXC_CCM_LTR2_WSW_MASK(x) (0x7 << \ + MXC_CCM_LTR2_WSW_OFFSET((x))) +#define MXC_CCM_LTR2_EMAC_OFFSET 0 +#define MXC_CCM_LTR2_EMAC_MASK 0x1FF + +/* + * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8 + */ +#define MXC_CCM_LTR3_WSW_OFFSET(x) (5 + (x) * 3) +#define MXC_CCM_LTR3_WSW_MASK(x) (0x7 << \ + MXC_CCM_LTR3_WSW_OFFSET((x))) + +#define MXC_CCM_PMCR0_DFSUP1 0x80000000 +#define MXC_CCM_PMCR0_DFSUP1_SPLL (0 << 31) +#define MXC_CCM_PMCR0_DFSUP1_MPLL (1 << 31) +#define MXC_CCM_PMCR0_DFSUP0 0x40000000 +#define MXC_CCM_PMCR0_DFSUP0_PLL (0 << 30) +#define MXC_CCM_PMCR0_DFSUP0_PDR (1 << 30) +#define MXC_CCM_PMCR0_DFSUP_MASK (0x3 << 30) + +#define DVSUP_TURBO 0 +#define DVSUP_HIGH 1 +#define DVSUP_MEDIUM 2 +#define DVSUP_LOW 3 +#define MXC_CCM_PMCR0_DVSUP_TURBO (DVSUP_TURBO << 28) +#define MXC_CCM_PMCR0_DVSUP_HIGH (DVSUP_HIGH << 28) +#define MXC_CCM_PMCR0_DVSUP_MEDIUM (DVSUP_MEDIUM << 28) +#define MXC_CCM_PMCR0_DVSUP_LOW (DVSUP_LOW << 28) +#define MXC_CCM_PMCR0_DVSUP_OFFSET 28 +#define MXC_CCM_PMCR0_DVSUP_MASK (0x3 << 28) +#define MXC_CCM_PMCR0_UDSC 0x08000000 +#define MXC_CCM_PMCR0_UDSC_MASK (1 << 27) +#define MXC_CCM_PMCR0_UDSC_UP (1 << 27) +#define MXC_CCM_PMCR0_UDSC_DOWN (0 << 27) + +#define MXC_CCM_PMCR0_VSCNT_1 (0x0 << 24) +#define MXC_CCM_PMCR0_VSCNT_2 (0x1 << 24) +#define MXC_CCM_PMCR0_VSCNT_3 (0x2 << 24) +#define MXC_CCM_PMCR0_VSCNT_4 (0x3 << 24) +#define MXC_CCM_PMCR0_VSCNT_5 (0x4 << 24) +#define MXC_CCM_PMCR0_VSCNT_6 (0x5 << 24) +#define MXC_CCM_PMCR0_VSCNT_7 (0x6 << 24) +#define MXC_CCM_PMCR0_VSCNT_8 (0x7 << 24) +#define MXC_CCM_PMCR0_VSCNT_OFFSET 24 +#define MXC_CCM_PMCR0_VSCNT_MASK (0x7 << 24) +#define MXC_CCM_PMCR0_DVFEV 0x00800000 +#define MXC_CCM_PMCR0_DVFIS 0x00400000 +#define MXC_CCM_PMCR0_LBMI 0x00200000 +#define MXC_CCM_PMCR0_LBFL 0x00100000 +#define MXC_CCM_PMCR0_LBCF_4 (0x0 << 18) +#define MXC_CCM_PMCR0_LBCF_8 (0x1 << 18) +#define MXC_CCM_PMCR0_LBCF_12 (0x2 << 18) +#define MXC_CCM_PMCR0_LBCF_16 (0x3 << 18) +#define MXC_CCM_PMCR0_LBCF_OFFSET 18 +#define MXC_CCM_PMCR0_LBCF_MASK (0x3 << 18) +#define MXC_CCM_PMCR0_PTVIS 0x00020000 +#define MXC_CCM_PMCR0_UPDTEN 0x00010000 +#define MXC_CCM_PMCR0_UPDTEN_MASK (0x1 << 16) +#define MXC_CCM_PMCR0_FSVAIM 0x00008000 +#define MXC_CCM_PMCR0_FSVAI_OFFSET 13 +#define MXC_CCM_PMCR0_FSVAI_MASK (0x3 << 13) +#define MXC_CCM_PMCR0_DPVCR 0x00001000 +#define MXC_CCM_PMCR0_DPVV 0x00000800 +#define MXC_CCM_PMCR0_WFIM 0x00000400 +#define MXC_CCM_PMCR0_DRCE3 0x00000200 +#define MXC_CCM_PMCR0_DRCE2 0x00000100 +#define MXC_CCM_PMCR0_DRCE1 0x00000080 +#define MXC_CCM_PMCR0_DRCE0 0x00000040 +#define MXC_CCM_PMCR0_DCR 0x00000020 +#define MXC_CCM_PMCR0_DVFEN 0x00000010 +#define MXC_CCM_PMCR0_PTVAIM 0x00000008 +#define MXC_CCM_PMCR0_PTVAI_OFFSET 1 +#define MXC_CCM_PMCR0_PTVAI_MASK (0x3 << 1) +#define MXC_CCM_PMCR0_DPTEN 0x00000001 + +#define MXC_CCM_PMCR1_DVGP_OFFSET 0 +#define MXC_CCM_PMCR1_DVGP_MASK (0xF) + +#define MXC_CCM_PMCR1_PLLRDIS (0x1 << 7) +#define MXC_CCM_PMCR1_EMIRQ_EN (0x1 << 8) + +#define MXC_CCM_DCVR_ULV_MASK (0x3FF << 22) +#define MXC_CCM_DCVR_ULV_OFFSET 22 +#define MXC_CCM_DCVR_LLV_MASK (0x3FF << 12) +#define MXC_CCM_DCVR_LLV_OFFSET 12 +#define MXC_CCM_DCVR_ELV_MASK (0x3FF << 2) +#define MXC_CCM_DCVR_ELV_OFFSET 2 + +#define MXC_CCM_PDR2_MST2_PDF_MASK (0x3F << 7) +#define MXC_CCM_PDR2_MST2_PDF_OFFSET 7 +#define MXC_CCM_PDR2_MST1_PDF_MASK 0x3F +#define MXC_CCM_PDR2_MST1_PDF_OFFSET 0 + +#define MXC_CCM_COSR_CLKOSEL_MASK 0x0F +#define MXC_CCM_COSR_CLKOSEL_OFFSET 0 +#define MXC_CCM_COSR_CLKOUTDIV_MASK (0x07 << 6) +#define MXC_CCM_COSR_CLKOUTDIV_OFFSET 6 +#define MXC_CCM_COSR_CLKOEN (1 << 9) + +/* + * PMCR0 register offsets + */ +#define MXC_CCM_PMCR0_LBFL_OFFSET 20 +#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30 +#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31 + +#endif /* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */ diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h index 23b4350edbd..c6d4aa36063 100644 --- a/include/asm-arm/arch-mxc/common.h +++ b/include/asm-arm/arch-mxc/common.h @@ -16,5 +16,6 @@ struct sys_timer; extern void mxc_map_io(void); extern void mxc_init_irq(void); extern struct sys_timer mxc_timer; +extern int mxc_clocks_init(unsigned long fref); #endif -- cgit v1.2.3-70-g09d2 From e3d13ff4b9d3b05d7a969153e2c049548e25deea Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:48 +0200 Subject: mxc: add MX3 support for i.MX internal UART driver This patch adds MX3 support for the i.MX internal uart driver. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/devices.c | 153 ++++++++++++++++++++++++++++++++++++ drivers/serial/Kconfig | 2 +- drivers/serial/imx.c | 100 ++++++++++++++++++----- include/asm-arm/arch-mxc/imx-uart.h | 32 ++++++++ 5 files changed, 267 insertions(+), 22 deletions(-) create mode 100644 arch/arm/mach-mx3/devices.c create mode 100644 include/asm-arm/arch-mxc/imx-uart.h (limited to 'include/asm-arm') diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index febb37f2393..a788cb0b793 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o clock.o +obj-y := mm.o time.o clock.o devices.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c new file mode 100644 index 00000000000..1bc6d23a1d5 --- /dev/null +++ b/arch/arm/mach-mx3/devices.c @@ -0,0 +1,153 @@ +/* + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Sascha Hauer, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +static struct resource uart0[] = { + { + .start = UART1_BASE_ADDR, + .end = UART1_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART1, + .end = MXC_INT_UART1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device0 = { + .name = "imx-uart", + .id = 0, + .resource = uart0, + .num_resources = ARRAY_SIZE(uart0), +}; + +static struct resource uart1[] = { + { + .start = UART2_BASE_ADDR, + .end = UART2_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART2, + .end = MXC_INT_UART2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device1 = { + .name = "imx-uart", + .id = 1, + .resource = uart1, + .num_resources = ARRAY_SIZE(uart1), +}; + +static struct resource uart2[] = { + { + .start = UART3_BASE_ADDR, + .end = UART3_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART3, + .end = MXC_INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device2 = { + .name = "imx-uart", + .id = 2, + .resource = uart2, + .num_resources = ARRAY_SIZE(uart2), +}; + +static struct resource uart3[] = { + { + .start = UART4_BASE_ADDR, + .end = UART4_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART4, + .end = MXC_INT_UART4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device3 = { + .name = "imx-uart", + .id = 3, + .resource = uart3, + .num_resources = ARRAY_SIZE(uart3), +}; + +static struct resource uart4[] = { + { + .start = UART5_BASE_ADDR, + .end = UART5_BASE_ADDR + 0x0B5, + .flags = IORESOURCE_MEM, + }, { + .start = MXC_INT_UART5, + .end = MXC_INT_UART5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_uart_device4 = { + .name = "imx-uart", + .id = 4, + .resource = uart4, + .num_resources = ARRAY_SIZE(uart4), +}; + +/* + * Register only those UARTs that physically exist + */ +int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata) +{ + switch (uart_no) { + case 0: + mxc_uart_device0.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device0); + break; + case 1: + mxc_uart_device1.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device1); + break; + case 2: + mxc_uart_device2.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device2); + break; + case 3: + mxc_uart_device3.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device3); + break; + case 4: + mxc_uart_device4.dev.platform_data = pdata; + platform_device_register(&mxc_uart_device4); + break; + default: + return -ENODEV; + } + + return 0; +} + diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 9bc42763623..0843c540068 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -753,7 +753,7 @@ config BFIN_UART3_CTSRTS config SERIAL_IMX bool "IMX serial port support" - depends on ARM && ARCH_IMX + depends on ARM && (ARCH_IMX || ARCH_MXC) select SERIAL_CORE help If you have a machine based on a Motorola IMX CPU you diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 9e2162ebf1b..549440b098b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -62,6 +62,11 @@ #define UBIR 0xa4 /* BRM Incremental Register */ #define UBMR 0xa8 /* BRM Modulator Register */ #define UBRC 0xac /* Baud Rate Count Register */ +#ifdef CONFIG_ARCH_MX3 +#define ONEMS 0xb0 /* One Millisecond register */ +#define UTS 0xb4 /* UART Test Register */ +#endif +#ifdef CONFIG_ARCH_IMX #define BIPR1 0xb0 /* Incremental Preset Register 1 */ #define BIPR2 0xb4 /* Incremental Preset Register 2 */ #define BIPR3 0xb8 /* Incremental Preset Register 3 */ @@ -71,6 +76,7 @@ #define BMPR3 0xc8 /* BRM Modulator Register 3 */ #define BMPR4 0xcc /* BRM Modulator Register 4 */ #define UTS 0xd0 /* UART Test Register */ +#endif /* UART Control Register Bit Fields.*/ #define URXD_CHARRDY (1<<15) @@ -90,7 +96,12 @@ #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ #define UCR1_SNDBRK (1<<4) /* Send break */ #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ +#ifdef CONFIG_ARCH_IMX #define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ +#endif +#ifdef CONFIG_ARCH_MX3 +#define UCR1_UARTCLKEN (0) /* not present on mx2/mx3 */ +#endif #define UCR1_DOZE (1<<1) /* Doze */ #define UCR1_UARTEN (1<<0) /* UART enabled */ #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ @@ -164,8 +175,19 @@ #define UTS_SOFTRST (1<<0) /* Software reset */ /* We've been assigned a range on the "Low-density serial ports" major */ +#ifdef CONFIG_ARCH_IMX #define SERIAL_IMX_MAJOR 204 #define MINOR_START 41 +#define DEV_NAME "ttySMX" +#define MAX_INTERNAL_IRQ IMX_IRQS +#endif + +#ifdef CONFIG_ARCH_MX3 +#define SERIAL_IMX_MAJOR 207 +#define MINOR_START 16 +#define DEV_NAME "ttymxc" +#define MAX_INTERNAL_IRQ MXC_MAX_INT_LINES +#endif /* * This determines how often we check the modem status signals @@ -409,6 +431,26 @@ out: return IRQ_HANDLED; } +static irqreturn_t imx_int(int irq, void *dev_id) +{ + struct imx_port *sport = dev_id; + unsigned int sts; + + sts = readl(sport->port.membase + USR1); + + if (sts & USR1_RRDY) + imx_rxint(irq, dev_id); + + if (sts & USR1_TRDY && + readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) + imx_txint(irq, dev_id); + + if (sts & USR1_RTSS) + imx_rtsint(irq, dev_id); + + return IRQ_HANDLED; +} + /* * Return TIOCSER_TEMT when transmitter is not busy. */ @@ -514,21 +556,34 @@ static int imx_startup(struct uart_port *port) writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); /* - * Allocate the IRQ + * Allocate the IRQ(s) i.MX1 has three interrupts whereas later + * chips only have one interrupt. */ - retval = request_irq(sport->rxirq, imx_rxint, 0, - DRIVER_NAME, sport); - if (retval) goto error_out1; - - retval = request_irq(sport->txirq, imx_txint, 0, - DRIVER_NAME, sport); - if (retval) goto error_out2; - - retval = request_irq(sport->rtsirq, imx_rtsint, - (sport->rtsirq < IMX_IRQS) ? 0 : + if (sport->txirq > 0) { + retval = request_irq(sport->rxirq, imx_rxint, 0, + DRIVER_NAME, sport); + if (retval) + goto error_out1; + + retval = request_irq(sport->txirq, imx_txint, 0, + DRIVER_NAME, sport); + if (retval) + goto error_out2; + + retval = request_irq(sport->rtsirq, imx_rtsint, + (sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 : IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - DRIVER_NAME, sport); - if (retval) goto error_out3; + DRIVER_NAME, sport); + if (retval) + goto error_out3; + } else { + retval = request_irq(sport->port.irq, imx_int, 0, + DRIVER_NAME, sport); + if (retval) { + free_irq(sport->port.irq, sport); + goto error_out1; + } + } /* * Finally, clear and enable interrupts @@ -553,9 +608,11 @@ static int imx_startup(struct uart_port *port) return 0; error_out3: - free_irq(sport->txirq, sport); + if (sport->txirq) + free_irq(sport->txirq, sport); error_out2: - free_irq(sport->rxirq, sport); + if (sport->rxirq) + free_irq(sport->rxirq, sport); error_out1: return retval; } @@ -573,9 +630,12 @@ static void imx_shutdown(struct uart_port *port) /* * Free the interrupts */ - free_irq(sport->rtsirq, sport); - free_irq(sport->txirq, sport); - free_irq(sport->rxirq, sport); + if (sport->txirq > 0) { + free_irq(sport->rtsirq, sport); + free_irq(sport->txirq, sport); + free_irq(sport->rxirq, sport); + } else + free_irq(sport->port.irq, sport); /* * Disable all interrupts, port and break condition. @@ -973,7 +1033,7 @@ imx_console_setup(struct console *co, char *options) static struct uart_driver imx_reg; static struct console imx_console = { - .name = "ttySMX", + .name = DEV_NAME, .write = imx_console_write, .device = uart_console_device, .setup = imx_console_setup, @@ -990,7 +1050,7 @@ static struct console imx_console = { static struct uart_driver imx_reg = { .owner = THIS_MODULE, .driver_name = DRIVER_NAME, - .dev_name = "ttySMX", + .dev_name = DEV_NAME, .major = SERIAL_IMX_MAJOR, .minor = MINOR_START, .nr = ARRAY_SIZE(imx_ports), diff --git a/include/asm-arm/arch-mxc/imx-uart.h b/include/asm-arm/arch-mxc/imx-uart.h new file mode 100644 index 00000000000..83fb72c4048 --- /dev/null +++ b/include/asm-arm/arch-mxc/imx-uart.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 by Sascha Hauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef ASMARM_ARCH_UART_H +#define ASMARM_ARCH_UART_H + +#define IMXUART_HAVE_RTSCTS (1<<0) + +struct imxuart_platform_data { + int (*init)(struct platform_device *pdev); + int (*exit)(struct platform_device *pdev); + unsigned int flags; +}; + +int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata); + +#endif -- cgit v1.2.3-70-g09d2 From 07bd1a6cc7cbb3f373fbe49b204c6cde5e9155fc Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:49 +0200 Subject: MXC arch: Add gpio support for the whole platform This patch bases on the one from Daniel Mack. The most important change to Daniel's patch is to be more generic. This gpio routine supports at least the i.MX27 and i.MX31 processors. Signed-off-by: Juergen Beisert Acked-by: Daniel Mack --- arch/arm/Kconfig | 2 + arch/arm/mach-mx3/devices.c | 27 ++++ arch/arm/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/gpio.c | 253 ++++++++++++++++++++++++++++++++++++++ arch/arm/plat-mxc/irq.c | 3 + include/asm-arm/arch-mxc/common.h | 1 + include/asm-arm/arch-mxc/gpio.h | 42 +++++++ include/asm-arm/arch-mxc/mx31.h | 19 +++ 8 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 arch/arm/plat-mxc/gpio.c create mode 100644 include/asm-arm/arch-mxc/gpio.h (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..5c8c1a89be7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -368,6 +368,8 @@ config ARCH_NS9XXX config ARCH_MXC bool "Freescale MXC/iMX-based" select ARCH_MTD_XIP + select GENERIC_GPIO + select HAVE_GPIO_LIB help Support for Freescale MXC/iMX-based family of processors diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 1bc6d23a1d5..5c0320fce5b 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -151,3 +152,29 @@ int __init imx_init_uart(int uart_no, struct imxuart_platform_data *pdata) return 0; } +/* GPIO port description */ +static struct mxc_gpio_port imx_gpio_ports[] = { + [0] = { + .chip.label = "gpio-0", + .base = IO_ADDRESS(GPIO1_BASE_ADDR), + .irq = MXC_INT_GPIO1, + .virtual_irq_start = MXC_GPIO_INT_BASE + }, + [1] = { + .chip.label = "gpio-1", + .base = IO_ADDRESS(GPIO2_BASE_ADDR), + .irq = MXC_INT_GPIO2, + .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN + }, + [2] = { + .chip.label = "gpio-2", + .base = IO_ADDRESS(GPIO3_BASE_ADDR), + .irq = MXC_INT_GPIO3, + .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2 + } +}; + +int __init mxc_register_gpios(void) +{ + return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); +} diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 3eb181cb7af..66272a6fc32 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,4 +3,4 @@ # # Common support -obj-y := irq.o clock.o +obj-y := irq.o clock.o gpio.o diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c new file mode 100644 index 00000000000..4a7736717d8 --- /dev/null +++ b/arch/arm/plat-mxc/gpio.c @@ -0,0 +1,253 @@ +/* + * MXC GPIO support. (c) 2008 Daniel Mack + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * Based on code from Freescale, + * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include + +static struct mxc_gpio_port *mxc_gpio_ports; +static int gpio_table_size; + +/* Note: This driver assumes 32 GPIOs are handled in one register */ + +static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) +{ + __raw_writel(1 << index, port->base + GPIO_ISR); +} + +static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, + int enable) +{ + u32 l; + + l = __raw_readl(port->base + GPIO_IMR); + l = (l & (~(1 << index))) | (!!enable << index); + __raw_writel(l, port->base + GPIO_IMR); +} + +static void gpio_ack_irq(u32 irq) +{ + u32 gpio = irq_to_gpio(irq); + _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f); +} + +static void gpio_mask_irq(u32 irq) +{ + u32 gpio = irq_to_gpio(irq); + _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0); +} + +static void gpio_unmask_irq(u32 irq) +{ + u32 gpio = irq_to_gpio(irq); + _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1); +} + +static int gpio_set_irq_type(u32 irq, u32 type) +{ + u32 gpio = irq_to_gpio(irq); + struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; + u32 bit, val; + int edge; + void __iomem *reg = port->base; + + switch (type) { + case IRQT_RISING: + edge = GPIO_INT_RISE_EDGE; + break; + case IRQT_FALLING: + edge = GPIO_INT_FALL_EDGE; + break; + case IRQT_LOW: + edge = GPIO_INT_LOW_LEV; + break; + case IRQT_HIGH: + edge = GPIO_INT_HIGH_LEV; + break; + default: /* this includes IRQT_BOTHEDGE */ + return -EINVAL; + } + + reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ + bit = gpio & 0xf; + val = __raw_readl(reg) & ~(0x3 << (bit << 1)); + __raw_writel(val | (edge << (bit << 1)), reg); + _clear_gpio_irqstatus(port, gpio & 0x1f); + + return 0; +} + +/* handle n interrupts in one status register */ +static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) +{ + u32 gpio_irq_no; + + gpio_irq_no = port->virtual_irq_start; + for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { + + if ((irq_stat & 1) == 0) + continue; + + BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); + irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, + &irq_desc[gpio_irq_no]); + } +} + +#ifdef CONFIG_ARCH_MX3 +/* MX3 has one interrupt *per* gpio port */ +static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) +{ + u32 irq_stat; + struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); + + irq_stat = __raw_readl(port->base + GPIO_ISR) & + __raw_readl(port->base + GPIO_IMR); + BUG_ON(!irq_stat); + mxc_gpio_irq_handler(port, irq_stat); +} +#endif + +#ifdef CONFIG_ARCH_MX2 +/* MX2 has one interrupt *for all* gpio ports */ +static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) +{ + int i; + u32 irq_msk, irq_stat; + struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); + + /* walk through all interrupt status registers */ + for (i = 0; i < gpio_table_size; i++) { + irq_msk = __raw_readl(port[i].base + GPIO_IMR); + if (!irq_msk) + continue; + + irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk; + if (irq_stat) + mxc_gpio_irq_handler(&port[i], irq_stat); + } +} +#endif + +static struct irq_chip gpio_irq_chip = { + .ack = gpio_ack_irq, + .mask = gpio_mask_irq, + .unmask = gpio_unmask_irq, + .set_type = gpio_set_irq_type, +}; + +static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, + int dir) +{ + struct mxc_gpio_port *port = + container_of(chip, struct mxc_gpio_port, chip); + u32 l; + + l = __raw_readl(port->base + GPIO_GDIR); + if (dir) + l |= 1 << offset; + else + l &= ~(1 << offset); + __raw_writel(l, port->base + GPIO_GDIR); +} + +static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct mxc_gpio_port *port = + container_of(chip, struct mxc_gpio_port, chip); + void __iomem *reg = port->base + GPIO_DR; + u32 l; + + l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); + __raw_writel(l, reg); +} + +static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct mxc_gpio_port *port = + container_of(chip, struct mxc_gpio_port, chip); + + return (__raw_readl(port->base + GPIO_DR) >> offset) & 1; +} + +static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + _set_gpio_direction(chip, offset, 0); + return 0; +} + +static int mxc_gpio_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + _set_gpio_direction(chip, offset, 1); + mxc_gpio_set(chip, offset, value); + return 0; +} + +int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) +{ + int i, j; + + /* save for local usage */ + mxc_gpio_ports = port; + gpio_table_size = cnt; + + printk(KERN_INFO "MXC GPIO hardware\n"); + + for (i = 0; i < cnt; i++) { + /* disable the interrupt and clear the status */ + __raw_writel(0, port[i].base + GPIO_IMR); + __raw_writel(~0, port[i].base + GPIO_ISR); + for (j = port[i].virtual_irq_start; + j < port[i].virtual_irq_start + 32; j++) { + set_irq_chip(j, &gpio_irq_chip); + set_irq_handler(j, handle_edge_irq); + set_irq_flags(j, IRQF_VALID); + } + + /* register gpio chip */ + port[i].chip.direction_input = mxc_gpio_direction_input; + port[i].chip.direction_output = mxc_gpio_direction_output; + port[i].chip.get = mxc_gpio_get; + port[i].chip.set = mxc_gpio_set; + port[i].chip.base = i * 32; + port[i].chip.ngpio = 32; + + /* its a serious configuration bug when it fails */ + BUG_ON( gpiochip_add(&port[i].chip) < 0 ); + +#ifdef CONFIG_ARCH_MX3 + /* setup one handler for each entry */ + set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler); + set_irq_data(port[i].irq, &port[i]); +#endif + } + +#ifdef CONFIG_ARCH_MX2 + /* setup one handler for all GPIO interrupts */ + set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler); + set_irq_data(port[0].irq, port); +#endif + return 0; +} diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c index 2ad5a6917b3..88f0cfababd 100644 --- a/arch/arm/plat-mxc/irq.c +++ b/arch/arm/plat-mxc/irq.c @@ -71,5 +71,8 @@ void __init mxc_init_irq(void) reg |= (0xF << 28); __raw_writel(reg, AVIC_NIPRIORITY6); + /* init architectures chained interrupt handler */ + mxc_register_gpios(); + printk(KERN_INFO "MXC IRQ initialized\n"); } diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h index c6d4aa36063..8774783ed98 100644 --- a/include/asm-arm/arch-mxc/common.h +++ b/include/asm-arm/arch-mxc/common.h @@ -17,5 +17,6 @@ extern void mxc_map_io(void); extern void mxc_init_irq(void); extern struct sys_timer mxc_timer; extern int mxc_clocks_init(unsigned long fref); +extern int mxc_register_gpios(void); #endif diff --git a/include/asm-arm/arch-mxc/gpio.h b/include/asm-arm/arch-mxc/gpio.h new file mode 100644 index 00000000000..d393e15f5a6 --- /dev/null +++ b/include/asm-arm/arch-mxc/gpio.h @@ -0,0 +1,42 @@ +/* + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_GPIO_H__ +#define __ASM_ARCH_MXC_GPIO_H__ + +#include +#include + +/* use gpiolib dispatchers */ +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep + +#define gpio_to_irq(gpio) (MXC_MAX_INT_LINES + (gpio)) +#define irq_to_gpio(irq) ((irq) - MXC_MAX_INT_LINES) + +struct mxc_gpio_port { + void __iomem *base; + int irq; + int virtual_irq_start; + struct gpio_chip chip; +}; + +int mxc_gpio_init(struct mxc_gpio_port*, int); + +#endif diff --git a/include/asm-arm/arch-mxc/mx31.h b/include/asm-arm/arch-mxc/mx31.h index 36a1af495bb..98e6a4cd1ea 100644 --- a/include/asm-arm/arch-mxc/mx31.h +++ b/include/asm-arm/arch-mxc/mx31.h @@ -347,6 +347,25 @@ #define SYSTEM_REV_MIN CHIP_REV_1_0 #define SYSTEM_REV_NUM 3 +/* gpio and gpio based interrupt handling */ +#define GPIO_DR 0x00 +#define GPIO_GDIR 0x04 +#define GPIO_PSR 0x08 +#define GPIO_ICR1 0x0C +#define GPIO_ICR2 0x10 +#define GPIO_IMR 0x14 +#define GPIO_ISR 0x18 +#define GPIO_INT_LOW_LEV 0x0 +#define GPIO_INT_HIGH_LEV 0x1 +#define GPIO_INT_RISE_EDGE 0x2 +#define GPIO_INT_FALL_EDGE 0x3 +#define GPIO_INT_NONE 0x4 + +/* Mandatory defines used globally */ + +/* this CPU supports up to 96 GPIOs */ +#define ARCH_NR_GPIOS 96 + #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) /* this is a i.MX31 CPU */ -- cgit v1.2.3-70-g09d2 From 90292ea60f1c730efb9fea02b2e12676da89ebef Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:50 +0200 Subject: MXC: add io multiplexing functions for mx3 This patch adds functions to use the io multiplexer on mx3 platforms. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/iomux.c | 111 ++++++++ include/asm-arm/arch-mxc/iomux-mx3.h | 501 +++++++++++++++++++++++++++++++++++ 3 files changed, 613 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-mx3/iomux.c create mode 100644 include/asm-arm/arch-mxc/iomux-mx3.h (limited to 'include/asm-arm') diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index a788cb0b793..68f062b70d3 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o clock.o devices.o +obj-y := mm.o time.o clock.o devices.o iomux.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c new file mode 100644 index 00000000000..adc51feefc1 --- /dev/null +++ b/arch/arm/mach-mx3/iomux.c @@ -0,0 +1,111 @@ +/* + * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * IOMUX register (base) addresses + */ +#define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR) +#define IOMUXINT_OBS1 (IOMUX_BASE + 0x000) +#define IOMUXINT_OBS2 (IOMUX_BASE + 0x004) +#define IOMUXGPR (IOMUX_BASE + 0x008) +#define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C) +#define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154) + +static DEFINE_SPINLOCK(gpio_mux_lock); + +#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) +/* + * set the mode for a IOMUX pin. + */ +int mxc_iomux_mode(unsigned int pin_mode) +{ + u32 reg, field, l, mode, ret = 0; + + reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK); + field = pin_mode & 0x3; + mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; + + pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n", + __func__, (pin_mode & IOMUX_REG_MASK), field, mode); + + spin_lock(&gpio_mux_lock); + + l = __raw_readl(reg); + l &= ~(0xff << (field * 8)); + l |= mode << (field * 8); + __raw_writel(l, reg); + + spin_unlock(&gpio_mux_lock); + + return ret; +} +EXPORT_SYMBOL(mxc_iomux_mode); + +/* + * This function configures the pad value for a IOMUX pin. + */ +void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) +{ + u32 reg, field, l; + + reg = IOMUXSW_PAD_CTL + (pin + 2) / 3; + field = (pin + 2) % 3; + + pr_debug("%s: reg offset = 0x%x field = %d\n", + __func__, (pin + 2) / 3, field); + + spin_lock(&gpio_mux_lock); + + l = __raw_readl(reg); + l &= ~(0x1ff << (field * 9)); + l |= config << (field * 9); + __raw_writel(l, reg); + + spin_unlock(&gpio_mux_lock); +} +EXPORT_SYMBOL(mxc_iomux_set_pad); + +/* + * This function enables/disables the general purpose function for a particular + * signal. + */ +void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) +{ + u32 l; + + spin_lock(&gpio_mux_lock); + l = __raw_readl(IOMUXGPR); + if (en) + l |= gp; + else + l &= ~gp; + + __raw_writel(l, IOMUXGPR); + spin_unlock(&gpio_mux_lock); +} +EXPORT_SYMBOL(mxc_iomux_set_gpr); + diff --git a/include/asm-arm/arch-mxc/iomux-mx3.h b/include/asm-arm/arch-mxc/iomux-mx3.h new file mode 100644 index 00000000000..7509e7692f0 --- /dev/null +++ b/include/asm-arm/arch-mxc/iomux-mx3.h @@ -0,0 +1,501 @@ +/* + * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __MACH_MX31_IOMUX_H__ +#define __MACH_MX31_IOMUX_H__ + +#include + +/* + * various IOMUX output functions + */ + +#define IOMUX_OCONFIG_GPIO (0 << 4) /* used as GPIO */ +#define IOMUX_OCONFIG_FUNC (1 << 4) /* used as function */ +#define IOMUX_OCONFIG_ALT1 (2 << 4) /* used as alternate function 1 */ +#define IOMUX_OCONFIG_ALT2 (3 << 4) /* used as alternate function 2 */ +#define IOMUX_OCONFIG_ALT3 (4 << 4) /* used as alternate function 3 */ +#define IOMUX_OCONFIG_ALT4 (5 << 4) /* used as alternate function 4 */ +#define IOMUX_OCONFIG_ALT5 (6 << 4) /* used as alternate function 5 */ +#define IOMUX_OCONFIG_ALT6 (7 << 4) /* used as alternate function 6 */ +#define IOMUX_ICONFIG_NONE 0 /* not configured for input */ +#define IOMUX_ICONFIG_GPIO 1 /* used as GPIO */ +#define IOMUX_ICONFIG_FUNC 2 /* used as function */ +#define IOMUX_ICONFIG_ALT1 4 /* used as alternate function 1 */ +#define IOMUX_ICONFIG_ALT2 8 /* used as alternate function 2 */ + +#define IOMUX_CONFIG_GPIO (IOMUX_OCONFIG_GPIO | IOMUX_ICONFIG_GPIO) +#define IOMUX_CONFIG_FUNC (IOMUX_OCONFIG_FUNC | IOMUX_ICONFIG_FUNC) +#define IOMUX_CONFIG_ALT1 (IOMUX_OCONFIG_ALT1 | IOMUX_ICONFIG_ALT1) +#define IOMUX_CONFIG_ALT2 (IOMUX_OCONFIG_ALT2 | IOMUX_ICONFIG_ALT2) + +/* + * various IOMUX pad functions + */ +enum iomux_pad_config { + PAD_CTL_NOLOOPBACK = 0x0 << 9, + PAD_CTL_LOOPBACK = 0x1 << 9, + PAD_CTL_PKE_NONE = 0x0 << 8, + PAD_CTL_PKE_ENABLE = 0x1 << 8, + PAD_CTL_PUE_KEEPER = 0x0 << 7, + PAD_CTL_PUE_PUD = 0x1 << 7, + PAD_CTL_100K_PD = 0x0 << 5, + PAD_CTL_100K_PU = 0x1 << 5, + PAD_CTL_47K_PU = 0x2 << 5, + PAD_CTL_22K_PU = 0x3 << 5, + PAD_CTL_HYS_CMOS = 0x0 << 4, + PAD_CTL_HYS_SCHMITZ = 0x1 << 4, + PAD_CTL_ODE_CMOS = 0x0 << 3, + PAD_CTL_ODE_OpenDrain = 0x1 << 3, + PAD_CTL_DRV_NORMAL = 0x0 << 1, + PAD_CTL_DRV_HIGH = 0x1 << 1, + PAD_CTL_DRV_MAX = 0x2 << 1, + PAD_CTL_SRE_SLOW = 0x0 << 0, + PAD_CTL_SRE_FAST = 0x1 << 0 +}; + +/* + * various IOMUX general purpose functions + */ +enum iomux_gp_func { + MUX_PGP_FIRI = 1 << 0, + MUX_DDR_MODE = 1 << 1, + MUX_PGP_CSPI_BB = 1 << 2, + MUX_PGP_ATA_1 = 1 << 3, + MUX_PGP_ATA_2 = 1 << 4, + MUX_PGP_ATA_3 = 1 << 5, + MUX_PGP_ATA_4 = 1 << 6, + MUX_PGP_ATA_5 = 1 << 7, + MUX_PGP_ATA_6 = 1 << 8, + MUX_PGP_ATA_7 = 1 << 9, + MUX_PGP_ATA_8 = 1 << 10, + MUX_PGP_UH2 = 1 << 11, + MUX_SDCTL_CSD0_SEL = 1 << 12, + MUX_SDCTL_CSD1_SEL = 1 << 13, + MUX_CSPI1_UART3 = 1 << 14, + MUX_EXTDMAREQ2_MBX_SEL = 1 << 15, + MUX_TAMPER_DETECT_EN = 1 << 16, + MUX_PGP_USB_4WIRE = 1 << 17, + MUX_PGB_USB_COMMON = 1 << 18, + MUX_SDHC_MEMSTICK1 = 1 << 19, + MUX_SDHC_MEMSTICK2 = 1 << 20, + MUX_PGP_SPLL_BYP = 1 << 21, + MUX_PGP_UPLL_BYP = 1 << 22, + MUX_PGP_MSHC1_CLK_SEL = 1 << 23, + MUX_PGP_MSHC2_CLK_SEL = 1 << 24, + MUX_CSPI3_UART5_SEL = 1 << 25, + MUX_PGP_ATA_9 = 1 << 26, + MUX_PGP_USB_SUSPEND = 1 << 27, + MUX_PGP_USB_OTG_LOOPBACK = 1 << 28, + MUX_PGP_USB_HS1_LOOPBACK = 1 << 29, + MUX_PGP_USB_HS2_LOOPBACK = 1 << 30, + MUX_CLKO_DDR_MODE = 1 << 31, +}; + +/* + * This function enables/disables the general purpose function for a particular + * signal. + */ +void iomux_config_gpr(enum iomux_gp_func , bool); + +/* + * set the mode for a IOMUX pin. + */ +int mxc_iomux_mode(unsigned int); + +/* + * This function enables/disables the general purpose function for a particular + * signal. + */ +void mxc_iomux_set_gpr(enum iomux_gp_func, bool); + +#define IOMUX_PADNUM_MASK 0x1ff +#define IOMUX_GPIONUM_SHIFT 9 +#define IOMUX_GPIONUM_MASK (0xff << IOMUX_GPIONUM_SHIFT) +#define IOMUX_MODE_SHIFT 17 +#define IOMUX_MODE_MASK (0xff << IOMUX_MODE_SHIFT) + +#define IOMUX_PIN(gpionum, padnum) \ + (((gpionum << IOMUX_GPIONUM_SHIFT) & IOMUX_GPIONUM_MASK) | \ + (padnum & IOMUX_PADNUM_MASK)) + +#define IOMUX_MODE(pin, mode) (pin | mode << IOMUX_MODE_SHIFT) + +#define IOMUX_TO_GPIO(iomux_pin) \ + ((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) +#define IOMUX_TO_IRQ(iomux_pin) \ + (((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) + \ + MXC_GPIO_INT_BASE) + +/* + * This enumeration is constructed based on the Section + * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated + * value is constructed based on the rules described above. + */ + +enum iomux_pins { + MX31_PIN_TTM_PAD = IOMUX_PIN(0xff, 0), + MX31_PIN_CSPI3_SPI_RDY = IOMUX_PIN(0xff, 1), + MX31_PIN_CSPI3_SCLK = IOMUX_PIN(0xff, 2), + MX31_PIN_CSPI3_MISO = IOMUX_PIN(0xff, 3), + MX31_PIN_CSPI3_MOSI = IOMUX_PIN(0xff, 4), + MX31_PIN_CLKSS = IOMUX_PIN(0xff, 5), + MX31_PIN_CE_CONTROL = IOMUX_PIN(0xff, 6), + MX31_PIN_ATA_RESET_B = IOMUX_PIN(95, 7), + MX31_PIN_ATA_DMACK = IOMUX_PIN(94, 8), + MX31_PIN_ATA_DIOW = IOMUX_PIN(93, 9), + MX31_PIN_ATA_DIOR = IOMUX_PIN(92, 10), + MX31_PIN_ATA_CS1 = IOMUX_PIN(91, 11), + MX31_PIN_ATA_CS0 = IOMUX_PIN(90, 12), + MX31_PIN_SD1_DATA3 = IOMUX_PIN(63, 13), + MX31_PIN_SD1_DATA2 = IOMUX_PIN(62, 14), + MX31_PIN_SD1_DATA1 = IOMUX_PIN(61, 15), + MX31_PIN_SD1_DATA0 = IOMUX_PIN(60, 16), + MX31_PIN_SD1_CLK = IOMUX_PIN(59, 17), + MX31_PIN_SD1_CMD = IOMUX_PIN(58, 18), + MX31_PIN_D3_SPL = IOMUX_PIN(0xff, 19), + MX31_PIN_D3_CLS = IOMUX_PIN(0xff, 20), + MX31_PIN_D3_REV = IOMUX_PIN(0xff, 21), + MX31_PIN_CONTRAST = IOMUX_PIN(0xff, 22), + MX31_PIN_VSYNC3 = IOMUX_PIN(0xff, 23), + MX31_PIN_READ = IOMUX_PIN(0xff, 24), + MX31_PIN_WRITE = IOMUX_PIN(0xff, 25), + MX31_PIN_PAR_RS = IOMUX_PIN(0xff, 26), + MX31_PIN_SER_RS = IOMUX_PIN(89, 27), + MX31_PIN_LCS1 = IOMUX_PIN(88, 28), + MX31_PIN_LCS0 = IOMUX_PIN(87, 29), + MX31_PIN_SD_D_CLK = IOMUX_PIN(86, 30), + MX31_PIN_SD_D_IO = IOMUX_PIN(85, 31), + MX31_PIN_SD_D_I = IOMUX_PIN(84, 32), + MX31_PIN_DRDY0 = IOMUX_PIN(0xff, 33), + MX31_PIN_FPSHIFT = IOMUX_PIN(0xff, 34), + MX31_PIN_HSYNC = IOMUX_PIN(0xff, 35), + MX31_PIN_VSYNC0 = IOMUX_PIN(0xff, 36), + MX31_PIN_LD17 = IOMUX_PIN(0xff, 37), + MX31_PIN_LD16 = IOMUX_PIN(0xff, 38), + MX31_PIN_LD15 = IOMUX_PIN(0xff, 39), + MX31_PIN_LD14 = IOMUX_PIN(0xff, 40), + MX31_PIN_LD13 = IOMUX_PIN(0xff, 41), + MX31_PIN_LD12 = IOMUX_PIN(0xff, 42), + MX31_PIN_LD11 = IOMUX_PIN(0xff, 43), + MX31_PIN_LD10 = IOMUX_PIN(0xff, 44), + MX31_PIN_LD9 = IOMUX_PIN(0xff, 45), + MX31_PIN_LD8 = IOMUX_PIN(0xff, 46), + MX31_PIN_LD7 = IOMUX_PIN(0xff, 47), + MX31_PIN_LD6 = IOMUX_PIN(0xff, 48), + MX31_PIN_LD5 = IOMUX_PIN(0xff, 49), + MX31_PIN_LD4 = IOMUX_PIN(0xff, 50), + MX31_PIN_LD3 = IOMUX_PIN(0xff, 51), + MX31_PIN_LD2 = IOMUX_PIN(0xff, 52), + MX31_PIN_LD1 = IOMUX_PIN(0xff, 53), + MX31_PIN_LD0 = IOMUX_PIN(0xff, 54), + MX31_PIN_USBH2_DATA1 = IOMUX_PIN(0xff, 55), + MX31_PIN_USBH2_DATA0 = IOMUX_PIN(0xff, 56), + MX31_PIN_USBH2_NXT = IOMUX_PIN(0xff, 57), + MX31_PIN_USBH2_STP = IOMUX_PIN(0xff, 58), + MX31_PIN_USBH2_DIR = IOMUX_PIN(0xff, 59), + MX31_PIN_USBH2_CLK = IOMUX_PIN(0xff, 60), + MX31_PIN_USBOTG_DATA7 = IOMUX_PIN(0xff, 61), + MX31_PIN_USBOTG_DATA6 = IOMUX_PIN(0xff, 62), + MX31_PIN_USBOTG_DATA5 = IOMUX_PIN(0xff, 63), + MX31_PIN_USBOTG_DATA4 = IOMUX_PIN(0xff, 64), + MX31_PIN_USBOTG_DATA3 = IOMUX_PIN(0xff, 65), + MX31_PIN_USBOTG_DATA2 = IOMUX_PIN(0xff, 66), + MX31_PIN_USBOTG_DATA1 = IOMUX_PIN(0xff, 67), + MX31_PIN_USBOTG_DATA0 = IOMUX_PIN(0xff, 68), + MX31_PIN_USBOTG_NXT = IOMUX_PIN(0xff, 69), + MX31_PIN_USBOTG_STP = IOMUX_PIN(0xff, 70), + MX31_PIN_USBOTG_DIR = IOMUX_PIN(0xff, 71), + MX31_PIN_USBOTG_CLK = IOMUX_PIN(0xff, 72), + MX31_PIN_USB_BYP = IOMUX_PIN(31, 73), + MX31_PIN_USB_OC = IOMUX_PIN(30, 74), + MX31_PIN_USB_PWR = IOMUX_PIN(29, 75), + MX31_PIN_SJC_MOD = IOMUX_PIN(0xff, 76), + MX31_PIN_DE_B = IOMUX_PIN(0xff, 77), + MX31_PIN_TRSTB = IOMUX_PIN(0xff, 78), + MX31_PIN_TDO = IOMUX_PIN(0xff, 79), + MX31_PIN_TDI = IOMUX_PIN(0xff, 80), + MX31_PIN_TMS = IOMUX_PIN(0xff, 81), + MX31_PIN_TCK = IOMUX_PIN(0xff, 82), + MX31_PIN_RTCK = IOMUX_PIN(0xff, 83), + MX31_PIN_KEY_COL7 = IOMUX_PIN(57, 84), + MX31_PIN_KEY_COL6 = IOMUX_PIN(56, 85), + MX31_PIN_KEY_COL5 = IOMUX_PIN(55, 86), + MX31_PIN_KEY_COL4 = IOMUX_PIN(54, 87), + MX31_PIN_KEY_COL3 = IOMUX_PIN(0xff, 88), + MX31_PIN_KEY_COL2 = IOMUX_PIN(0xff, 89), + MX31_PIN_KEY_COL1 = IOMUX_PIN(0xff, 90), + MX31_PIN_KEY_COL0 = IOMUX_PIN(0xff, 91), + MX31_PIN_KEY_ROW7 = IOMUX_PIN(53, 92), + MX31_PIN_KEY_ROW6 = IOMUX_PIN(52, 93), + MX31_PIN_KEY_ROW5 = IOMUX_PIN(51, 94), + MX31_PIN_KEY_ROW4 = IOMUX_PIN(50, 95), + MX31_PIN_KEY_ROW3 = IOMUX_PIN(0xff, 96), + MX31_PIN_KEY_ROW2 = IOMUX_PIN(0xff, 97), + MX31_PIN_KEY_ROW1 = IOMUX_PIN(0xff, 98), + MX31_PIN_KEY_ROW0 = IOMUX_PIN(0xff, 99), + MX31_PIN_BATT_LINE = IOMUX_PIN(49, 100), + MX31_PIN_CTS2 = IOMUX_PIN(0xff, 101), + MX31_PIN_RTS2 = IOMUX_PIN(0xff, 102), + MX31_PIN_TXD2 = IOMUX_PIN(28, 103), + MX31_PIN_RXD2 = IOMUX_PIN(27, 104), + MX31_PIN_DTR_DCE2 = IOMUX_PIN(48, 105), + MX31_PIN_DCD_DTE1 = IOMUX_PIN(47, 106), + MX31_PIN_RI_DTE1 = IOMUX_PIN(46, 107), + MX31_PIN_DSR_DTE1 = IOMUX_PIN(45, 108), + MX31_PIN_DTR_DTE1 = IOMUX_PIN(44, 109), + MX31_PIN_DCD_DCE1 = IOMUX_PIN(43, 110), + MX31_PIN_RI_DCE1 = IOMUX_PIN(42, 111), + MX31_PIN_DSR_DCE1 = IOMUX_PIN(41, 112), + MX31_PIN_DTR_DCE1 = IOMUX_PIN(40, 113), + MX31_PIN_CTS1 = IOMUX_PIN(39, 114), + MX31_PIN_RTS1 = IOMUX_PIN(38, 115), + MX31_PIN_TXD1 = IOMUX_PIN(37, 116), + MX31_PIN_RXD1 = IOMUX_PIN(36, 117), + MX31_PIN_CSPI2_SPI_RDY = IOMUX_PIN(0xff, 118), + MX31_PIN_CSPI2_SCLK = IOMUX_PIN(0xff, 119), + MX31_PIN_CSPI2_SS2 = IOMUX_PIN(0xff, 120), + MX31_PIN_CSPI2_SS1 = IOMUX_PIN(0xff, 121), + MX31_PIN_CSPI2_SS0 = IOMUX_PIN(0xff, 122), + MX31_PIN_CSPI2_MISO = IOMUX_PIN(0xff, 123), + MX31_PIN_CSPI2_MOSI = IOMUX_PIN(0xff, 124), + MX31_PIN_CSPI1_SPI_RDY = IOMUX_PIN(0xff, 125), + MX31_PIN_CSPI1_SCLK = IOMUX_PIN(0xff, 126), + MX31_PIN_CSPI1_SS2 = IOMUX_PIN(0xff, 127), + MX31_PIN_CSPI1_SS1 = IOMUX_PIN(0xff, 128), + MX31_PIN_CSPI1_SS0 = IOMUX_PIN(0xff, 129), + MX31_PIN_CSPI1_MISO = IOMUX_PIN(0xff, 130), + MX31_PIN_CSPI1_MOSI = IOMUX_PIN(0xff, 131), + MX31_PIN_SFS6 = IOMUX_PIN(26, 132), + MX31_PIN_SCK6 = IOMUX_PIN(25, 133), + MX31_PIN_SRXD6 = IOMUX_PIN(24, 134), + MX31_PIN_STXD6 = IOMUX_PIN(23, 135), + MX31_PIN_SFS5 = IOMUX_PIN(0xff, 136), + MX31_PIN_SCK5 = IOMUX_PIN(0xff, 137), + MX31_PIN_SRXD5 = IOMUX_PIN(22, 138), + MX31_PIN_STXD5 = IOMUX_PIN(21, 139), + MX31_PIN_SFS4 = IOMUX_PIN(0xff, 140), + MX31_PIN_SCK4 = IOMUX_PIN(0xff, 141), + MX31_PIN_SRXD4 = IOMUX_PIN(20, 142), + MX31_PIN_STXD4 = IOMUX_PIN(19, 143), + MX31_PIN_SFS3 = IOMUX_PIN(0xff, 144), + MX31_PIN_SCK3 = IOMUX_PIN(0xff, 145), + MX31_PIN_SRXD3 = IOMUX_PIN(18, 146), + MX31_PIN_STXD3 = IOMUX_PIN(17, 147), + MX31_PIN_I2C_DAT = IOMUX_PIN(0xff, 148), + MX31_PIN_I2C_CLK = IOMUX_PIN(0xff, 149), + MX31_PIN_CSI_PIXCLK = IOMUX_PIN(83, 150), + MX31_PIN_CSI_HSYNC = IOMUX_PIN(82, 151), + MX31_PIN_CSI_VSYNC = IOMUX_PIN(81, 152), + MX31_PIN_CSI_MCLK = IOMUX_PIN(80, 153), + MX31_PIN_CSI_D15 = IOMUX_PIN(79, 154), + MX31_PIN_CSI_D14 = IOMUX_PIN(78, 155), + MX31_PIN_CSI_D13 = IOMUX_PIN(77, 156), + MX31_PIN_CSI_D12 = IOMUX_PIN(76, 157), + MX31_PIN_CSI_D11 = IOMUX_PIN(75, 158), + MX31_PIN_CSI_D10 = IOMUX_PIN(74, 159), + MX31_PIN_CSI_D9 = IOMUX_PIN(73, 160), + MX31_PIN_CSI_D8 = IOMUX_PIN(72, 161), + MX31_PIN_CSI_D7 = IOMUX_PIN(71, 162), + MX31_PIN_CSI_D6 = IOMUX_PIN(70, 163), + MX31_PIN_CSI_D5 = IOMUX_PIN(69, 164), + MX31_PIN_CSI_D4 = IOMUX_PIN(68, 165), + MX31_PIN_M_GRANT = IOMUX_PIN(0xff, 166), + MX31_PIN_M_REQUEST = IOMUX_PIN(0xff, 167), + MX31_PIN_PC_POE = IOMUX_PIN(0xff, 168), + MX31_PIN_PC_RW_B = IOMUX_PIN(0xff, 169), + MX31_PIN_IOIS16 = IOMUX_PIN(0xff, 170), + MX31_PIN_PC_RST = IOMUX_PIN(0xff, 171), + MX31_PIN_PC_BVD2 = IOMUX_PIN(0xff, 172), + MX31_PIN_PC_BVD1 = IOMUX_PIN(0xff, 173), + MX31_PIN_PC_VS2 = IOMUX_PIN(0xff, 174), + MX31_PIN_PC_VS1 = IOMUX_PIN(0xff, 175), + MX31_PIN_PC_PWRON = IOMUX_PIN(0xff, 176), + MX31_PIN_PC_READY = IOMUX_PIN(0xff, 177), + MX31_PIN_PC_WAIT_B = IOMUX_PIN(0xff, 178), + MX31_PIN_PC_CD2_B = IOMUX_PIN(0xff, 179), + MX31_PIN_PC_CD1_B = IOMUX_PIN(0xff, 180), + MX31_PIN_D0 = IOMUX_PIN(0xff, 181), + MX31_PIN_D1 = IOMUX_PIN(0xff, 182), + MX31_PIN_D2 = IOMUX_PIN(0xff, 183), + MX31_PIN_D3 = IOMUX_PIN(0xff, 184), + MX31_PIN_D4 = IOMUX_PIN(0xff, 185), + MX31_PIN_D5 = IOMUX_PIN(0xff, 186), + MX31_PIN_D6 = IOMUX_PIN(0xff, 187), + MX31_PIN_D7 = IOMUX_PIN(0xff, 188), + MX31_PIN_D8 = IOMUX_PIN(0xff, 189), + MX31_PIN_D9 = IOMUX_PIN(0xff, 190), + MX31_PIN_D10 = IOMUX_PIN(0xff, 191), + MX31_PIN_D11 = IOMUX_PIN(0xff, 192), + MX31_PIN_D12 = IOMUX_PIN(0xff, 193), + MX31_PIN_D13 = IOMUX_PIN(0xff, 194), + MX31_PIN_D14 = IOMUX_PIN(0xff, 195), + MX31_PIN_D15 = IOMUX_PIN(0xff, 196), + MX31_PIN_NFRB = IOMUX_PIN(16, 197), + MX31_PIN_NFCE_B = IOMUX_PIN(15, 198), + MX31_PIN_NFWP_B = IOMUX_PIN(14, 199), + MX31_PIN_NFCLE = IOMUX_PIN(13, 200), + MX31_PIN_NFALE = IOMUX_PIN(12, 201), + MX31_PIN_NFRE_B = IOMUX_PIN(11, 202), + MX31_PIN_NFWE_B = IOMUX_PIN(10, 203), + MX31_PIN_SDQS3 = IOMUX_PIN(0xff, 204), + MX31_PIN_SDQS2 = IOMUX_PIN(0xff, 205), + MX31_PIN_SDQS1 = IOMUX_PIN(0xff, 206), + MX31_PIN_SDQS0 = IOMUX_PIN(0xff, 207), + MX31_PIN_SDCLK_B = IOMUX_PIN(0xff, 208), + MX31_PIN_SDCLK = IOMUX_PIN(0xff, 209), + MX31_PIN_SDCKE1 = IOMUX_PIN(0xff, 210), + MX31_PIN_SDCKE0 = IOMUX_PIN(0xff, 211), + MX31_PIN_SDWE = IOMUX_PIN(0xff, 212), + MX31_PIN_CAS = IOMUX_PIN(0xff, 213), + MX31_PIN_RAS = IOMUX_PIN(0xff, 214), + MX31_PIN_RW = IOMUX_PIN(0xff, 215), + MX31_PIN_BCLK = IOMUX_PIN(0xff, 216), + MX31_PIN_LBA = IOMUX_PIN(0xff, 217), + MX31_PIN_ECB = IOMUX_PIN(0xff, 218), + MX31_PIN_CS5 = IOMUX_PIN(0xff, 219), + MX31_PIN_CS4 = IOMUX_PIN(0xff, 220), + MX31_PIN_CS3 = IOMUX_PIN(0xff, 221), + MX31_PIN_CS2 = IOMUX_PIN(0xff, 222), + MX31_PIN_CS1 = IOMUX_PIN(0xff, 223), + MX31_PIN_CS0 = IOMUX_PIN(0xff, 224), + MX31_PIN_OE = IOMUX_PIN(0xff, 225), + MX31_PIN_EB1 = IOMUX_PIN(0xff, 226), + MX31_PIN_EB0 = IOMUX_PIN(0xff, 227), + MX31_PIN_DQM3 = IOMUX_PIN(0xff, 228), + MX31_PIN_DQM2 = IOMUX_PIN(0xff, 229), + MX31_PIN_DQM1 = IOMUX_PIN(0xff, 230), + MX31_PIN_DQM0 = IOMUX_PIN(0xff, 231), + MX31_PIN_SD31 = IOMUX_PIN(0xff, 232), + MX31_PIN_SD30 = IOMUX_PIN(0xff, 233), + MX31_PIN_SD29 = IOMUX_PIN(0xff, 234), + MX31_PIN_SD28 = IOMUX_PIN(0xff, 235), + MX31_PIN_SD27 = IOMUX_PIN(0xff, 236), + MX31_PIN_SD26 = IOMUX_PIN(0xff, 237), + MX31_PIN_SD25 = IOMUX_PIN(0xff, 238), + MX31_PIN_SD24 = IOMUX_PIN(0xff, 239), + MX31_PIN_SD23 = IOMUX_PIN(0xff, 240), + MX31_PIN_SD22 = IOMUX_PIN(0xff, 241), + MX31_PIN_SD21 = IOMUX_PIN(0xff, 242), + MX31_PIN_SD20 = IOMUX_PIN(0xff, 243), + MX31_PIN_SD19 = IOMUX_PIN(0xff, 244), + MX31_PIN_SD18 = IOMUX_PIN(0xff, 245), + MX31_PIN_SD17 = IOMUX_PIN(0xff, 246), + MX31_PIN_SD16 = IOMUX_PIN(0xff, 247), + MX31_PIN_SD15 = IOMUX_PIN(0xff, 248), + MX31_PIN_SD14 = IOMUX_PIN(0xff, 249), + MX31_PIN_SD13 = IOMUX_PIN(0xff, 250), + MX31_PIN_SD12 = IOMUX_PIN(0xff, 251), + MX31_PIN_SD11 = IOMUX_PIN(0xff, 252), + MX31_PIN_SD10 = IOMUX_PIN(0xff, 253), + MX31_PIN_SD9 = IOMUX_PIN(0xff, 254), + MX31_PIN_SD8 = IOMUX_PIN(0xff, 255), + MX31_PIN_SD7 = IOMUX_PIN(0xff, 256), + MX31_PIN_SD6 = IOMUX_PIN(0xff, 257), + MX31_PIN_SD5 = IOMUX_PIN(0xff, 258), + MX31_PIN_SD4 = IOMUX_PIN(0xff, 259), + MX31_PIN_SD3 = IOMUX_PIN(0xff, 260), + MX31_PIN_SD2 = IOMUX_PIN(0xff, 261), + MX31_PIN_SD1 = IOMUX_PIN(0xff, 262), + MX31_PIN_SD0 = IOMUX_PIN(0xff, 263), + MX31_PIN_SDBA0 = IOMUX_PIN(0xff, 264), + MX31_PIN_SDBA1 = IOMUX_PIN(0xff, 265), + MX31_PIN_A25 = IOMUX_PIN(0xff, 266), + MX31_PIN_A24 = IOMUX_PIN(0xff, 267), + MX31_PIN_A23 = IOMUX_PIN(0xff, 268), + MX31_PIN_A22 = IOMUX_PIN(0xff, 269), + MX31_PIN_A21 = IOMUX_PIN(0xff, 270), + MX31_PIN_A20 = IOMUX_PIN(0xff, 271), + MX31_PIN_A19 = IOMUX_PIN(0xff, 272), + MX31_PIN_A18 = IOMUX_PIN(0xff, 273), + MX31_PIN_A17 = IOMUX_PIN(0xff, 274), + MX31_PIN_A16 = IOMUX_PIN(0xff, 275), + MX31_PIN_A14 = IOMUX_PIN(0xff, 276), + MX31_PIN_A15 = IOMUX_PIN(0xff, 277), + MX31_PIN_A13 = IOMUX_PIN(0xff, 278), + MX31_PIN_A12 = IOMUX_PIN(0xff, 279), + MX31_PIN_A11 = IOMUX_PIN(0xff, 280), + MX31_PIN_MA10 = IOMUX_PIN(0xff, 281), + MX31_PIN_A10 = IOMUX_PIN(0xff, 282), + MX31_PIN_A9 = IOMUX_PIN(0xff, 283), + MX31_PIN_A8 = IOMUX_PIN(0xff, 284), + MX31_PIN_A7 = IOMUX_PIN(0xff, 285), + MX31_PIN_A6 = IOMUX_PIN(0xff, 286), + MX31_PIN_A5 = IOMUX_PIN(0xff, 287), + MX31_PIN_A4 = IOMUX_PIN(0xff, 288), + MX31_PIN_A3 = IOMUX_PIN(0xff, 289), + MX31_PIN_A2 = IOMUX_PIN(0xff, 290), + MX31_PIN_A1 = IOMUX_PIN(0xff, 291), + MX31_PIN_A0 = IOMUX_PIN(0xff, 292), + MX31_PIN_VPG1 = IOMUX_PIN(0xff, 293), + MX31_PIN_VPG0 = IOMUX_PIN(0xff, 294), + MX31_PIN_DVFS1 = IOMUX_PIN(0xff, 295), + MX31_PIN_DVFS0 = IOMUX_PIN(0xff, 296), + MX31_PIN_VSTBY = IOMUX_PIN(0xff, 297), + MX31_PIN_POWER_FAIL = IOMUX_PIN(0xff, 298), + MX31_PIN_CKIL = IOMUX_PIN(0xff, 299), + MX31_PIN_BOOT_MODE4 = IOMUX_PIN(0xff, 300), + MX31_PIN_BOOT_MODE3 = IOMUX_PIN(0xff, 301), + MX31_PIN_BOOT_MODE2 = IOMUX_PIN(0xff, 302), + MX31_PIN_BOOT_MODE1 = IOMUX_PIN(0xff, 303), + MX31_PIN_BOOT_MODE0 = IOMUX_PIN(0xff, 304), + MX31_PIN_CLKO = IOMUX_PIN(0xff, 305), + MX31_PIN_POR_B = IOMUX_PIN(0xff, 306), + MX31_PIN_RESET_IN_B = IOMUX_PIN(0xff, 307), + MX31_PIN_CKIH = IOMUX_PIN(0xff, 308), + MX31_PIN_SIMPD0 = IOMUX_PIN(35, 309), + MX31_PIN_SRX0 = IOMUX_PIN(34, 310), + MX31_PIN_STX0 = IOMUX_PIN(33, 311), + MX31_PIN_SVEN0 = IOMUX_PIN(32, 312), + MX31_PIN_SRST0 = IOMUX_PIN(67, 313), + MX31_PIN_SCLK0 = IOMUX_PIN(66, 314), + MX31_PIN_GPIO3_1 = IOMUX_PIN(65, 315), + MX31_PIN_GPIO3_0 = IOMUX_PIN(64, 316), + MX31_PIN_GPIO1_6 = IOMUX_PIN( 6, 317), + MX31_PIN_GPIO1_5 = IOMUX_PIN( 5, 318), + MX31_PIN_GPIO1_4 = IOMUX_PIN( 4, 319), + MX31_PIN_GPIO1_3 = IOMUX_PIN( 3, 320), + MX31_PIN_GPIO1_2 = IOMUX_PIN( 2, 321), + MX31_PIN_GPIO1_1 = IOMUX_PIN( 1, 322), + MX31_PIN_GPIO1_0 = IOMUX_PIN( 0, 323), + MX31_PIN_PWMO = IOMUX_PIN( 9, 324), + MX31_PIN_WATCHDOG_RST = IOMUX_PIN(0xff, 325), + MX31_PIN_COMPARE = IOMUX_PIN( 8, 326), + MX31_PIN_CAPTURE = IOMUX_PIN( 7, 327), +}; + +/* + * Convenience values for use with mxc_iomux_mode() + * + * Format here is MX31_PIN_(pin name)__(function) + */ +#define MX31_PIN_CSPI3_MOSI__RXD3 IOMUX_MODE(MX31_PIN_CSPI3_MOSI, IOMUX_CONFIG_ALT1) +#define MX31_PIN_CSPI3_MISO__TXD3 IOMUX_MODE(MX31_PIN_CSPI3_MISO, IOMUX_CONFIG_ALT1) +#define MX31_PIN_CTS1__CTS1 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_FUNC) +#define MX31_PIN_RTS1__RTS1 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC) +#define MX31_PIN_TXD1__TXD1 IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC) +#define MX31_PIN_RXD1__RXD1 IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC) + +/* + * This function configures the pad value for a IOMUX pin. + */ +void mxc_iomux_set_pad(enum iomux_pins, u32); + +#endif + -- cgit v1.2.3-70-g09d2 From d0f349fbce2905607e0473d2358f97f48866e52c Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:50 +0200 Subject: i.MXC family: Adding timer support This patch adds timer support for the i.MX machine family. This code can be used on the following machs: - i.MX1 (tested) - i.MX2 (i.MX21 (to be tested), i.MX27 (tested)) - i.MX3 (i.MX31 (tested)) TODO: It seems impossible to build a kernel for more than one CPU because the timer do not follow the platform device rules. So it does only work if timer 1 can be accessed on all CPUs at the same address. Signed-off-by: Juergen Beisert Signed-off-by: Sascha Hauer --- arch/arm/Kconfig | 2 + arch/arm/mach-mx3/Makefile | 2 +- arch/arm/mach-mx3/mx31ads.c | 13 +- arch/arm/mach-mx3/time.c | 148 ----------------------- arch/arm/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/time.c | 228 +++++++++++++++++++++++++++++++++++ include/asm-arm/arch-mxc/common.h | 4 +- include/asm-arm/arch-mxc/mxc.h | 112 +++-------------- include/asm-arm/arch-mxc/mxc_timer.h | 158 ++++++++++++++++++++++++ 9 files changed, 418 insertions(+), 251 deletions(-) delete mode 100644 arch/arm/mach-mx3/time.c create mode 100644 arch/arm/plat-mxc/time.c create mode 100644 include/asm-arm/arch-mxc/mxc_timer.h (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5c8c1a89be7..8a9a84c4adf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -367,6 +367,8 @@ config ARCH_NS9XXX config ARCH_MXC bool "Freescale MXC/iMX-based" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS select ARCH_MTD_XIP select GENERIC_GPIO select HAVE_GPIO_LIB diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 68f062b70d3..562c75d2e37 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,5 +4,5 @@ # Object file lists. -obj-y := mm.o time.o clock.o devices.o iomux.o +obj-y := mm.o clock.o devices.o iomux.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 5addbb7f711..eba3e0cd428 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -127,6 +128,16 @@ static void __init mxc_board_init(void) mxc_init_extuart(); } +static void __init mx31ads_timer_init(void) +{ + mxc_clocks_init(26000000); + mxc_timer_init("ipg_clk.0"); +} + +struct sys_timer mx31ads_timer = { + .init = mx31ads_timer_init, +}; + /* * The following uses standard kernel macros defined in arch.h in order to * initialize __mach_desc_MX31ADS data structure. @@ -139,5 +150,5 @@ MACHINE_START(MX31ADS, "Freescale MX31ADS") .map_io = mx31ads_map_io, .init_irq = mxc_init_irq, .init_machine = mxc_board_init, - .timer = &mxc_timer, + .timer = &mx31ads_timer, MACHINE_END diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c deleted file mode 100644 index fb565c98dbf..00000000000 --- a/arch/arm/mach-mx3/time.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * System Timer Interrupt reconfigured to run in free-run mode. - * Author: Vitaly Wool - * Copyright 2004 MontaVista Software Inc. - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/*! - * @file time.c - * @brief This file contains OS tick and wdog timer implementations. - * - * This file contains OS tick and wdog timer implementations. - * - * @ingroup Timers - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/*! - * This is the timer interrupt service routine to do required tasks. - * It also services the WDOG timer at the frequency of twice per WDOG - * timeout value. For example, if the WDOG's timeout value is 4 (2 - * seconds since the WDOG runs at 0.5Hz), it will be serviced once - * every 2/2=1 second. - * - * @param irq GPT interrupt source number (not used) - * @param dev_id this parameter is not used - * @return always returns \b IRQ_HANDLED as defined in - * include/linux/interrupt.h. - */ -static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) -{ - unsigned int next_match; - - if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { - do { - timer_tick(); - next_match = __raw_readl(MXC_GPT_GPTOCR1) + LATCH; - __raw_writel(GPTSR_OF1, MXC_GPT_GPTSR); - __raw_writel(next_match, MXC_GPT_GPTOCR1); - } while ((signed long)(next_match - - __raw_readl(MXC_GPT_GPTCNT)) <= 0); - } - - return IRQ_HANDLED; -} - -/*! - * This function is used to obtain the number of microseconds since the last - * timer interrupt. Note that interrupts is disabled by do_gettimeofday(). - * - * @return the number of microseconds since the last timer interrupt. - */ -static unsigned long mxc_gettimeoffset(void) -{ - unsigned long ticks_to_match, elapsed, usec, tick_usec, i; - - /* Get ticks before next timer match */ - ticks_to_match = - __raw_readl(MXC_GPT_GPTOCR1) - __raw_readl(MXC_GPT_GPTCNT); - - /* We need elapsed ticks since last match */ - elapsed = LATCH - ticks_to_match; - - /* Now convert them to usec */ - /* Insure no overflow when calculating the usec below */ - for (i = 1, tick_usec = tick_nsec / 1000;; i *= 2) { - tick_usec /= i; - if ((0xFFFFFFFF / tick_usec) > elapsed) - break; - } - usec = (unsigned long)(elapsed * tick_usec) / (LATCH / i); - - return usec; -} - -/*! - * The OS tick timer interrupt structure. - */ -static struct irqaction timer_irq = { - .name = "MXC Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER, - .handler = mxc_timer_interrupt -}; - -/*! - * This function is used to initialize the GPT to produce an interrupt - * based on HZ. It is called by start_kernel() during system startup. - */ -void __init mxc_init_time(void) -{ - u32 reg, v; - reg = __raw_readl(MXC_GPT_GPTCR); - reg &= ~GPTCR_ENABLE; - __raw_writel(reg, MXC_GPT_GPTCR); - reg |= GPTCR_SWR; - __raw_writel(reg, MXC_GPT_GPTCR); - - while ((__raw_readl(MXC_GPT_GPTCR) & GPTCR_SWR) != 0) - cpu_relax(); - - reg = GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ; - __raw_writel(reg, MXC_GPT_GPTCR); - - /* TODO: get timer rate from clk driver */ - v = 66500000; - - __raw_writel((v / CLOCK_TICK_RATE) - 1, MXC_GPT_GPTPR); - - if ((v % CLOCK_TICK_RATE) != 0) { - pr_info("\nWARNING: Can't generate CLOCK_TICK_RATE at %d Hz\n", - CLOCK_TICK_RATE); - } - pr_info("Actual CLOCK_TICK_RATE is %d Hz\n", - v / ((__raw_readl(MXC_GPT_GPTPR) & 0xFFF) + 1)); - - reg = __raw_readl(MXC_GPT_GPTCNT); - reg += LATCH; - __raw_writel(reg, MXC_GPT_GPTOCR1); - - setup_irq(MXC_INT_GPT, &timer_irq); - - reg = __raw_readl(MXC_GPT_GPTCR); - reg = - GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ | GPTCR_STOPEN | GPTCR_DOZEN | - GPTCR_WAITEN | GPTCR_ENMOD | GPTCR_ENABLE; - __raw_writel(reg, MXC_GPT_GPTCR); - - __raw_writel(GPTIR_OF1IE, MXC_GPT_GPTIR); -} - -struct sys_timer mxc_timer = { - .init = mxc_init_time, - .offset = mxc_gettimeoffset, -}; diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 66272a6fc32..e3cc25c6d46 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,4 +3,4 @@ # # Common support -obj-y := irq.o clock.o gpio.o +obj-y := irq.o clock.o gpio.o time.o diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c new file mode 100644 index 00000000000..3bf86343fdf --- /dev/null +++ b/arch/arm/plat-mxc/time.c @@ -0,0 +1,228 @@ +/* + * linux/arch/arm/plat-mxc/time.c + * + * Copyright (C) 2000-2001 Deep Blue Solutions + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct clock_event_device clockevent_mxc; +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; + +/* clock source for the timer */ +static struct clk *timer_clk; + +/* clock source */ + +static cycle_t mxc_get_cycles(void) +{ + return __raw_readl(TIMER_BASE + MXC_TCN); +} + +static struct clocksource clocksource_mxc = { + .name = "mxc_timer1", + .rating = 200, + .read = mxc_get_cycles, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init mxc_clocksource_init(void) +{ + unsigned int clock; + + clock = clk_get_rate(timer_clk); + + clocksource_mxc.mult = clocksource_hz2mult(clock, + clocksource_mxc.shift); + clocksource_register(&clocksource_mxc); + + return 0; +} + +/* clock event */ + +static int mxc_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + unsigned long tcmp; + + tcmp = __raw_readl(TIMER_BASE + MXC_TCN) + evt; + __raw_writel(tcmp, TIMER_BASE + MXC_TCMP); + + return (int)(tcmp - __raw_readl(TIMER_BASE + MXC_TCN)) < 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 mxc_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 mxc_set_next_event() + */ + local_irq_save(flags); + + /* Disable interrupt in GPT module */ + gpt_irq_disable(); + + if (mode != clockevent_mode) { + /* Set event time into far-far future */ + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCN) - 3, + TIMER_BASE + MXC_TCMP); + /* Clear pending interrupt */ + gpt_irq_acknowledge(); + } + +#ifdef DEBUG + printk(KERN_INFO "mxc_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"mxc_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 + * mxc_set_next_event(), the core has about 4 minutes + * to call mxc_set_next_event() or shutdown clock after + * mode switching + */ + local_irq_save(flags); + gpt_irq_enable(); + local_irq_restore(flags); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + /* Left event sources disabled, no more interrupts appear */ + break; + } +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &clockevent_mxc; + uint32_t tstat; + + tstat = __raw_readl(TIMER_BASE + MXC_TSTAT); + + gpt_irq_acknowledge(); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction mxc_timer_irq = { + .name = "i.MX Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = mxc_timer_interrupt, +}; + +static struct clock_event_device clockevent_mxc = { + .name = "mxc_timer1", + .features = CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .set_mode = mxc_set_mode, + .set_next_event = mxc_set_next_event, + .rating = 200, +}; + +static int __init mxc_clockevent_init(void) +{ + unsigned int clock; + + clock = clk_get_rate(timer_clk); + + clockevent_mxc.mult = div_sc(clock, NSEC_PER_SEC, + clockevent_mxc.shift); + clockevent_mxc.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &clockevent_mxc); + clockevent_mxc.min_delta_ns = + clockevent_delta2ns(0xff, &clockevent_mxc); + + clockevent_mxc.cpumask = cpumask_of_cpu(0); + + clockevents_register_device(&clockevent_mxc); + + return 0; +} + +void __init mxc_timer_init(const char *clk_timer) +{ + timer_clk = clk_get(NULL, clk_timer); + if (!timer_clk) { + printk(KERN_ERR"Cannot determine timer clock. Giving up.\n"); + return; + } + + clk_enable(timer_clk); + + /* + * Initialise to a known state (all timers off, and timing reset) + */ + __raw_writel(0, TIMER_BASE + MXC_TCTL); + __raw_writel(0, TIMER_BASE + MXC_TPRER); /* see datasheet note */ + + __raw_writel(TCTL_FRR | /* free running */ + TCTL_VAL | /* set clocksource and arch specific bits */ + TCTL_TEN, /* start the timer */ + TIMER_BASE + MXC_TCTL); + + /* init and register the timer to the framework */ + mxc_clocksource_init(); + mxc_clockevent_init(); + + /* Make irqs happen */ + setup_irq(TIMER_INTERRUPT, &mxc_timer_irq); +} + diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h index 8774783ed98..a6d2e24aab1 100644 --- a/include/asm-arm/arch-mxc/common.h +++ b/include/asm-arm/arch-mxc/common.h @@ -11,11 +11,9 @@ #ifndef __ASM_ARCH_MXC_COMMON_H__ #define __ASM_ARCH_MXC_COMMON_H__ -struct sys_timer; - extern void mxc_map_io(void); extern void mxc_init_irq(void); -extern struct sys_timer mxc_timer; +extern void mxc_timer_init(const char *clk_timer); extern int mxc_clocks_init(unsigned long fref); extern int mxc_register_gpios(void); diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h index 146d3f60951..1df4e2f2492 100644 --- a/include/asm-arm/arch-mxc/mxc.h +++ b/include/asm-arm/arch-mxc/mxc.h @@ -1,11 +1,20 @@ /* * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. */ #ifndef __ASM_ARCH_MXC_H__ @@ -20,97 +29,6 @@ # define cpu_is_mx31() (0) #endif -/* - ***************************************** - * GPT Register definitions * - ***************************************** - */ -#define MXC_GPT_GPTCR IO_ADDRESS(GPT1_BASE_ADDR + 0x00) -#define MXC_GPT_GPTPR IO_ADDRESS(GPT1_BASE_ADDR + 0x04) -#define MXC_GPT_GPTSR IO_ADDRESS(GPT1_BASE_ADDR + 0x08) -#define MXC_GPT_GPTIR IO_ADDRESS(GPT1_BASE_ADDR + 0x0C) -#define MXC_GPT_GPTOCR1 IO_ADDRESS(GPT1_BASE_ADDR + 0x10) -#define MXC_GPT_GPTOCR2 IO_ADDRESS(GPT1_BASE_ADDR + 0x14) -#define MXC_GPT_GPTOCR3 IO_ADDRESS(GPT1_BASE_ADDR + 0x18) -#define MXC_GPT_GPTICR1 IO_ADDRESS(GPT1_BASE_ADDR + 0x1C) -#define MXC_GPT_GPTICR2 IO_ADDRESS(GPT1_BASE_ADDR + 0x20) -#define MXC_GPT_GPTCNT IO_ADDRESS(GPT1_BASE_ADDR + 0x24) - -/* GPT Control register bit definitions */ -#define GPTCR_FO3 (1 << 31) -#define GPTCR_FO2 (1 << 30) -#define GPTCR_FO1 (1 << 29) - -#define GPTCR_OM3_SHIFT 26 -#define GPTCR_OM3_MASK (7 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_DISCONNECTED (0 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_TOGGLE (1 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_CLEAR (2 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_SET (3 << GPTCR_OM3_SHIFT) -#define GPTCR_OM3_GENERATE_LOW (7 << GPTCR_OM3_SHIFT) - -#define GPTCR_OM2_SHIFT 23 -#define GPTCR_OM2_MASK (7 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_DISCONNECTED (0 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_TOGGLE (1 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_CLEAR (2 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_SET (3 << GPTCR_OM2_SHIFT) -#define GPTCR_OM2_GENERATE_LOW (7 << GPTCR_OM2_SHIFT) - -#define GPTCR_OM1_SHIFT 20 -#define GPTCR_OM1_MASK (7 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_DISCONNECTED (0 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_TOGGLE (1 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_CLEAR (2 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_SET (3 << GPTCR_OM1_SHIFT) -#define GPTCR_OM1_GENERATE_LOW (7 << GPTCR_OM1_SHIFT) - -#define GPTCR_IM2_SHIFT 18 -#define GPTCR_IM2_MASK (3 << GPTCR_IM2_SHIFT) -#define GPTCR_IM2_CAPTURE_DISABLE (0 << GPTCR_IM2_SHIFT) -#define GPTCR_IM2_CAPTURE_RISING (1 << GPTCR_IM2_SHIFT) -#define GPTCR_IM2_CAPTURE_FALLING (2 << GPTCR_IM2_SHIFT) -#define GPTCR_IM2_CAPTURE_BOTH (3 << GPTCR_IM2_SHIFT) - -#define GPTCR_IM1_SHIFT 16 -#define GPTCR_IM1_MASK (3 << GPTCR_IM1_SHIFT) -#define GPTCR_IM1_CAPTURE_DISABLE (0 << GPTCR_IM1_SHIFT) -#define GPTCR_IM1_CAPTURE_RISING (1 << GPTCR_IM1_SHIFT) -#define GPTCR_IM1_CAPTURE_FALLING (2 << GPTCR_IM1_SHIFT) -#define GPTCR_IM1_CAPTURE_BOTH (3 << GPTCR_IM1_SHIFT) - -#define GPTCR_SWR (1 << 15) -#define GPTCR_FRR (1 << 9) - -#define GPTCR_CLKSRC_SHIFT 6 -#define GPTCR_CLKSRC_MASK (7 << GPTCR_CLKSRC_SHIFT) -#define GPTCR_CLKSRC_NOCLOCK (0 << GPTCR_CLKSRC_SHIFT) -#define GPTCR_CLKSRC_HIGHFREQ (2 << GPTCR_CLKSRC_SHIFT) -#define GPTCR_CLKSRC_CLKIN (3 << GPTCR_CLKSRC_SHIFT) -#define GPTCR_CLKSRC_CLK32K (7 << GPTCR_CLKSRC_SHIFT) - -#define GPTCR_STOPEN (1 << 5) -#define GPTCR_DOZEN (1 << 4) -#define GPTCR_WAITEN (1 << 3) -#define GPTCR_DBGEN (1 << 2) - -#define GPTCR_ENMOD (1 << 1) -#define GPTCR_ENABLE (1 << 0) - -#define GPTSR_OF1 (1 << 0) -#define GPTSR_OF2 (1 << 1) -#define GPTSR_OF3 (1 << 2) -#define GPTSR_IF1 (1 << 3) -#define GPTSR_IF2 (1 << 4) -#define GPTSR_ROV (1 << 5) - -#define GPTIR_OF1IE GPTSR_OF1 -#define GPTIR_OF2IE GPTSR_OF2 -#define GPTIR_OF3IE GPTSR_OF3 -#define GPTIR_IF1IE GPTSR_IF1 -#define GPTIR_IF2IE GPTSR_IF2 -#define GPTIR_ROVIE GPTSR_ROV - /* ***************************************** * AVIC Registers * diff --git a/include/asm-arm/arch-mxc/mxc_timer.h b/include/asm-arm/arch-mxc/mxc_timer.h new file mode 100644 index 00000000000..6cb11f4f1a0 --- /dev/null +++ b/include/asm-arm/arch-mxc/mxc_timer.h @@ -0,0 +1,158 @@ +/* + * mxc_timer.h + * + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * Platform independent (i.MX1, i.MX2, i.MX3) definition for timer handling. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __PLAT_MXC_TIMER_H +#define __PLAT_MXC_TIMER_H + +#include +#include + +#ifdef CONFIG_ARCH_IMX +#define TIMER_BASE IO_ADDRESS(TIM1_BASE_ADDR) +#define TIMER_INTERRUPT TIM1_INT + +#define TCTL_VAL TCTL_CLK_PCLK1 +#define TCTL_IRQEN (1<<4) +#define TCTL_FRR (1<<8) +#define TCTL_CLK_PCLK1 (1<<1) +#define TCTL_CLK_PCLK1_4 (2<<1) +#define TCTL_CLK_TIN (3<<1) +#define TCTL_CLK_32 (4<<1) + +#define MXC_TCTL 0x00 +#define MXC_TPRER 0x04 +#define MXC_TCMP 0x08 +#define MXC_TCR 0x0c +#define MXC_TCN 0x10 +#define MXC_TSTAT 0x14 +#define TSTAT_CAPT (1<<1) +#define TSTAT_COMP (1<<0) + +static inline void gpt_irq_disable(void) +{ + unsigned int tmp; + + tmp = __raw_readl(TIMER_BASE + MXC_TCTL); + __raw_writel(tmp & ~TCTL_IRQEN, TIMER_BASE + MXC_TCTL); +} + +static inline void gpt_irq_enable(void) +{ + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCTL) | TCTL_IRQEN, + TIMER_BASE + MXC_TCTL); +} + +static void gpt_irq_acknowledge(void) +{ + __raw_writel(0, TIMER_BASE + MXC_TSTAT); +} +#endif /* CONFIG_ARCH_IMX */ + +#ifdef CONFIG_ARCH_MX2 +#define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR) +#define TIMER_INTERRUPT MXC_INT_GPT1 + +#define MXC_TCTL 0x00 +#define TCTL_VAL TCTL_CLK_PCLK1 +#define TCTL_CLK_PCLK1 (1<<1) +#define TCTL_CLK_PCLK1_4 (2<<1) +#define TCTL_IRQEN (1<<4) +#define TCTL_FRR (1<<8) +#define MXC_TPRER 0x04 +#define MXC_TCMP 0x08 +#define MXC_TCR 0x0c +#define MXC_TCN 0x10 +#define MXC_TSTAT 0x14 +#define TSTAT_CAPT (1<<1) +#define TSTAT_COMP (1<<0) + +static inline void gpt_irq_disable(void) +{ + unsigned int tmp; + + tmp = __raw_readl(TIMER_BASE + MXC_TCTL); + __raw_writel(tmp & ~TCTL_IRQEN, TIMER_BASE + MXC_TCTL); +} + +static inline void gpt_irq_enable(void) +{ + __raw_writel(__raw_readl(TIMER_BASE + MXC_TCTL) | TCTL_IRQEN, + TIMER_BASE + MXC_TCTL); +} + +static void gpt_irq_acknowledge(void) +{ + __raw_writel(TSTAT_CAPT | TSTAT_COMP, TIMER_BASE + MXC_TSTAT); +} +#endif /* CONFIG_ARCH_MX2 */ + +#ifdef CONFIG_ARCH_MX3 +#define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR) +#define TIMER_INTERRUPT MXC_INT_GPT + +#define MXC_TCTL 0x00 +#define TCTL_VAL (TCTL_CLK_IPG | TCTL_WAITEN) +#define TCTL_CLK_IPG (1<<6) +#define TCTL_FRR (1<<9) +#define TCTL_WAITEN (1<<3) + +#define MXC_TPRER 0x04 +#define MXC_TSTAT 0x08 +#define TSTAT_OF1 (1<<0) +#define TSTAT_OF2 (1<<1) +#define TSTAT_OF3 (1<<2) +#define TSTAT_IF1 (1<<3) +#define TSTAT_IF2 (1<<4) +#define TSTAT_ROV (1<<5) +#define MXC_IR 0x0c +#define MXC_TCMP 0x10 +#define MXC_TCMP2 0x14 +#define MXC_TCMP3 0x18 +#define MXC_TCR 0x1c +#define MXC_TCN 0x24 + +static inline void gpt_irq_disable(void) +{ + __raw_writel(0, TIMER_BASE + MXC_IR); +} + +static inline void gpt_irq_enable(void) +{ + __raw_writel(1<<0, TIMER_BASE + MXC_IR); +} + +static inline void gpt_irq_acknowledge(void) +{ + __raw_writel(TSTAT_OF1, TIMER_BASE + MXC_TSTAT); +} +#endif /* CONFIG_ARCH_MX3 */ + +#define TCTL_SWR (1<<15) +#define TCTL_CC (1<<10) +#define TCTL_OM (1<<9) +#define TCTL_CAP_RIS (1<<6) +#define TCTL_CAP_FAL (2<<6) +#define TCTL_CAP_RIS_FAL (3<<6) +#define TCTL_CAP_ENA (1<<5) +#define TCTL_TEN (1<<0) + +#endif -- cgit v1.2.3-70-g09d2 From 4bc256501a159abc7e9fee43f63c68894f6a11d8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:51 +0200 Subject: MXC: add debug-macro.S for mxc This patch adds debug-macro.S for arch-mxc Disadvantage: Due to the board specific UART definition, these macros (and compile time) will fail for multi board kernels. Signed-off-by: Sascha Hauer --- include/asm-arm/arch-mxc/board-mx31ads.h | 5 +++++ include/asm-arm/arch-mxc/debug-macro.S | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 include/asm-arm/arch-mxc/debug-macro.S (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-mxc/board-mx31ads.h b/include/asm-arm/arch-mxc/board-mx31ads.h index 8590127760a..1bc6fb0f9a8 100644 --- a/include/asm-arm/arch-mxc/board-mx31ads.h +++ b/include/asm-arm/arch-mxc/board-mx31ads.h @@ -109,4 +109,9 @@ #define MXC_MAX_EXP_IO_LINES 16 +/* mandatory for CONFIG_LL_DEBUG */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + #endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S new file mode 100644 index 00000000000..34befbb2ea4 --- /dev/null +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -0,0 +1,38 @@ +/* linux/include/asm-arm/arch-imx/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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 + +#ifdef CONFIG_MACH_MX31ADS +#include +#endif + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, =MXC_LL_UART_PADDR @ physical + ldrne \rx, =MXC_LL_UART_VADDR @ virtual + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #0x40] @ TXDATA + .endm + + .macro waituart,rd,rx + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #0x98] @ SR2 + tst \rd, #1 << 3 @ TXDC + beq 1002b @ wait until transmit done + .endm -- cgit v1.2.3-70-g09d2 From ce8ffef0bfd6e55d5da3923d8e9af27c3b5c4eff Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 5 Jul 2008 10:02:52 +0200 Subject: MX31: add basic pcm037 board support This patch adds basic board support for phytecs pmc037 board. Signed-off-by: Sascha Hauer --- arch/arm/configs/pcm037_defconfig | 748 ++++++++++++++++++++++++++++++++ arch/arm/mach-mx3/Kconfig | 6 + arch/arm/mach-mx3/Makefile | 1 + arch/arm/mach-mx3/pcm037.c | 130 ++++++ include/asm-arm/arch-mxc/board-pcm037.h | 27 ++ include/asm-arm/arch-mxc/debug-macro.S | 3 + 6 files changed, 915 insertions(+) create mode 100644 arch/arm/configs/pcm037_defconfig create mode 100644 arch/arm/mach-mx3/pcm037.c create mode 100644 include/asm-arm/arch-mxc/board-pcm037.h (limited to 'include/asm-arm') diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig new file mode 100644 index 00000000000..62747458647 --- /dev/null +++ b/arch/arm/configs/pcm037_defconfig @@ -0,0 +1,748 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc6 +# Wed Jun 25 11:52:42 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +CONFIG_ARCH_MX3=y + +# +# MX3 Options +# +# CONFIG_MACH_MX31ADS is not set +CONFIG_MACH_PCM037=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_V6=y +# CONFIG_CPU_32v6K is not set +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_NOSWAP is not set +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 5fe8606cac0..8b7b49a9292 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -8,5 +8,11 @@ config MACH_MX31ADS Include support for MX31ADS platform. This includes specific configurations for the board and its peripherals. +config MACH_PCM037 + bool "Support Phytec pcm037 platforms" + help + Include support for Phytec pcm037 platform. This includes + specific configurations for the board and its peripherals. + endmenu diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 562c75d2e37..b09ca608349 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -6,3 +6,4 @@ obj-y := mm.o clock.o devices.o iomux.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o +obj-$(CONFIG_MACH_PCM037) += pcm037.o diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c new file mode 100644 index 00000000000..a34ae6de266 --- /dev/null +++ b/arch/arm/mach-mx3/pcm037.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2008 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct physmap_flash_data pcm037_flash_data = { + .width = 2, +}; + +static struct resource pcm037_flash_resource = { + .start = 0xa0000000, + .end = 0xa1ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device pcm037_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &pcm037_flash_data, + }, + .resource = &pcm037_flash_resource, + .num_resources = 1, +}; + +static struct imxuart_platform_data uart_pdata = { + .flags = 0, +}; + +static struct platform_device *devices[] __initdata = { + &pcm037_flash, +}; + +/* + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + platform_add_devices(devices, ARRAY_SIZE(devices)); + + mxc_iomux_mode(MX31_PIN_CTS1__CTS1); + mxc_iomux_mode(MX31_PIN_RTS1__RTS1); + mxc_iomux_mode(MX31_PIN_TXD1__TXD1); + mxc_iomux_mode(MX31_PIN_RXD1__RXD1); + + imx_init_uart(0, &uart_pdata); + + mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3); + mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3); + + imx_init_uart(2, &uart_pdata); +} + +/* + * This structure defines static mappings for the pcm037 board. + */ +static struct map_desc pcm037_io_desc[] __initdata = { + { + .virtual = AIPS1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), + .length = AIPS1_SIZE, + .type = MT_DEVICE + }, { + .virtual = AIPS2_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), + .length = AIPS2_SIZE, + .type = MT_DEVICE + }, +}; + +/* + * Set up static virtual mappings. + */ +void __init pcm037_map_io(void) +{ + mxc_map_io(); + iotable_init(pcm037_io_desc, ARRAY_SIZE(pcm037_io_desc)); +} + +static void __init pcm037_timer_init(void) +{ + mxc_clocks_init(26000000); + mxc_timer_init("ipg_clk.0"); +} + +struct sys_timer pcm037_timer = { + .init = pcm037_timer_init, +}; + +MACHINE_START(PCM037, "Phytec Phycore pcm037") + /* Maintainer: Pengutronix */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = pcm037_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &pcm037_timer, +MACHINE_END + diff --git a/include/asm-arm/arch-mxc/board-pcm037.h b/include/asm-arm/arch-mxc/board-pcm037.h new file mode 100644 index 00000000000..82232ba3c8f --- /dev/null +++ b/include/asm-arm/arch-mxc/board-pcm037.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2008 Sascha Hauer, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_MXC_BOARD_PCM037_H__ +#define __ASM_ARCH_MXC_BOARD_PCM037_H__ + +/* mandatory for CONFIG_LL_DEBUG */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +#endif /* __ASM_ARCH_MXC_BOARD_PCM037_H__ */ diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S index 34befbb2ea4..81caa0aacfe 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -15,6 +15,9 @@ #ifdef CONFIG_MACH_MX31ADS #include +#endif +#ifdef CONFIG_MACH_PCM037 +#include #endif .macro addruart,rx -- cgit v1.2.3-70-g09d2 From 9a4cd7a5c836e189a1712c9ffd2d76b2302ce212 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sat, 5 Jul 2008 10:02:53 +0200 Subject: MX3: Add basic support for LogicPD i.MX31 LiteKit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds basic support for i.MX31 LiteKit by LogicPD. With printascii() in kernel/printk.c, it boots right into the rootfs-panic. Note: This is a modified version of Daniel's patch to fit into this patch stack. > On 09.06.2008, at 17:26, Russell King - ARM Linux wrote: > > > I would much prefer it if board specific includes were included by the > > code which needs them rather than in asm/arch/hardware.h.  With the > > device model, drivers shouldn't need to include any board specific > > includes - only the board specific C file should need it. > > The new version of this patch (#5102) has been uploaded to the patch > tracker this morning. Signed-off-by: Daniel Mack -- arch/arm/configs/mx31litekit_defconfig | 1100 ++++++++++++++++++++++++++++++ arch/arm/mach-mx3/Kconfig | 7 arch/arm/mach-mx3/Makefile | 1 arch/arm/mach-mx3/mx31lite.c | 96 ++ include/asm-arm/arch-mxc/board-mx31lite.h | 38 + include/asm-arm/arch-mxc/debug-macro.S | 3 6 files changed, 1245 insertions(+) --- arch/arm/configs/mx31litekit_defconfig | 1100 +++++++++++++++++++++++++++++ arch/arm/mach-mx3/Kconfig | 7 + arch/arm/mach-mx3/Makefile | 1 + arch/arm/mach-mx3/mx31lite.c | 96 +++ include/asm-arm/arch-mxc/board-mx31lite.h | 38 + include/asm-arm/arch-mxc/debug-macro.S | 3 + 6 files changed, 1245 insertions(+) create mode 100644 arch/arm/configs/mx31litekit_defconfig create mode 100644 arch/arm/mach-mx3/mx31lite.c create mode 100644 include/asm-arm/arch-mxc/board-mx31lite.h (limited to 'include/asm-arm') diff --git a/arch/arm/configs/mx31litekit_defconfig b/arch/arm/configs/mx31litekit_defconfig new file mode 100644 index 00000000000..4f41c413568 --- /dev/null +++ b/arch/arm/configs/mx31litekit_defconfig @@ -0,0 +1,1100 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc5 +# Fri Jun 13 14:23:39 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_GENERIC_GPIO is not set +# CONFIG_GENERIC_TIME is not set +# CONFIG_GENERIC_CLOCKEVENTS is not set +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +CONFIG_ARCH_MX3=y + +# +# MX3 Options +# +# CONFIG_MACH_MX31ADS is not set +CONFIG_MACH_MX31LITE=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_V6=y +# CONFIG_CPU_32v6K is not set +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +# CONFIG_PCMCIA is not set + +# +# PC-card bridges +# + +# +# Kernel Features +# +# CONFIG_TICK_ONESHOT is not set +CONFIG_PREEMPT=y +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_SUSPEND is not set +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_QUICKCAM_MESSENGER is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_SOC_CAMERA is not set +CONFIG_RADIO_ADAPTERS=y +# CONFIG_USB_DSBR is not set +# CONFIG_USB_SI470X is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 8b7b49a9292..db9431dee1b 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -14,5 +14,12 @@ config MACH_PCM037 Include support for Phytec pcm037 platform. This includes specific configurations for the board and its peripherals. +config MACH_MX31LITE + bool "Support MX31 LITEKIT (LogicPD)" + default n + help + Include support for MX31 LITEKIT platform. This includes specific + configurations for the board and its peripherals. + endmenu diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index b09ca608349..8b21abb71fb 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -6,4 +6,5 @@ obj-y := mm.o clock.o devices.o iomux.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o +obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o obj-$(CONFIG_MACH_PCM037) += pcm037.o diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c new file mode 100644 index 00000000000..ea23a8ec685 --- /dev/null +++ b/arch/arm/mach-mx3/mx31lite.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This file contains the board-specific initialization routines. + */ + +/* + * This structure defines the MX31 memory map. + */ +static struct map_desc mx31lite_io_desc[] __initdata = { + { + .virtual = AIPS1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), + .length = AIPS1_SIZE, + .type = MT_NONSHARED_DEVICE + }, { + .virtual = SPBA0_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), + .length = SPBA0_SIZE, + .type = MT_NONSHARED_DEVICE + }, { + .virtual = AIPS2_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), + .length = AIPS2_SIZE, + .type = MT_NONSHARED_DEVICE + }, { + .virtual = CS4_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(CS4_BASE_ADDR), + .length = CS4_SIZE, + .type = MT_DEVICE + } +}; + +/* + * Set up static virtual mappings. + */ +void __init mx31lite_map_io(void) +{ + mxc_map_io(); + iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc)); +} + +/* + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ +} + +/* + * The following uses standard kernel macros defined in arch.h in order to + * initialize __mach_desc_MX31LITE data structure. + */ + +MACHINE_START(MX31LITE, "LogicPD MX31 LITEKIT") + /* Maintainer: Freescale Semiconductor, Inc. */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx31lite_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/include/asm-arm/arch-mxc/board-mx31lite.h b/include/asm-arm/arch-mxc/board-mx31lite.h new file mode 100644 index 00000000000..e4e5cf5ad7d --- /dev/null +++ b/include/asm-arm/arch-mxc/board-mx31lite.h @@ -0,0 +1,38 @@ +/* + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__ +#define __ASM_ARCH_MXC_BOARD_MX31LITE_H__ + +#define MXC_MAX_EXP_IO_LINES 16 + + +/* + * Memory Size parameters + */ + +/* + * Size of SDRAM memory + */ +#define SDRAM_MEM_SIZE SZ_128M +/* + * Size of MBX buffer memory + */ +#define MXC_MBX_MEM_SIZE SZ_16M +/* + * Size of memory available to kernel + */ +#define MEM_SIZE (SDRAM_MEM_SIZE - MXC_MBX_MEM_SIZE) + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ + diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S index 81caa0aacfe..5add48b6665 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -18,6 +18,9 @@ #endif #ifdef CONFIG_MACH_PCM037 #include +#endif +#ifdef CONFIG_MACH_MX31LITE +#include #endif .macro addruart,rx -- cgit v1.2.3-70-g09d2 From 259bcaae9a2f28d7e3303b202b64a1fb0a9ab9e4 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:54 +0200 Subject: MXC arch: Simplify architecture's irq sources Simplify architecture's irq headers and sources, to share these files between MXC3 and MXC2. Signed-off-by: Juergen Beisert --- arch/arm/plat-mxc/irq.c | 67 +++++++++++++++++++++++++++++++---------- include/asm-arm/arch-mxc/irqs.h | 13 -------- include/asm-arm/arch-mxc/mx31.h | 2 ++ include/asm-arm/arch-mxc/mxc.h | 38 ----------------------- 4 files changed, 53 insertions(+), 67 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c index 88f0cfababd..1fbe01da692 100644 --- a/arch/arm/plat-mxc/irq.c +++ b/arch/arm/plat-mxc/irq.c @@ -1,24 +1,59 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. */ -/* - * 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 -#include -#include -#include -#include -#include +#include #include -#include -#include #include +#define AVIC_BASE IO_ADDRESS(AVIC_BASE_ADDR) +#define AVIC_INTCNTL (AVIC_BASE + 0x00) /* int control reg */ +#define AVIC_NIMASK (AVIC_BASE + 0x04) /* int mask reg */ +#define AVIC_INTENNUM (AVIC_BASE + 0x08) /* int enable number reg */ +#define AVIC_INTDISNUM (AVIC_BASE + 0x0C) /* int disable number reg */ +#define AVIC_INTENABLEH (AVIC_BASE + 0x10) /* int enable reg high */ +#define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */ +#define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */ +#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */ +#define AVIC_NIPRIORITY7 (AVIC_BASE + 0x20) /* norm int priority lvl7 */ +#define AVIC_NIPRIORITY6 (AVIC_BASE + 0x24) /* norm int priority lvl6 */ +#define AVIC_NIPRIORITY5 (AVIC_BASE + 0x28) /* norm int priority lvl5 */ +#define AVIC_NIPRIORITY4 (AVIC_BASE + 0x2C) /* norm int priority lvl4 */ +#define AVIC_NIPRIORITY3 (AVIC_BASE + 0x30) /* norm int priority lvl3 */ +#define AVIC_NIPRIORITY2 (AVIC_BASE + 0x34) /* norm int priority lvl2 */ +#define AVIC_NIPRIORITY1 (AVIC_BASE + 0x38) /* norm int priority lvl1 */ +#define AVIC_NIPRIORITY0 (AVIC_BASE + 0x3C) /* norm int priority lvl0 */ +#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */ +#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */ +#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */ +#define AVIC_INTSRCL (AVIC_BASE + 0x4C) /* int source reg low */ +#define AVIC_INTFRCH (AVIC_BASE + 0x50) /* int force reg high */ +#define AVIC_INTFRCL (AVIC_BASE + 0x54) /* int force reg low */ +#define AVIC_NIPNDH (AVIC_BASE + 0x58) /* norm int pending high */ +#define AVIC_NIPNDL (AVIC_BASE + 0x5C) /* norm int pending low */ +#define AVIC_FIPNDH (AVIC_BASE + 0x60) /* fast int pending high */ +#define AVIC_FIPNDL (AVIC_BASE + 0x64) /* fast int pending low */ + +#define SYSTEM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20) +#define SYSTEM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24) +#define IIM_PROD_REV_SH 3 +#define IIM_PROD_REV_LEN 5 + /* Disable interrupt number "irq" in the AVIC */ static void mxc_mask_irq(unsigned int irq) { @@ -32,7 +67,7 @@ static void mxc_unmask_irq(unsigned int irq) } static struct irq_chip mxc_avic_chip = { - .mask_ack = mxc_mask_irq, + .ack = mxc_mask_irq, .mask = mxc_mask_irq, .unmask = mxc_unmask_irq, }; diff --git a/include/asm-arm/arch-mxc/irqs.h b/include/asm-arm/arch-mxc/irqs.h index b2c5205e196..f416130718c 100644 --- a/include/asm-arm/arch-mxc/irqs.h +++ b/include/asm-arm/arch-mxc/irqs.h @@ -13,17 +13,4 @@ #include -#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) - -#define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_GPIO_INT_BASE) -#define MXC_GPIO_TO_IRQ(x) (MXC_GPIO_INT_BASE + x) - -/* Number of normal interrupts */ -#define NR_IRQS (MXC_MAX_INT_LINES + \ - MXC_MAX_GPIO_LINES + \ - MXC_MAX_VIRTUAL_INTS) - -/* Number of fast interrupts */ -#define NR_FIQS MXC_MAX_INTS - #endif /* __ASM_ARCH_MXC_IRQS_H__ */ diff --git a/include/asm-arm/arch-mxc/mx31.h b/include/asm-arm/arch-mxc/mx31.h index 98e6a4cd1ea..a7373e4a56c 100644 --- a/include/asm-arm/arch-mxc/mx31.h +++ b/include/asm-arm/arch-mxc/mx31.h @@ -320,6 +320,8 @@ #define MXC_MAX_GPIO_LINES (GPIO_NUM_PIN * GPIO_PORT_NUM) #define MXC_MAX_VIRTUAL_INTS 16 +#define NR_IRQS (MXC_MAX_INT_LINES + MXC_MAX_GPIO_LINES + MXC_MAX_VIRTUAL_INTS) + /*! * Number of GPIO port as defined in the IC Spec */ diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h index 1df4e2f2492..3e1c4ded18e 100644 --- a/include/asm-arm/arch-mxc/mxc.h +++ b/include/asm-arm/arch-mxc/mxc.h @@ -29,42 +29,4 @@ # define cpu_is_mx31() (0) #endif -/* - ***************************************** - * AVIC Registers * - ***************************************** - */ -#define AVIC_BASE IO_ADDRESS(AVIC_BASE_ADDR) -#define AVIC_INTCNTL (AVIC_BASE + 0x00) /* int control reg */ -#define AVIC_NIMASK (AVIC_BASE + 0x04) /* int mask reg */ -#define AVIC_INTENNUM (AVIC_BASE + 0x08) /* int enable number reg */ -#define AVIC_INTDISNUM (AVIC_BASE + 0x0C) /* int disable number reg */ -#define AVIC_INTENABLEH (AVIC_BASE + 0x10) /* int enable reg high */ -#define AVIC_INTENABLEL (AVIC_BASE + 0x14) /* int enable reg low */ -#define AVIC_INTTYPEH (AVIC_BASE + 0x18) /* int type reg high */ -#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */ -#define AVIC_NIPRIORITY7 (AVIC_BASE + 0x20) /* norm int priority lvl7 */ -#define AVIC_NIPRIORITY6 (AVIC_BASE + 0x24) /* norm int priority lvl6 */ -#define AVIC_NIPRIORITY5 (AVIC_BASE + 0x28) /* norm int priority lvl5 */ -#define AVIC_NIPRIORITY4 (AVIC_BASE + 0x2C) /* norm int priority lvl4 */ -#define AVIC_NIPRIORITY3 (AVIC_BASE + 0x30) /* norm int priority lvl3 */ -#define AVIC_NIPRIORITY2 (AVIC_BASE + 0x34) /* norm int priority lvl2 */ -#define AVIC_NIPRIORITY1 (AVIC_BASE + 0x38) /* norm int priority lvl1 */ -#define AVIC_NIPRIORITY0 (AVIC_BASE + 0x3C) /* norm int priority lvl0 */ -#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */ -#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */ -#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */ -#define AVIC_INTSRCL (AVIC_BASE + 0x4C) /* int source reg low */ -#define AVIC_INTFRCH (AVIC_BASE + 0x50) /* int force reg high */ -#define AVIC_INTFRCL (AVIC_BASE + 0x54) /* int force reg low */ -#define AVIC_NIPNDH (AVIC_BASE + 0x58) /* norm int pending high */ -#define AVIC_NIPNDL (AVIC_BASE + 0x5C) /* norm int pending low */ -#define AVIC_FIPNDH (AVIC_BASE + 0x60) /* fast int pending high */ -#define AVIC_FIPNDL (AVIC_BASE + 0x64) /* fast int pending low */ - -#define SYSTEM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20) -#define SYSTEM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24) -#define IIM_PROD_REV_SH 3 -#define IIM_PROD_REV_LEN 5 - #endif /* __ASM_ARCH_MXC_H__ */ -- cgit v1.2.3-70-g09d2 From aa10abd381b9493a88f6b9e111adc79e33d548fa Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:55 +0200 Subject: i.MX2 family: Add GPIO multiplexing support This patch adds GPIO multiplexing support for the imx1/mxc2 family of procesors. Signed-off-by: Juergen Beisert --- arch/arm/plat-mxc/Makefile | 2 + arch/arm/plat-mxc/iomux-mx1-mx2.c | 156 +++++++++++++ include/asm-arm/arch-mxc/iomux-mx1-mx2.h | 372 +++++++++++++++++++++++++++++++ 3 files changed, 530 insertions(+) create mode 100644 arch/arm/plat-mxc/iomux-mx1-mx2.c create mode 100644 include/asm-arm/arch-mxc/iomux-mx1-mx2.h (limited to 'include/asm-arm') diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index e3cc25c6d46..db66e9ae841 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -4,3 +4,5 @@ # Common support obj-y := irq.o clock.o gpio.o time.o + +obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o diff --git a/arch/arm/plat-mxc/iomux-mx1-mx2.c b/arch/arm/plat-mxc/iomux-mx1-mx2.c new file mode 100644 index 00000000000..1985571eb40 --- /dev/null +++ b/arch/arm/plat-mxc/iomux-mx1-mx2.c @@ -0,0 +1,156 @@ +/* + * arch/arm/mach-mxc/generic.c + * + * author: Sascha Hauer + * Created: april 20th, 2004 + * Copyright: Synertronixx GmbH + * + * Common code for i.MX machines + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +void mxc_gpio_mode(int gpio_mode) +{ + unsigned int pin = gpio_mode & GPIO_PIN_MASK; + unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; + unsigned int tmp; + + /* Pullup enable */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_PUEN(port)); + if (gpio_mode & GPIO_PUEN) + tmp |= (1 << pin); + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_PUEN(port)); + + /* Data direction */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_DDIR(port)); + if (gpio_mode & GPIO_OUT) + tmp |= 1 << pin; + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_DDIR(port)); + + /* Primary / alternate function */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_GPR(port)); + if (gpio_mode & GPIO_AF) + tmp |= (1 << pin); + else + tmp &= ~(1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_GPR(port)); + + /* use as gpio? */ + tmp = __raw_readl(VA_GPIO_BASE + MXC_GIUS(port)); + if (gpio_mode & (GPIO_PF | GPIO_AF)) + tmp &= ~(1 << pin); + else + tmp |= (1 << pin); + __raw_writel(tmp, VA_GPIO_BASE + MXC_GIUS(port)); + + if (pin < 16) { + tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR1(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA1(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB1(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB1(port)); + } else { + pin -= 16; + + tmp = __raw_readl(VA_GPIO_BASE + MXC_OCR2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + __raw_writel(tmp, VA_GPIO_BASE + MXC_OCR2(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFA2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_AOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFA2(port)); + + tmp = __raw_readl(VA_GPIO_BASE + MXC_ICONFB2(port)); + tmp &= ~(3 << (pin * 2)); + tmp |= ((gpio_mode >> GPIO_BOUT_SHIFT) & 3) << (pin * 2); + __raw_writel(tmp, VA_GPIO_BASE + MXC_ICONFB2(port)); + } +} +EXPORT_SYMBOL(mxc_gpio_mode); + +int mxc_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 & MXC_GPIO_ALLOC_MODE_RELEASE) + gpio_free(gpio); + else if (!(alloc_mode & MXC_GPIO_ALLOC_MODE_NO_ALLOC)) + if (gpio_request(gpio, label) + && !(alloc_mode & MXC_GPIO_ALLOC_MODE_TRY_ALLOC)) + goto setup_error; + + if (!(alloc_mode & (MXC_GPIO_ALLOC_MODE_ALLOC_ONLY | + MXC_GPIO_ALLOC_MODE_RELEASE))) + mxc_gpio_mode(gpio | mode); + + p++; + } + return 0; + +setup_error: + if (alloc_mode & (MXC_GPIO_ALLOC_MODE_NO_ALLOC | + MXC_GPIO_ALLOC_MODE_TRY_ALLOC)) + return -EINVAL; + + while (p != pin_list) { + p--; + gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK); + gpio_free(gpio); + } + + return -EINVAL; +} +EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins); + diff --git a/include/asm-arm/arch-mxc/iomux-mx1-mx2.h b/include/asm-arm/arch-mxc/iomux-mx1-mx2.h new file mode 100644 index 00000000000..076d37b38eb --- /dev/null +++ b/include/asm-arm/arch-mxc/iomux-mx1-mx2.h @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2008 by Sascha Hauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef _MXC_GPIO_MX1_MX2_H +#define _MXC_GPIO_MX1_MX2_H + +#include + +#define MXC_GPIO_ALLOC_MODE_NORMAL 0 +#define MXC_GPIO_ALLOC_MODE_NO_ALLOC 1 +#define MXC_GPIO_ALLOC_MODE_TRY_ALLOC 2 +#define MXC_GPIO_ALLOC_MODE_ALLOC_ONLY 4 +#define MXC_GPIO_ALLOC_MODE_RELEASE 8 + +/* + * GPIO Module and I/O Multiplexer + * x = 0..3 for reg_A, reg_B, reg_C, reg_D + */ +#define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR) +#define MXC_DDIR(x) (0x00 + ((x) << 8)) +#define MXC_OCR1(x) (0x04 + ((x) << 8)) +#define MXC_OCR2(x) (0x08 + ((x) << 8)) +#define MXC_ICONFA1(x) (0x0c + ((x) << 8)) +#define MXC_ICONFA2(x) (0x10 + ((x) << 8)) +#define MXC_ICONFB1(x) (0x14 + ((x) << 8)) +#define MXC_ICONFB2(x) (0x18 + ((x) << 8)) +#define MXC_DR(x) (0x1c + ((x) << 8)) +#define MXC_GIUS(x) (0x20 + ((x) << 8)) +#define MXC_SSR(x) (0x24 + ((x) << 8)) +#define MXC_ICR1(x) (0x28 + ((x) << 8)) +#define MXC_ICR2(x) (0x2c + ((x) << 8)) +#define MXC_IMR(x) (0x30 + ((x) << 8)) +#define MXC_ISR(x) (0x34 + ((x) << 8)) +#define MXC_GPR(x) (0x38 + ((x) << 8)) +#define MXC_SWR(x) (0x3c + ((x) << 8)) +#define MXC_PUEN(x) (0x40 + ((x) << 8)) + +#ifdef CONFIG_ARCH_MX1 +# define GPIO_PORT_MAX 3 +#endif +#ifdef CONFIG_ARCH_MX2 +# define GPIO_PORT_MAX 5 +#endif + +#ifndef GPIO_PORT_MAX +# error "GPIO config port count unknown!" +#endif + +#define GPIO_PIN_MASK 0x1f + +#define GPIO_PORT_SHIFT 5 +#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) + +#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) + +#define GPIO_OUT (1 << 8) +#define GPIO_IN (0 << 8) +#define GPIO_PUEN (1 << 9) + +#define GPIO_PF (1 << 10) +#define GPIO_AF (1 << 11) + +#define GPIO_OCR_SHIFT 12 +#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) +#define GPIO_AIN (0 << GPIO_OCR_SHIFT) +#define GPIO_BIN (1 << GPIO_OCR_SHIFT) +#define GPIO_CIN (2 << GPIO_OCR_SHIFT) +#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) + +#define GPIO_AOUT_SHIFT 14 +#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) + +#define GPIO_BOUT_SHIFT 16 +#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) + +extern void mxc_gpio_mode(int gpio_mode); +extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, + int alloc_mode, const char *label); + +/*-------------------------------------------------------------------------*/ + +/* assignements for GPIO alternate/primary functions */ + +/* FIXME: This list is not completed. The correct directions are + * missing on some (many) pins + */ +#ifdef CONFIG_ARCH_MX1 +#define PA0_AIN_SPI2_CLK (GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 0) +#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0) +#define PA1_AOUT_SPI2_RXD (GPIO_GIUS | GPIO_PORTA | GPIO_IN | 1) +#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1) +#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 2) +#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3) +#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4) +#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5) +#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6) +#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7) +#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8) +#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9) +#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10) +#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11) +#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12) +#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13) +#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14) +#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15) +#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16) +#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17) +#define PA17_AIN_SPI2_SS (GPIO_GIUS | GPIO_PORTA | GPIO_OUT | 17) +#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18) +#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19) +#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20) +#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21) +#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22) +#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23) +#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24) +#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24) +#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25) +#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25) +#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26) +#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26) +#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27) +#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27) +#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28) +#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28) +#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29) +#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29) +#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30) +#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30) +#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31) +#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31) +#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8) +#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8) +#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9) +#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9) +#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10) +#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10) +#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11) +#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11) +#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12) +#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12) +#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13) +#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13) +#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14) +#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15) +#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_IN | GPIO_AF | 16) +#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_OUT | GPIO_AF | 17) +#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18) +#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19) +#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20) +#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21) +#define PB22_PFUSBD_RCV (GPIO_PORTB | GPIO_PF | 22) +#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23) +#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24) +#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25) +#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26) +#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27) +#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_OUT | GPIO_PF | 28) +#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_IN | GPIO_PF | 29) +#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_OUT | GPIO_PF | 30) +#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_IN | GPIO_PF | 31) +#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3) +#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4) +#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_IN | GPIO_PF | 5) +#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_OUT | GPIO_PF | 6) +#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7) +#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8) +#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_OUT | GPIO_PF | 9) +#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_IN | GPIO_PF | 10) +#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_OUT | GPIO_PF | 11) +#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 12) +#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13) +#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14) +#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15) +#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16) +#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17) +#define PC24_BIN_UART3_RI (GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 24) +#define PC25_BIN_UART3_DSR (GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 25) +#define PC26_AOUT_UART3_DTR (GPIO_GIUS | GPIO_PORTC | GPIO_IN | 26) +#define PC27_BIN_UART3_DCD (GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 27) +#define PC28_BIN_UART3_CTS (GPIO_GIUS | GPIO_PORTC | GPIO_OUT | GPIO_BIN | 28) +#define PC29_AOUT_UART3_RTS (GPIO_GIUS | GPIO_PORTC | GPIO_IN | 29) +#define PC30_BIN_UART3_TX (GPIO_GIUS | GPIO_PORTC | GPIO_BIN | 30) +#define PC31_AOUT_UART3_RX (GPIO_GIUS | GPIO_PORTC | GPIO_IN | 31) +#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 6) +#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7) +#define PD7_AF_UART2_DTR (GPIO_GIUS | GPIO_PORTD | GPIO_IN | GPIO_AF | 7) +#define PD7_AIN_SPI2_SCLK (GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 7) +#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8) +#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_OUT | GPIO_AF | 8) +#define PD8_AIN_SPI2_SS (GPIO_GIUS | GPIO_PORTD | GPIO_AIN | 8) +#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9) +#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_OUT | GPIO_AF | 9) +#define PD9_AOUT_SPI2_RXD (GPIO_GIUS | GPIO_PORTD | GPIO_IN | 9) +#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_OUT | GPIO_PF | 10) +#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_OUT | GPIO_AF | 10) +#define PD10_AIN_SPI2_TXD (GPIO_GIUS | GPIO_PORTD | GPIO_OUT | 10) +#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_OUT | GPIO_PF | 11) +#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_OUT | GPIO_PF | 12) +#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_OUT | GPIO_PF | 13) +#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_OUT | GPIO_PF | 14) +#define PD15_PF_LD0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 15) +#define PD16_PF_LD1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 16) +#define PD17_PF_LD2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17) +#define PD18_PF_LD3 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18) +#define PD19_PF_LD4 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 19) +#define PD20_PF_LD5 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 20) +#define PD21_PF_LD6 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 21) +#define PD22_PF_LD7 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 22) +#define PD23_PF_LD8 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 23) +#define PD24_PF_LD9 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 24) +#define PD25_PF_LD10 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25) +#define PD26_PF_LD11 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26) +#define PD27_PF_LD12 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27) +#define PD28_PF_LD13 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28) +#define PD29_PF_LD14 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29) +#define PD30_PF_LD15 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 30) +#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31) +#define PD31_BIN_SPI2_TXD (GPIO_GIUS | GPIO_PORTD | GPIO_BIN | 31) +#endif + +#ifdef CONFIG_ARCH_MX2 +#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_OUT | GPIO_PF | 5) +#define PA6_PF_LD0 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 6) +#define PA7_PF_LD1 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 7) +#define PA8_PF_LD2 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 8) +#define PA9_PF_LD3 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 9) +#define PA10_PF_LD4 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 10) +#define PA11_PF_LD5 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 11) +#define PA12_PF_LD6 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 12) +#define PA13_PF_LD7 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 13) +#define PA14_PF_LD8 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 14) +#define PA15_PF_LD9 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15) +#define PA16_PF_LD10 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16) +#define PA17_PF_LD11 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 17) +#define PA18_PF_LD12 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 18) +#define PA19_PF_LD13 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 19) +#define PA20_PF_LD14 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 20) +#define PA21_PF_LD15 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 21) +#define PA22_PF_LD16 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 22) +#define PA23_PF_LD17 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 23) +#define PA24_PF_REV (GPIO_PORTA | GPIO_OUT | GPIO_PF | 24) +#define PA25_PF_CLS (GPIO_PORTA | GPIO_OUT | GPIO_PF | 25) +#define PA26_PF_PS (GPIO_PORTA | GPIO_OUT | GPIO_PF | 26) +#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_OUT | GPIO_PF | 27) +#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_OUT | GPIO_PF | 28) +#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_OUT | GPIO_PF | 29) +#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_OUT | GPIO_PF | 30) +#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_OUT | GPIO_PF | 31) +#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 10) +#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 10) +#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 11) +#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 11) +#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 12) +#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 12) +#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 13) +#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_IN | GPIO_AF | 13) +#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 14) +#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_OUT | GPIO_PF | 15) +#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_OUT | GPIO_PF | 16) +#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 17) +#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 18) +#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 18) +#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 19) +#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 19) +#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_OUT | GPIO_PF | 20) +#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 20) +#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_OUT | GPIO_PF | 21) +#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_IN | GPIO_AF | 21) +#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_IN | GPIO_PF | 26) +#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 28) +#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 29) +#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 31) +#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_IN | GPIO_PF | 5) +#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_IN | GPIO_PF | 6) +#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 16) +#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 17) +#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 18) +#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 19) +#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 20) +#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 21) +#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 22) +#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 23) +#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 24) +#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 25) +#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 26) +#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 27) +#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 28) +#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 29) +#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 30) +#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 31) +#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 0) +#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 1) +#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 2) +#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 3) +#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 4) +#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 5) +#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 6) +#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 7) +#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_IN | GPIO_AF | 8) +#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 9) +#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 10) +#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 11) +#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 12) +#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 13) +#define PD14_AOUT_FEC_CLR (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 14) +#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 15) +#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 16) +#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17) +#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18) +#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25) +#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26) +#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27) +#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28) +#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29) +#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_IN | GPIO_PF | 30) +#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_OUT | GPIO_PF | 31) +#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_OUT | GPIO_AIN | 23) +#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 3) +#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 4) +#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 6) +#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 7) +#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 8) +#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 9) +#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 10) +#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 11) +#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 12) +#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 13) +#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 14) +#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 15) +#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_IN | GPIO_AF | 18) +#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_OUT | GPIO_AF | 21) +#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_OUT | GPIO_AF | 22) +#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_OUT | GPIO_AF | 23) +#endif + +/* decode irq number to use with IMR(x), ISR(x) and friends */ +#define IRQ_TO_REG(irq) ((irq - MXC_MAX_INT_LINES) >> 5) + +#define IRQ_GPIOA(x) (MXC_MAX_INT_LINES + x) +#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x) +#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x) +#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x) + +#endif /* _MXC_GPIO_MX1_MX2_H */ -- cgit v1.2.3-70-g09d2 From 32dc80c9cb13a7ce686bcc26efcf39e35719b466 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:56 +0200 Subject: i.MX2 family: Add basic mach support (headers) This patch adds basic mach support for the mx2 processor family, based on the original freescale code and adapted to mainline kernel coding style. Signed-off-by: Juergen Beisert --- arch/arm/mach-mx2/crm_regs.h | 273 ++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-mxc/hardware.h | 3 + include/asm-arm/arch-mxc/iim.h | 77 ++++++++++ 3 files changed, 353 insertions(+) create mode 100644 arch/arm/mach-mx2/crm_regs.h create mode 100644 include/asm-arm/arch-mxc/iim.h (limited to 'include/asm-arm') diff --git a/arch/arm/mach-mx2/crm_regs.h b/arch/arm/mach-mx2/crm_regs.h new file mode 100644 index 00000000000..a40a9b950ce --- /dev/null +++ b/arch/arm/mach-mx2/crm_regs.h @@ -0,0 +1,273 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ARCH_ARM_MACH_MX2_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX2_CRM_REGS_H__ + +#include + +/* Register offsets */ +#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0) +#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4) +#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8) +#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC) +#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) +#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) +#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) +#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c) +#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) +#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) +#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) +#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c) +#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) +#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) + +#define CCM_CSCR_USB_OFFSET 28 +#define CCM_CSCR_USB_MASK (0x7 << 28) +#define CCM_CSCR_SD_OFFSET 24 +#define CCM_CSCR_SD_MASK (0x3 << 24) +#define CCM_CSCR_SSI2 (1 << 23) +#define CCM_CSCR_SSI2_OFFSET 23 +#define CCM_CSCR_SSI1 (1 << 22) +#define CCM_CSCR_SSI1_OFFSET 22 +#define CCM_CSCR_VPU (1 << 21) +#define CCM_CSCR_VPU_OFFSET 21 +#define CCM_CSCR_MSHC (1 << 20) +#define CCM_CSCR_SPLLRES (1 << 19) +#define CCM_CSCR_MPLLRES (1 << 18) +#define CCM_CSCR_SP (1 << 17) +#define CCM_CSCR_MCU (1 << 16) +/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_ARM_SRC (1 << 15) +#define CCM_CSCR_ARM_OFFSET 12 +#define CCM_CSCR_ARM_MASK (0x3 << 12) +/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_PRESC_OFFSET 13 +#define CCM_CSCR_PRESC_MASK (0x7 << 13) +#define CCM_CSCR_BCLK_OFFSET 9 +#define CCM_CSCR_BCLK_MASK (0xf << 9) +#define CCM_CSCR_IPDIV_OFFSET 8 +#define CCM_CSCR_IPDIV (1 << 8) +/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_AHB_OFFSET 8 +#define CCM_CSCR_AHB_MASK (0x3 << 8) +/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/ +#define CCM_CSCR_OSC26MDIV (1 << 4) +#define CCM_CSCR_OSC26M (1 << 3) +#define CCM_CSCR_FPM (1 << 2) +#define CCM_CSCR_SPEN (1 << 1) +#define CCM_CSCR_MPEN 1 + +#define CCM_MPCTL0_CPLM (1 << 31) +#define CCM_MPCTL0_PD_OFFSET 26 +#define CCM_MPCTL0_PD_MASK (0xf << 26) +#define CCM_MPCTL0_MFD_OFFSET 16 +#define CCM_MPCTL0_MFD_MASK (0x3ff << 16) +#define CCM_MPCTL0_MFI_OFFSET 10 +#define CCM_MPCTL0_MFI_MASK (0xf << 10) +#define CCM_MPCTL0_MFN_OFFSET 0 +#define CCM_MPCTL0_MFN_MASK 0x3ff + +#define CCM_MPCTL1_LF (1 << 15) +#define CCM_MPCTL1_BRMO (1 << 6) + +#define CCM_SPCTL0_CPLM (1 << 31) +#define CCM_SPCTL0_PD_OFFSET 26 +#define CCM_SPCTL0_PD_MASK (0xf << 26) +#define CCM_SPCTL0_MFD_OFFSET 16 +#define CCM_SPCTL0_MFD_MASK (0x3ff << 16) +#define CCM_SPCTL0_MFI_OFFSET 10 +#define CCM_SPCTL0_MFI_MASK (0xf << 10) +#define CCM_SPCTL0_MFN_OFFSET 0 +#define CCM_SPCTL0_MFN_MASK 0x3ff + +#define CCM_SPCTL1_LF (1 << 15) +#define CCM_SPCTL1_BRMO (1 << 6) + +#define CCM_OSC26MCTL_PEAK_OFFSET 16 +#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16) +#define CCM_OSC26MCTL_AGC_OFFSET 8 +#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8) +#define CCM_OSC26MCTL_ANATEST_OFFSET 0 +#define CCM_OSC26MCTL_ANATEST_MASK 0x3f + +#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26 +#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26) +#define CCM_PCDR0_CLKO_EN 25 +#define CCM_PCDR0_CLKODIV_OFFSET 22 +#define CCM_PCDR0_CLKODIV_MASK (0x7 << 22) +#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16 +#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16) +/*The difinition for i.MX27 TO2*/ +#define CCM_PCDR0_VPUDIV2_OFFSET 10 +#define CCM_PCDR0_VPUDIV2_MASK (0x3f << 10) +#define CCM_PCDR0_NFCDIV2_OFFSET 6 +#define CCM_PCDR0_NFCDIV2_MASK (0xf << 6) +#define CCM_PCDR0_MSHCDIV2_MASK 0x3f +/*The difinition for i.MX27 TO2*/ +#define CCM_PCDR0_NFCDIV_OFFSET 12 +#define CCM_PCDR0_NFCDIV_MASK (0xf << 12) +#define CCM_PCDR0_VPUDIV_OFFSET 8 +#define CCM_PCDR0_VPUDIV_MASK (0xf << 8) +#define CCM_PCDR0_MSHCDIV_OFFSET 0 +#define CCM_PCDR0_MSHCDIV_MASK 0x1f + +#define CCM_PCDR1_PERDIV4_OFFSET 24 +#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24) +#define CCM_PCDR1_PERDIV3_OFFSET 16 +#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16) +#define CCM_PCDR1_PERDIV2_OFFSET 8 +#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8) +#define CCM_PCDR1_PERDIV1_OFFSET 0 +#define CCM_PCDR1_PERDIV1_MASK 0x3f + +#define CCM_PCCR0_CSPI1_OFFSET 31 +#define CCM_PCCR0_CSPI1_MASK (1 << 31) +#define CCM_PCCR0_CSPI2_OFFSET 30 +#define CCM_PCCR0_CSPI2_MASK (1 << 30) +#define CCM_PCCR0_CSPI3_OFFSET 29 +#define CCM_PCCR0_CSPI3_MASK (1 << 29) +#define CCM_PCCR0_DMA_OFFSET 28 +#define CCM_PCCR0_DMA_MASK (1 << 28) +#define CCM_PCCR0_EMMA_OFFSET 27 +#define CCM_PCCR0_EMMA_MASK (1 << 27) +#define CCM_PCCR0_FEC_OFFSET 26 +#define CCM_PCCR0_FEC_MASK (1 << 26) +#define CCM_PCCR0_GPIO_OFFSET 25 +#define CCM_PCCR0_GPIO_MASK (1 << 25) +#define CCM_PCCR0_GPT1_OFFSET 24 +#define CCM_PCCR0_GPT1_MASK (1 << 24) +#define CCM_PCCR0_GPT2_OFFSET 23 +#define CCM_PCCR0_GPT2_MASK (1 << 23) +#define CCM_PCCR0_GPT3_OFFSET 22 +#define CCM_PCCR0_GPT3_MASK (1 << 22) +#define CCM_PCCR0_GPT4_OFFSET 21 +#define CCM_PCCR0_GPT4_MASK (1 << 21) +#define CCM_PCCR0_GPT5_OFFSET 20 +#define CCM_PCCR0_GPT5_MASK (1 << 20) +#define CCM_PCCR0_GPT6_OFFSET 19 +#define CCM_PCCR0_GPT6_MASK (1 << 19) +#define CCM_PCCR0_I2C1_OFFSET 18 +#define CCM_PCCR0_I2C1_MASK (1 << 18) +#define CCM_PCCR0_I2C2_OFFSET 17 +#define CCM_PCCR0_I2C2_MASK (1 << 17) +#define CCM_PCCR0_IIM_OFFSET 16 +#define CCM_PCCR0_IIM_MASK (1 << 16) +#define CCM_PCCR0_KPP_OFFSET 15 +#define CCM_PCCR0_KPP_MASK (1 << 15) +#define CCM_PCCR0_LCDC_OFFSET 14 +#define CCM_PCCR0_LCDC_MASK (1 << 14) +#define CCM_PCCR0_MSHC_OFFSET 13 +#define CCM_PCCR0_MSHC_MASK (1 << 13) +#define CCM_PCCR0_OWIRE_OFFSET 12 +#define CCM_PCCR0_OWIRE_MASK (1 << 12) +#define CCM_PCCR0_PWM_OFFSET 11 +#define CCM_PCCR0_PWM_MASK (1 << 11) +#define CCM_PCCR0_RTC_OFFSET 9 +#define CCM_PCCR0_RTC_MASK (1 << 9) +#define CCM_PCCR0_RTIC_OFFSET 8 +#define CCM_PCCR0_RTIC_MASK (1 << 8) +#define CCM_PCCR0_SAHARA_OFFSET 7 +#define CCM_PCCR0_SAHARA_MASK (1 << 7) +#define CCM_PCCR0_SCC_OFFSET 6 +#define CCM_PCCR0_SCC_MASK (1 << 6) +#define CCM_PCCR0_SDHC1_OFFSET 5 +#define CCM_PCCR0_SDHC1_MASK (1 << 5) +#define CCM_PCCR0_SDHC2_OFFSET 4 +#define CCM_PCCR0_SDHC2_MASK (1 << 4) +#define CCM_PCCR0_SDHC3_OFFSET 3 +#define CCM_PCCR0_SDHC3_MASK (1 << 3) +#define CCM_PCCR0_SLCDC_OFFSET 2 +#define CCM_PCCR0_SLCDC_MASK (1 << 2) +#define CCM_PCCR0_SSI1_IPG_OFFSET 1 +#define CCM_PCCR0_SSI1_IPG_MASK (1 << 1) +#define CCM_PCCR0_SSI2_IPG_OFFSET 0 +#define CCM_PCCR0_SSI2_IPG_MASK (1 << 0) + +#define CCM_PCCR1_UART1_OFFSET 31 +#define CCM_PCCR1_UART1_MASK (1 << 31) +#define CCM_PCCR1_UART2_OFFSET 30 +#define CCM_PCCR1_UART2_MASK (1 << 30) +#define CCM_PCCR1_UART3_OFFSET 29 +#define CCM_PCCR1_UART3_MASK (1 << 29) +#define CCM_PCCR1_UART4_OFFSET 28 +#define CCM_PCCR1_UART4_MASK (1 << 28) +#define CCM_PCCR1_UART5_OFFSET 27 +#define CCM_PCCR1_UART5_MASK (1 << 27) +#define CCM_PCCR1_UART6_OFFSET 26 +#define CCM_PCCR1_UART6_MASK (1 << 26) +#define CCM_PCCR1_USBOTG_OFFSET 25 +#define CCM_PCCR1_USBOTG_MASK (1 << 25) +#define CCM_PCCR1_WDT_OFFSET 24 +#define CCM_PCCR1_WDT_MASK (1 << 24) +#define CCM_PCCR1_HCLK_ATA_OFFSET 23 +#define CCM_PCCR1_HCLK_ATA_MASK (1 << 23) +#define CCM_PCCR1_HCLK_BROM_OFFSET 22 +#define CCM_PCCR1_HCLK_BROM_MASK (1 << 22) +#define CCM_PCCR1_HCLK_CSI_OFFSET 21 +#define CCM_PCCR1_HCLK_CSI_MASK (1 << 21) +#define CCM_PCCR1_HCLK_DMA_OFFSET 20 +#define CCM_PCCR1_HCLK_DMA_MASK (1 << 20) +#define CCM_PCCR1_HCLK_EMI_OFFSET 19 +#define CCM_PCCR1_HCLK_EMI_MASK (1 << 19) +#define CCM_PCCR1_HCLK_EMMA_OFFSET 18 +#define CCM_PCCR1_HCLK_EMMA_MASK (1 << 18) +#define CCM_PCCR1_HCLK_FEC_OFFSET 17 +#define CCM_PCCR1_HCLK_FEC_MASK (1 << 17) +#define CCM_PCCR1_HCLK_VPU_OFFSET 16 +#define CCM_PCCR1_HCLK_VPU_MASK (1 << 16) +#define CCM_PCCR1_HCLK_LCDC_OFFSET 15 +#define CCM_PCCR1_HCLK_LCDC_MASK (1 << 15) +#define CCM_PCCR1_HCLK_RTIC_OFFSET 14 +#define CCM_PCCR1_HCLK_RTIC_MASK (1 << 14) +#define CCM_PCCR1_HCLK_SAHARA_OFFSET 13 +#define CCM_PCCR1_HCLK_SAHARA_MASK (1 << 13) +#define CCM_PCCR1_HCLK_SLCDC_OFFSET 12 +#define CCM_PCCR1_HCLK_SLCDC_MASK (1 << 12) +#define CCM_PCCR1_HCLK_USBOTG_OFFSET 11 +#define CCM_PCCR1_HCLK_USBOTG_MASK (1 << 11) +#define CCM_PCCR1_PERCLK1_OFFSET 10 +#define CCM_PCCR1_PERCLK1_MASK (1 << 10) +#define CCM_PCCR1_PERCLK2_OFFSET 9 +#define CCM_PCCR1_PERCLK2_MASK (1 << 9) +#define CCM_PCCR1_PERCLK3_OFFSET 8 +#define CCM_PCCR1_PERCLK3_MASK (1 << 8) +#define CCM_PCCR1_PERCLK4_OFFSET 7 +#define CCM_PCCR1_PERCLK4_MASK (1 << 7) +#define CCM_PCCR1_VPU_BAUD_OFFSET 6 +#define CCM_PCCR1_VPU_BAUD_MASK (1 << 6) +#define CCM_PCCR1_SSI1_BAUD_OFFSET 5 +#define CCM_PCCR1_SSI1_BAUD_MASK (1 << 5) +#define CCM_PCCR1_SSI2_BAUD_OFFSET 4 +#define CCM_PCCR1_SSI2_BAUD_MASK (1 << 4) +#define CCM_PCCR1_NFC_BAUD_OFFSET 3 +#define CCM_PCCR1_NFC_BAUD_MASK (1 << 3) +#define CCM_PCCR1_MSHC_BAUD_OFFSET 2 +#define CCM_PCCR1_MSHC_BAUD_MASK (1 << 2) + +#define CCM_CCSR_32KSR (1 << 15) +#define CCM_CCSR_CLKMODE1 (1 << 9) +#define CCM_CCSR_CLKMODE0 (1 << 8) +#define CCM_CCSR_CLKOSEL_OFFSET 0 +#define CCM_CCSR_CLKOSEL_MASK 0x1f + +#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */ +#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ + +#endif /* __ARCH_ARM_MACH_MX2_CRM_REGS_H__ */ diff --git a/include/asm-arm/arch-mxc/hardware.h b/include/asm-arm/arch-mxc/hardware.h index 4ed2d8072d0..f841127ef75 100644 --- a/include/asm-arm/arch-mxc/hardware.h +++ b/include/asm-arm/arch-mxc/hardware.h @@ -26,6 +26,9 @@ # include #endif +#ifdef CONFIG_ARCH_MX2 +#endif + #include #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ diff --git a/include/asm-arm/arch-mxc/iim.h b/include/asm-arm/arch-mxc/iim.h new file mode 100644 index 00000000000..315bffadafd --- /dev/null +++ b/include/asm-arm/arch-mxc/iim.h @@ -0,0 +1,77 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_IIM_H__ +#define __ASM_ARCH_MXC_IIM_H__ + +/* Register offsets */ +#define MXC_IIMSTAT 0x0000 +#define MXC_IIMSTATM 0x0004 +#define MXC_IIMERR 0x0008 +#define MXC_IIMEMASK 0x000C +#define MXC_IIMFCTL 0x0010 +#define MXC_IIMUA 0x0014 +#define MXC_IIMLA 0x0018 +#define MXC_IIMSDAT 0x001C +#define MXC_IIMPREV 0x0020 +#define MXC_IIMSREV 0x0024 +#define MXC_IIMPRG_P 0x0028 +#define MXC_IIMSCS0 0x002C +#define MXC_IIMSCS1 0x0030 +#define MXC_IIMSCS2 0x0034 +#define MXC_IIMSCS3 0x0038 +#define MXC_IIMFBAC0 0x0800 +#define MXC_IIMJAC 0x0804 +#define MXC_IIMHWV1 0x0808 +#define MXC_IIMHWV2 0x080C +#define MXC_IIMHAB0 0x0810 +#define MXC_IIMHAB1 0x0814 +/* Definitions for i.MX27 TO2 */ +#define MXC_IIMMAC 0x0814 +#define MXC_IIMPREV_FUSE 0x0818 +#define MXC_IIMSREV_FUSE 0x081C +#define MXC_IIMSJC_CHALL_0 0x0820 +#define MXC_IIMSJC_CHALL_7 0x083C +#define MXC_IIMFB0UC17 0x0840 +#define MXC_IIMFB0UC255 0x0BFC +#define MXC_IIMFBAC1 0x0C00 +/* Definitions for i.MX27 TO2 */ +#define MXC_IIMSUID 0x0C04 +#define MXC_IIMKEY0 0x0C04 +#define MXC_IIMKEY20 0x0C54 +#define MXC_IIMSJC_RESP_0 0x0C58 +#define MXC_IIMSJC_RESP_7 0x0C74 +#define MXC_IIMFB1UC30 0x0C78 +#define MXC_IIMFB1UC255 0x0FFC + +/* Bit definitions */ + +#define MXC_IIMHWV1_WLOCK (0x1 << 7) +#define MXC_IIMHWV1_MCU_ENDIAN (0x1 << 6) +#define MXC_IIMHWV1_DSP_ENDIAN (0x1 << 5) +#define MXC_IIMHWV1_BOOT_INT (0x1 << 4) +#define MXC_IIMHWV1_SCC_DISABLE (0x1 << 3) +#define MXC_IIMHWV1_HANTRO_DISABLE (0x1 << 2) +#define MXC_IIMHWV1_MEMSTICK_DIS (0x1 << 1) + +#define MXC_IIMHWV2_WLOCK (0x1 << 7) +#define MXC_IIMHWV2_BP_SDMA (0x1 << 6) +#define MXC_IIMHWV2_SCM_DCM (0x1 << 5) + +#endif /* __ASM_ARCH_MXC_IIM_H__ */ -- cgit v1.2.3-70-g09d2 From f31405cc4cc568baad28273c7f45b0563b57a17d Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:02:59 +0200 Subject: i.MX27 CPU: Add basic i.MX27 CPU support Add basic i.MX27 CPU support Signed-off-by: Juergen Beisert --- arch/arm/mach-mx2/Kconfig | 6 + arch/arm/mach-mx2/Makefile | 2 + arch/arm/mach-mx2/cpu_imx27.c | 63 ++++++++ include/asm-arm/arch-mxc/hardware.h | 3 + include/asm-arm/arch-mxc/mx27.h | 302 ++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-mxc/mxc.h | 4 + 6 files changed, 380 insertions(+) create mode 100644 arch/arm/mach-mx2/cpu_imx27.c create mode 100644 include/asm-arm/arch-mxc/mx27.h (limited to 'include/asm-arm') diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 23def05fea0..6e7d724e323 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -1,5 +1,11 @@ comment "MX2 family CPU support" depends on ARCH_MX2 +config MACH_MX27 + bool "i.MX27 support" + depends on ARCH_MX2 + help + This enables support for Freescale's MX2 based i.MX27 processor. + comment "MX2 Platforms" depends on ARCH_MX2 diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index f8f8ecb01c9..c9eac3b1e13 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -5,3 +5,5 @@ # Object file lists. obj-y := system.o generic.o devices.o serial.o + +obj-$(CONFIG_MACH_MX27) += cpu_imx27.o diff --git a/arch/arm/mach-mx2/cpu_imx27.c b/arch/arm/mach-mx2/cpu_imx27.c new file mode 100644 index 00000000000..d6b5c2e3377 --- /dev/null +++ b/arch/arm/mach-mx2/cpu_imx27.c @@ -0,0 +1,63 @@ +/* + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* + * i.MX27 specific CPU detection code + */ + +#include +#include + +#include + +#include "crm_regs.h" + +static int cpu_silicon_rev = -1; +static int cpu_partnumber; + +static void query_silicon_parameter(void) +{ + u32 val; + /* + * now we have access to the IO registers. As we need + * the silicon revision very early we read it here to + * avoid any further hooks + */ + val = __raw_readl(IO_ADDRESS(SYSCTRL_BASE_ADDR) + SYS_CHIP_ID); + + cpu_silicon_rev = (int)(val >> 28); + cpu_partnumber = (int)((val >> 12) & 0xFFFF); +} + +/* + * Returns: + * the silicon revision of the cpu + * -EINVAL - not a mx27 + */ +int mx27_revision(void) +{ + if (cpu_silicon_rev == -1) + query_silicon_parameter(); + + if (cpu_partnumber != 0x8821) + return -EINVAL; + + return cpu_silicon_rev; +} +EXPORT_SYMBOL(mx27_revision); diff --git a/include/asm-arm/arch-mxc/hardware.h b/include/asm-arm/arch-mxc/hardware.h index f841127ef75..37cddbaaade 100644 --- a/include/asm-arm/arch-mxc/hardware.h +++ b/include/asm-arm/arch-mxc/hardware.h @@ -27,6 +27,9 @@ #endif #ifdef CONFIG_ARCH_MX2 +# ifdef CONFIG_MACH_MX27 +# include +# endif #endif #include diff --git a/include/asm-arm/arch-mxc/mx27.h b/include/asm-arm/arch-mxc/mx27.h new file mode 100644 index 00000000000..212ecc24662 --- /dev/null +++ b/include/asm-arm/arch-mxc/mx27.h @@ -0,0 +1,302 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_MX27_H__ +#define __ASM_ARCH_MXC_MX27_H__ + +#ifndef __ASM_ARCH_MXC_HARDWARE_H__ +#error "Do not include directly." +#endif + +/* IRAM */ +#define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */ + +/* Register offests */ +#define AIPI_BASE_ADDR 0x10000000 +#define AIPI_BASE_ADDR_VIRT 0xF4000000 +#define AIPI_SIZE SZ_1M + +#define DMA_BASE_ADDR (AIPI_BASE_ADDR + 0x01000) +#define WDOG_BASE_ADDR (AIPI_BASE_ADDR + 0x02000) +#define GPT1_BASE_ADDR (AIPI_BASE_ADDR + 0x03000) +#define GPT2_BASE_ADDR (AIPI_BASE_ADDR + 0x04000) +#define GPT3_BASE_ADDR (AIPI_BASE_ADDR + 0x05000) +#define PWM_BASE_ADDR (AIPI_BASE_ADDR + 0x06000) +#define RTC_BASE_ADDR (AIPI_BASE_ADDR + 0x07000) +#define KPP_BASE_ADDR (AIPI_BASE_ADDR + 0x08000) +#define OWIRE_BASE_ADDR (AIPI_BASE_ADDR + 0x09000) +#define UART1_BASE_ADDR (AIPI_BASE_ADDR + 0x0A000) +#define UART2_BASE_ADDR (AIPI_BASE_ADDR + 0x0B000) +#define UART3_BASE_ADDR (AIPI_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (AIPI_BASE_ADDR + 0x0D000) +#define CSPI1_BASE_ADDR (AIPI_BASE_ADDR + 0x0E000) +#define CSPI2_BASE_ADDR (AIPI_BASE_ADDR + 0x0F000) +#define SSI1_BASE_ADDR (AIPI_BASE_ADDR + 0x10000) +#define SSI2_BASE_ADDR (AIPI_BASE_ADDR + 0x11000) +#define I2C_BASE_ADDR (AIPI_BASE_ADDR + 0x12000) +#define SDHC1_BASE_ADDR (AIPI_BASE_ADDR + 0x13000) +#define SDHC2_BASE_ADDR (AIPI_BASE_ADDR + 0x14000) +#define GPIO_BASE_ADDR (AIPI_BASE_ADDR + 0x15000) +#define AUDMUX_BASE_ADDR (AIPI_BASE_ADDR + 0x16000) + +#define CSPI3_BASE_ADDR (AIPI_BASE_ADDR + 0x17000) +#define MSHC_BASE_ADDR (AIPI_BASE_ADDR + 0x18000) +#define GPT5_BASE_ADDR (AIPI_BASE_ADDR + 0x19000) +#define GPT4_BASE_ADDR (AIPI_BASE_ADDR + 0x1A000) +#define UART5_BASE_ADDR (AIPI_BASE_ADDR + 0x1B000) +#define UART6_BASE_ADDR (AIPI_BASE_ADDR + 0x1C000) +#define I2C2_BASE_ADDR (AIPI_BASE_ADDR + 0x1D000) +#define SDHC3_BASE_ADDR (AIPI_BASE_ADDR + 0x1E000) +#define GPT6_BASE_ADDR (AIPI_BASE_ADDR + 0x1F000) + +#define LCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x21000) +#define SLCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x22000) +#define VPU_BASE_ADDR (AIPI_BASE_ADDR + 0x23000) +#define USBOTG_BASE_ADDR (AIPI_BASE_ADDR + 0x24000) +/* for mx27*/ +#define OTG_BASE_ADDR USBOTG_BASE_ADDR +#define SAHARA_BASE_ADDR (AIPI_BASE_ADDR + 0x25000) +#define EMMA_BASE_ADDR (AIPI_BASE_ADDR + 0x26400) +#define CCM_BASE_ADDR (AIPI_BASE_ADDR + 0x27000) +#define SYSCTRL_BASE_ADDR (AIPI_BASE_ADDR + 0x27800) +#define IIM_BASE_ADDR (AIPI_BASE_ADDR + 0x28000) + +#define RTIC_BASE_ADDR (AIPI_BASE_ADDR + 0x2A000) +#define FEC_BASE_ADDR (AIPI_BASE_ADDR + 0x2B000) +#define SCC_BASE_ADDR (AIPI_BASE_ADDR + 0x2C000) +#define ETB_BASE_ADDR (AIPI_BASE_ADDR + 0x3B000) +#define ETB_RAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3C000) + +#define JAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3E000) +#define MAX_BASE_ADDR (AIPI_BASE_ADDR + 0x3F000) + +/* ROMP and AVIC */ +#define ROMP_BASE_ADDR 0x10041000 + +#define AVIC_BASE_ADDR 0x10040000 + +#define SAHB1_BASE_ADDR 0x80000000 +#define SAHB1_BASE_ADDR_VIRT 0xF4100000 +#define SAHB1_SIZE SZ_1M + +#define CSI_BASE_ADDR (SAHB1_BASE_ADDR + 0x0000) +#define ATA_BASE_ADDR (SAHB1_BASE_ADDR + 0x1000) + +/* NAND, SDRAM, WEIM, M3IF, EMI controllers */ +#define X_MEMC_BASE_ADDR 0xD8000000 +#define X_MEMC_BASE_ADDR_VIRT 0xF4200000 +#define X_MEMC_SIZE SZ_1M + +#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR) +#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) +#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) +#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) +#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) + +/* Memory regions and CS */ +#define SDRAM_BASE_ADDR 0xA0000000 +#define CSD1_BASE_ADDR 0xB0000000 + +#define CS0_BASE_ADDR 0xC0000000 +#define CS1_BASE_ADDR 0xC8000000 +#define CS2_BASE_ADDR 0xD0000000 +#define CS3_BASE_ADDR 0xD2000000 +#define CS4_BASE_ADDR 0xD4000000 +#define CS5_BASE_ADDR 0xD6000000 +#define PCMCIA_MEM_BASE_ADDR 0xDC000000 + +/* + * This macro defines the physical to virtual address mapping for all the + * peripheral modules. It is used by passing in the physical address as x + * and returning the virtual address. If the physical address is not mapped, + * it returns 0xDEADBEEF + */ +#define IO_ADDRESS(x) \ + (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \ + AIPI_IO_ADDRESS(x) : \ + ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \ + SAHB1_IO_ADDRESS(x) : \ + ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \ + X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF) + +/* define the address mapping macros: in physical address order */ +#define AIPI_IO_ADDRESS(x) \ + (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT) + +#define AVIC_IO_ADDRESS(x) AIPI_IO_ADDRESS(x) + +#define SAHB1_IO_ADDRESS(x) \ + (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT) + +#define CS4_IO_ADDRESS(x) \ + (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT) + +#define X_MEMC_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +#define PCMCIA_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +/* fixed interrput numbers */ +#define MXC_INT_CCM 63 +#define MXC_INT_IIM 62 +#define MXC_INT_LCDC 61 +#define MXC_INT_SLCDC 60 +#define MXC_INT_SAHARA 59 +#define MXC_INT_SCC_SCM 58 +#define MXC_INT_SCC_SMN 57 +#define MXC_INT_USB3 56 +#define MXC_INT_USB2 55 +#define MXC_INT_USB1 54 +#define MXC_INT_VPU 53 +#define MXC_INT_EMMAPP 52 +#define MXC_INT_EMMAPRP 51 +#define MXC_INT_FEC 50 +#define MXC_INT_UART5 49 +#define MXC_INT_UART6 48 +#define MXC_INT_DMACH15 47 +#define MXC_INT_DMACH14 46 +#define MXC_INT_DMACH13 45 +#define MXC_INT_DMACH12 44 +#define MXC_INT_DMACH11 43 +#define MXC_INT_DMACH10 42 +#define MXC_INT_DMACH9 41 +#define MXC_INT_DMACH8 40 +#define MXC_INT_DMACH7 39 +#define MXC_INT_DMACH6 38 +#define MXC_INT_DMACH5 37 +#define MXC_INT_DMACH4 36 +#define MXC_INT_DMACH3 35 +#define MXC_INT_DMACH2 34 +#define MXC_INT_DMACH1 33 +#define MXC_INT_DMACH0 32 +#define MXC_INT_CSI 31 +#define MXC_INT_ATA 30 +#define MXC_INT_NANDFC 29 +#define MXC_INT_PCMCIA 28 +#define MXC_INT_WDOG 27 +#define MXC_INT_GPT1 26 +#define MXC_INT_GPT2 25 +#define MXC_INT_GPT3 24 +#define MXC_INT_GPT INT_GPT1 +#define MXC_INT_PWM 23 +#define MXC_INT_RTC 22 +#define MXC_INT_KPP 21 +#define MXC_INT_UART1 20 +#define MXC_INT_UART2 19 +#define MXC_INT_UART3 18 +#define MXC_INT_UART4 17 +#define MXC_INT_CSPI1 16 +#define MXC_INT_CSPI2 15 +#define MXC_INT_SSI1 14 +#define MXC_INT_SSI2 13 +#define MXC_INT_I2C 12 +#define MXC_INT_SDHC1 11 +#define MXC_INT_SDHC2 10 +#define MXC_INT_SDHC3 9 +#define MXC_INT_GPIO 8 +#define MXC_INT_SDHC 7 +#define MXC_INT_CSPI3 6 +#define MXC_INT_RTIC 5 +#define MXC_INT_GPT4 4 +#define MXC_INT_GPT5 3 +#define MXC_INT_GPT6 2 +#define MXC_INT_I2C2 1 + +/* fixed DMA request numbers */ +#define DMA_REQ_NFC 37 +#define DMA_REQ_SDHC3 36 +#define DMA_REQ_UART6_RX 35 +#define DMA_REQ_UART6_TX 34 +#define DMA_REQ_UART5_RX 33 +#define DMA_REQ_UART5_TX 32 +#define DMA_REQ_CSI_RX 31 +#define DMA_REQ_CSI_STAT 30 +#define DMA_REQ_ATA_RCV 29 +#define DMA_REQ_ATA_TX 28 +#define DMA_REQ_UART1_TX 27 +#define DMA_REQ_UART1_RX 26 +#define DMA_REQ_UART2_TX 25 +#define DMA_REQ_UART2_RX 24 +#define DMA_REQ_UART3_TX 23 +#define DMA_REQ_UART3_RX 22 +#define DMA_REQ_UART4_TX 21 +#define DMA_REQ_UART4_RX 20 +#define DMA_REQ_CSPI1_TX 19 +#define DMA_REQ_CSPI1_RX 18 +#define DMA_REQ_CSPI2_TX 17 +#define DMA_REQ_CSPI2_RX 16 +#define DMA_REQ_SSI1_TX1 15 +#define DMA_REQ_SSI1_RX1 14 +#define DMA_REQ_SSI1_TX0 13 +#define DMA_REQ_SSI1_RX0 12 +#define DMA_REQ_SSI2_TX1 11 +#define DMA_REQ_SSI2_RX1 10 +#define DMA_REQ_SSI2_TX0 9 +#define DMA_REQ_SSI2_RX0 8 +#define DMA_REQ_SDHC1 7 +#define DMA_REQ_SDHC2 6 +#define DMA_REQ_MSHC 4 +#define DMA_REQ_EXT 3 +#define DMA_REQ_CSPI3_TX 2 +#define DMA_REQ_CSPI3_RX 1 + +/* silicon revisions specific to i.MX27 */ +#define CHIP_REV_1_0 0x00 +#define CHIP_REV_2_0 0x01 + +#ifndef __ASSEMBLY__ +extern int mx27_revision(void); +#endif + +/* gpio and gpio based interrupt handling */ +#define GPIO_DR 0x1C +#define GPIO_GDIR 0x00 +#define GPIO_PSR 0x24 +#define GPIO_ICR1 0x28 +#define GPIO_ICR2 0x2C +#define GPIO_IMR 0x30 +#define GPIO_ISR 0x34 +#define GPIO_INT_LOW_LEV 0x3 +#define GPIO_INT_HIGH_LEV 0x2 +#define GPIO_INT_RISE_EDGE 0x0 +#define GPIO_INT_FALL_EDGE 0x1 +#define GPIO_INT_NONE 0x4 + +/* Mandatory defines used globally */ + +/* this is an i.MX27 CPU */ +#define cpu_is_mx27() (1) + +/* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */ +#define ARCH_NR_GPIOS (192 + 16) + +/* OS clock tick rate */ +#define CLOCK_TICK_RATE 13300000 + +/* Start of RAM */ +#define PHYS_OFFSET SDRAM_BASE_ADDR + +/* max interrupt lines count */ +#define NR_IRQS 256 + +/* count of internal interrupt sources */ +#define MXC_MAX_INT_LINES 64 + +#endif /* __ASM_ARCH_MXC_MX27_H__ */ diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h index 3e1c4ded18e..332eda4dbd3 100644 --- a/include/asm-arm/arch-mxc/mxc.h +++ b/include/asm-arm/arch-mxc/mxc.h @@ -29,4 +29,8 @@ # define cpu_is_mx31() (0) #endif +#ifndef CONFIG_MACH_MX27 +# define cpu_is_mx27() (0) +#endif + #endif /* __ASM_ARCH_MXC_H__ */ -- cgit v1.2.3-70-g09d2 From 80eedae6f0322dafc749140b67986b2472473745 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:00 +0200 Subject: i.MX27: Add ADS platform support This patch adds basic support for the Freescale MX27ADS reference board. Currently only a serial console can be used. Signed-off-by: Juergen Beisert --- arch/arm/configs/imx27ads_defconfig | 826 +++++++++++++++++++++++++++++++ arch/arm/mach-mx2/Kconfig | 7 + arch/arm/mach-mx2/Makefile | 2 + arch/arm/mach-mx2/mx27ads.c | 304 ++++++++++++ include/asm-arm/arch-mxc/board-mx27ads.h | 354 +++++++++++++ include/asm-arm/arch-mxc/debug-macro.S | 4 +- 6 files changed, 1496 insertions(+), 1 deletion(-) create mode 100644 arch/arm/configs/imx27ads_defconfig create mode 100644 arch/arm/mach-mx2/mx27ads.c create mode 100644 include/asm-arm/arch-mxc/board-mx27ads.h (limited to 'include/asm-arm') diff --git a/arch/arm/configs/imx27ads_defconfig b/arch/arm/configs/imx27ads_defconfig new file mode 100644 index 00000000000..bcd95b8dd2d --- /dev/null +++ b/arch/arm/configs/imx27ads_defconfig @@ -0,0 +1,826 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc6 +# Fri Jun 20 16:29:34 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +CONFIG_ARCH_MX2=y +# CONFIG_ARCH_MX3 is not set + +# +# MX2 family CPU support +# +CONFIG_MACH_MX27=y + +# +# MX2 Platforms +# +CONFIG_MACH_MX27ADS=y +# CONFIG_MACH_PCM038 is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x00000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +# CONFIG_FEC_OLD is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_IMX is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 6e7d724e323..6f98355d686 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -9,3 +9,10 @@ config MACH_MX27 comment "MX2 Platforms" depends on ARCH_MX2 + +config MACH_MX27ADS + bool "MX27ADS platform" + depends on MACH_MX27 + help + Include support for MX27ADS platform. This includes specific + configurations for the board and its peripherals. diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index 74fb9b3eb06..f6764eb6471 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -8,3 +8,5 @@ obj-y := system.o generic.o devices.o serial.o obj-$(CONFIG_MACH_MX27) += cpu_imx27.o obj-$(CONFIG_MACH_MX27) += clock_imx27.o + +obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c new file mode 100644 index 00000000000..a9ff01fff13 --- /dev/null +++ b/arch/arm/mach-mx2/mx27ads.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* ADS's NOR flash */ +static struct physmap_flash_data mx27ads_flash_data = { + .width = 2, +}; + +static struct resource mx27ads_flash_resource = { + .start = 0xc0000000, + .end = 0xc0000000 + 0x02000000 - 1, + .flags = IORESOURCE_MEM, + +}; + +static struct platform_device mx27ads_nor_mtd_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &mx27ads_flash_data, + }, + .num_resources = 1, + .resource = &mx27ads_flash_resource, +}; + +static int mxc_uart0_pins[] = { + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + PE14_PF_UART1_CTS, + PE15_PF_UART1_RTS +}; + +static int uart_mxc_port0_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart0_pins, + ARRAY_SIZE(mxc_uart0_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART0"); +} + +static int uart_mxc_port0_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart0_pins, + ARRAY_SIZE(mxc_uart0_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART0"); +} + +static int mxc_uart1_pins[] = { + PE3_PF_UART2_CTS, + PE4_PF_UART2_RTS, + PE6_PF_UART2_TXD, + PE7_PF_UART2_RXD +}; + +static int uart_mxc_port1_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart1_pins, + ARRAY_SIZE(mxc_uart1_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART1"); +} + +static int uart_mxc_port1_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart1_pins, + ARRAY_SIZE(mxc_uart1_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART1"); +} + +static int mxc_uart2_pins[] = { + PE8_PF_UART3_TXD, + PE9_PF_UART3_RXD, + PE10_PF_UART3_CTS, + PE11_PF_UART3_RTS +}; + +static int uart_mxc_port2_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart2_pins, + ARRAY_SIZE(mxc_uart2_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART2"); +} + +static int uart_mxc_port2_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart2_pins, + ARRAY_SIZE(mxc_uart2_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART2"); +} + +static int mxc_uart3_pins[] = { + PB26_AF_UART4_RTS, + PB28_AF_UART4_TXD, + PB29_AF_UART4_CTS, + PB31_AF_UART4_RXD +}; + +static int uart_mxc_port3_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart3_pins, + ARRAY_SIZE(mxc_uart3_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART3"); +} + +static int uart_mxc_port3_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart3_pins, + ARRAY_SIZE(mxc_uart3_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART3"); +} + +static int mxc_uart4_pins[] = { + PB18_AF_UART5_TXD, + PB19_AF_UART5_RXD, + PB20_AF_UART5_CTS, + PB21_AF_UART5_RTS +}; + +static int uart_mxc_port4_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart4_pins, + ARRAY_SIZE(mxc_uart4_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART4"); +} + +static int uart_mxc_port4_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart4_pins, + ARRAY_SIZE(mxc_uart4_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART4"); +} + +static int mxc_uart5_pins[] = { + PB10_AF_UART6_TXD, + PB12_AF_UART6_CTS, + PB11_AF_UART6_RXD, + PB13_AF_UART6_RTS +}; + +static int uart_mxc_port5_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart5_pins, + ARRAY_SIZE(mxc_uart5_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART5"); +} + +static int uart_mxc_port5_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart5_pins, + ARRAY_SIZE(mxc_uart5_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART5"); +} + +static struct platform_device *platform_devices[] __initdata = { + &mx27ads_nor_mtd_device, +}; + +static int mxc_fec_pins[] = { + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_CLR, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN +}; + +static void gpio_fec_active(void) +{ + mxc_gpio_setup_multiple_pins(mxc_fec_pins, + ARRAY_SIZE(mxc_fec_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "FEC"); +} + +static void gpio_fec_inactive(void) +{ + mxc_gpio_setup_multiple_pins(mxc_fec_pins, + ARRAY_SIZE(mxc_fec_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "FEC"); +} + +static struct imxuart_platform_data uart_pdata[] = { + { + .init = uart_mxc_port0_init, + .exit = uart_mxc_port0_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port1_init, + .exit = uart_mxc_port1_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port2_init, + .exit = uart_mxc_port2_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port3_init, + .exit = uart_mxc_port3_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port4_init, + .exit = uart_mxc_port4_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port5_init, + .exit = uart_mxc_port5_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, +}; + +static void __init mx27ads_board_init(void) +{ + int i; + + gpio_fec_active(); + + for (i = 0; i < 6; i++) + imx_init_uart(i, &uart_pdata[i]); + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} + +static void __init mx27ads_timer_init(void) +{ + unsigned long fref = 26000000; + + if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) + fref = 27000000; + + mxc_clocks_init(fref); + mxc_timer_init("gpt_clk.0"); +} + +struct sys_timer mx27ads_timer = { + .init = mx27ads_timer_init, +}; + +static struct map_desc mx27ads_io_desc[] __initdata = { + { + .virtual = PBC_BASE_ADDRESS, + .pfn = __phys_to_pfn(CS4_BASE_ADDR), + .length = SZ_1M, + .type = MT_DEVICE, + }, +}; + +void __init mx27ads_map_io(void) +{ + mxc_map_io(); + iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc)); +} + +MACHINE_START(MX27ADS, "Freescale i.MX27ADS") + /* maintainer: Freescale Semiconductor, Inc. */ + .phys_io = AIPI_BASE_ADDR, + .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx27ads_map_io, + .init_irq = mxc_init_irq, + .init_machine = mx27ads_board_init, + .timer = &mx27ads_timer, +MACHINE_END + diff --git a/include/asm-arm/arch-mxc/board-mx27ads.h b/include/asm-arm/arch-mxc/board-mx27ads.h new file mode 100644 index 00000000000..61e66dac90e --- /dev/null +++ b/include/asm-arm/arch-mxc/board-mx27ads.h @@ -0,0 +1,354 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX27ADS_H__ +#define __ASM_ARCH_MXC_BOARD_MX27ADS_H__ + +/* external interrupt multiplexer */ +#define MXC_EXP_IO_BASE (MXC_GPIO_BASE + MXC_MAX_GPIO_LINES) + +#define MXC_VIRTUAL_INTS_BASE (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES) +#define MXC_SDIO1_CARD_IRQ MXC_VIRTUAL_INTS_BASE +#define MXC_SDIO2_CARD_IRQ (MXC_VIRTUAL_INTS_BASE + 1) +#define MXC_SDIO3_CARD_IRQ (MXC_VIRTUAL_INTS_BASE + 2) + +#define MXC_MAX_BOARD_INTS (MXC_MAX_EXP_IO_LINES + \ + MXC_MAX_VIRTUAL_INTS) + +/* + * MXC UART EVB board level configurations + */ + +#define MXC_LL_EXTUART_PADDR (CS4_BASE_ADDR + 0x20000) +#define MXC_LL_EXTUART_VADDR (CS4_BASE_ADDR_VIRT + 0x20000) +#define MXC_LL_EXTUART_16BIT_BUS + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR) + +/* + * @name Memory Size parameters + */ + +/* + * Size of SDRAM memory + */ +#define SDRAM_MEM_SIZE SZ_128M + +/* + * PBC Controller parameters + */ + +/* + * Base address of PBC controller, CS4 + */ +#define PBC_BASE_ADDRESS 0xEB000000 +#define PBC_REG_ADDR(offset) (PBC_BASE_ADDRESS + (offset)) + +/* + * PBC Interupt name definitions + */ +#define PBC_GPIO1_0 0 +#define PBC_GPIO1_1 1 +#define PBC_GPIO1_2 2 +#define PBC_GPIO1_3 3 +#define PBC_GPIO1_4 4 +#define PBC_GPIO1_5 5 + +#define PBC_INTR_MAX_NUM 6 +#define PBC_INTR_SHARED_MAX_NUM 8 + +/* When the PBC address connection is fixed in h/w, defined as 1 */ +#define PBC_ADDR_SH 0 + +/* Offsets for the PBC Controller register */ +/* + * PBC Board version register offset + */ +#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH) +/* + * PBC Board control register 1 set address. + */ +#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH) +/* + * PBC Board control register 1 clear address. + */ +#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH) +/* + * PBC Board control register 2 set address. + */ +#define PBC_BCTRL2_SET_REG PBC_REG_ADDR(0x00010 >> PBC_ADDR_SH) +/* + * PBC Board control register 2 clear address. + */ +#define PBC_BCTRL2_CLEAR_REG PBC_REG_ADDR(0x00014 >> PBC_ADDR_SH) +/* + * PBC Board control register 3 set address. + */ +#define PBC_BCTRL3_SET_REG PBC_REG_ADDR(0x00018 >> PBC_ADDR_SH) +/* + * PBC Board control register 3 clear address. + */ +#define PBC_BCTRL3_CLEAR_REG PBC_REG_ADDR(0x0001C >> PBC_ADDR_SH) +/* + * PBC Board control register 3 set address. + */ +#define PBC_BCTRL4_SET_REG PBC_REG_ADDR(0x00020 >> PBC_ADDR_SH) +/* + * PBC Board control register 4 clear address. + */ +#define PBC_BCTRL4_CLEAR_REG PBC_REG_ADDR(0x00024 >> PBC_ADDR_SH) +/*PBC_ADDR_SH + * PBC Board status register 1. + */ +#define PBC_BSTAT1_REG PBC_REG_ADDR(0x00028 >> PBC_ADDR_SH) +/* + * PBC Board interrupt status register. + */ +#define PBC_INTSTATUS_REG PBC_REG_ADDR(0x0002C >> PBC_ADDR_SH) +/* + * PBC Board interrupt current status register. + */ +#define PBC_INTCURR_STATUS_REG PBC_REG_ADDR(0x00034 >> PBC_ADDR_SH) +/* + * PBC Interrupt mask register set address. + */ +#define PBC_INTMASK_SET_REG PBC_REG_ADDR(0x00038 >> PBC_ADDR_SH) +/* + * PBC Interrupt mask register clear address. + */ +#define PBC_INTMASK_CLEAR_REG PBC_REG_ADDR(0x0003C >> PBC_ADDR_SH) +/* + * External UART A. + */ +#define PBC_SC16C652_UARTA_REG PBC_REG_ADDR(0x20000 >> PBC_ADDR_SH) +/* + * UART 4 Expanding Signal Status. + */ +#define PBC_UART_STATUS_REG PBC_REG_ADDR(0x22000 >> PBC_ADDR_SH) +/* + * UART 4 Expanding Signal Control Set. + */ +#define PBC_UCTRL_SET_REG PBC_REG_ADDR(0x24000 >> PBC_ADDR_SH) +/* + * UART 4 Expanding Signal Control Clear. + */ +#define PBC_UCTRL_CLR_REG PBC_REG_ADDR(0x26000 >> PBC_ADDR_SH) +/* + * Ethernet Controller IO base address. + */ +#define PBC_CS8900A_IOBASE_REG PBC_REG_ADDR(0x40000 >> PBC_ADDR_SH) +/* + * Ethernet Controller Memory base address. + */ +#define PBC_CS8900A_MEMBASE_REG PBC_REG_ADDR(0x42000 >> PBC_ADDR_SH) +/* + * Ethernet Controller DMA base address. + */ +#define PBC_CS8900A_DMABASE_REG PBC_REG_ADDR(0x44000 >> PBC_ADDR_SH) + +/* PBC Board Version Register bit definition */ +#define PBC_VERSION_ADS 0x8000 /* Bit15=1 means version for ads */ +#define PBC_VERSION_EVB_REVB 0x4000 /* BIT14=1 means version for evb revb */ + +/* PBC Board Control Register 1 bit definitions */ +#define PBC_BCTRL1_ERST 0x0001 /* Ethernet Reset */ +#define PBC_BCTRL1_URST 0x0002 /* Reset External UART controller */ +#define PBC_BCTRL1_FRST 0x0004 /* FEC Reset */ +#define PBC_BCTRL1_ESLEEP 0x0010 /* Enable ethernet Sleep */ +#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */ + +/* PBC Board Control Register 2 bit definitions */ +#define PBC_BCTRL2_VCC_EN 0x0004 /* Enable VCC */ +#define PBC_BCTRL2_VPP_EN 0x0008 /* Enable Vpp */ +#define PBC_BCTRL2_ATAFEC_EN 0X0010 +#define PBC_BCTRL2_ATAFEC_SEL 0X0020 +#define PBC_BCTRL2_ATA_EN 0X0040 +#define PBC_BCTRL2_IRDA_SD 0X0080 +#define PBC_BCTRL2_IRDA_EN 0X0100 +#define PBC_BCTRL2_CCTL10 0X0200 +#define PBC_BCTRL2_CCTL11 0X0400 + +/* PBC Board Control Register 3 bit definitions */ +#define PBC_BCTRL3_HSH_EN 0X0020 +#define PBC_BCTRL3_FSH_MOD 0X0040 +#define PBC_BCTRL3_OTG_HS_EN 0X0080 +#define PBC_BCTRL3_OTG_VBUS_EN 0X0100 +#define PBC_BCTRL3_FSH_VBUS_EN 0X0200 +#define PBC_BCTRL3_USB_OTG_ON 0X0800 +#define PBC_BCTRL3_USB_FSH_ON 0X1000 + +/* PBC Board Control Register 4 bit definitions */ +#define PBC_BCTRL4_REGEN_SEL 0X0001 +#define PBC_BCTRL4_USER_OFF 0X0002 +#define PBC_BCTRL4_VIB_EN 0X0004 +#define PBC_BCTRL4_PWRGT1_EN 0X0008 +#define PBC_BCTRL4_PWRGT2_EN 0X0010 +#define PBC_BCTRL4_STDBY_PRI 0X0020 + +#ifndef __ASSEMBLY__ +/* + * Enumerations for SD cards and memory stick card. This corresponds to + * the card EN bits in the IMR: SD1_EN | MS_EN | SD3_EN | SD2_EN. + */ +enum mxc_card_no { + MXC_CARD_SD2 = 0, + MXC_CARD_SD3, + MXC_CARD_MS, + MXC_CARD_SD1, + MXC_CARD_MIN = MXC_CARD_SD2, + MXC_CARD_MAX = MXC_CARD_SD1, +}; +#endif + +#define MXC_CPLD_VER_1_50 0x01 + +/* + * PBC BSTAT Register bit definitions + */ +#define PBC_BSTAT_PRI_INT 0X0001 +#define PBC_BSTAT_USB_BYP 0X0002 +#define PBC_BSTAT_ATA_IOCS16 0X0004 +#define PBC_BSTAT_ATA_CBLID 0X0008 +#define PBC_BSTAT_ATA_DASP 0X0010 +#define PBC_BSTAT_PWR_RDY 0X0020 +#define PBC_BSTAT_SD3_WP 0X0100 +#define PBC_BSTAT_SD2_WP 0X0200 +#define PBC_BSTAT_SD1_WP 0X0400 +#define PBC_BSTAT_SD3_DET 0X0800 +#define PBC_BSTAT_SD2_DET 0X1000 +#define PBC_BSTAT_SD1_DET 0X2000 +#define PBC_BSTAT_MS_DET 0X4000 +#define PBC_BSTAT_SD3_DET_BIT 11 +#define PBC_BSTAT_SD2_DET_BIT 12 +#define PBC_BSTAT_SD1_DET_BIT 13 +#define PBC_BSTAT_MS_DET_BIT 14 +#define MXC_BSTAT_BIT(n) ((n == MXC_CARD_SD2) ? PBC_BSTAT_SD2_DET : \ + ((n == MXC_CARD_SD3) ? PBC_BSTAT_SD3_DET : \ + ((n == MXC_CARD_SD1) ? PBC_BSTAT_SD1_DET : \ + ((n == MXC_CARD_MS) ? PBC_BSTAT_MS_DET : \ + 0x0)))) + +/* + * PBC UART Control Register bit definitions + */ +#define PBC_UCTRL_DCE_DCD 0X0001 +#define PBC_UCTRL_DCE_DSR 0X0002 +#define PBC_UCTRL_DCE_RI 0X0004 +#define PBC_UCTRL_DTE_DTR 0X0100 + +/* + * PBC UART Status Register bit definitions + */ +#define PBC_USTAT_DTE_DCD 0X0001 +#define PBC_USTAT_DTE_DSR 0X0002 +#define PBC_USTAT_DTE_RI 0X0004 +#define PBC_USTAT_DCE_DTR 0X0100 + +/* + * PBC Interupt mask register bit definitions + */ +#define PBC_INTR_SD3_R_EN_BIT 4 +#define PBC_INTR_SD2_R_EN_BIT 0 +#define PBC_INTR_SD1_R_EN_BIT 6 +#define PBC_INTR_MS_R_EN_BIT 5 +#define PBC_INTR_SD3_EN_BIT 13 +#define PBC_INTR_SD2_EN_BIT 12 +#define PBC_INTR_MS_EN_BIT 14 +#define PBC_INTR_SD1_EN_BIT 15 + +#define PBC_INTR_SD2_R_EN 0x0001 +#define PBC_INTR_LOW_BAT 0X0002 +#define PBC_INTR_OTG_FSOVER 0X0004 +#define PBC_INTR_FSH_OVER 0X0008 +#define PBC_INTR_SD3_R_EN 0x0010 +#define PBC_INTR_MS_R_EN 0x0020 +#define PBC_INTR_SD1_R_EN 0x0040 +#define PBC_INTR_FEC_INT 0X0080 +#define PBC_INTR_ENET_INT 0X0100 +#define PBC_INTR_OTGFS_INT 0X0200 +#define PBC_INTR_XUART_INT 0X0400 +#define PBC_INTR_CCTL12 0X0800 +#define PBC_INTR_SD2_EN 0x1000 +#define PBC_INTR_SD3_EN 0x2000 +#define PBC_INTR_MS_EN 0x4000 +#define PBC_INTR_SD1_EN 0x8000 + + + +/* For interrupts like xuart, enet etc */ +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX27_PIN_TIN) +#define MXC_MAX_EXP_IO_LINES 16 + +/* + * This corresponds to PBC_INTMASK_SET_REG at offset 0x38. + * + */ +#define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 1) +#define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2) +#define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3) +#define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4) +#define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5) +#define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6) +#define EXPIO_INT_FEC (MXC_EXP_IO_BASE + 7) +#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) +#define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9) +#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) +#define EXPIO_INT_CCTL12_INT (MXC_EXP_IO_BASE + 11) +#define EXPIO_INT_SD2_EN (MXC_EXP_IO_BASE + 12) +#define EXPIO_INT_SD3_EN (MXC_EXP_IO_BASE + 13) +#define EXPIO_INT_MS_EN (MXC_EXP_IO_BASE + 14) +#define EXPIO_INT_SD1_EN (MXC_EXP_IO_BASE + 15) + +/* + * This is System IRQ used by CS8900A for interrupt generation + * taken from platform.h + */ +#define CS8900AIRQ EXPIO_INT_ENET_INT +/* This is I/O Base address used to access registers of CS8900A on MXC ADS */ +#define CS8900A_BASE_ADDRESS (PBC_CS8900A_IOBASE_REG + 0x300) + +#define MXC_PMIC_INT_LINE IOMUX_TO_IRQ(MX27_PIN_TOUT) + +/* +* This is used to detect if the CPLD version is for mx27 evb board rev-a +*/ +#define PBC_CPLD_VERSION_IS_REVA() \ + ((__raw_readw(PBC_VERSION_REG) & \ + (PBC_VERSION_ADS | PBC_VERSION_EVB_REVB))\ + == 0) + +/* This is used to active or inactive ata signal in CPLD . + * It is dependent with hardware + */ +#define PBC_ATA_SIGNAL_ACTIVE() \ + __raw_writew( \ + PBC_BCTRL2_ATAFEC_EN|PBC_BCTRL2_ATAFEC_SEL|PBC_BCTRL2_ATA_EN, \ + PBC_BCTRL2_CLEAR_REG) + +#define PBC_ATA_SIGNAL_INACTIVE() \ + __raw_writew( \ + PBC_BCTRL2_ATAFEC_EN|PBC_BCTRL2_ATAFEC_SEL|PBC_BCTRL2_ATA_EN, \ + PBC_BCTRL2_SET_REG) + +#define MXC_BD_LED1 (1 << 5) +#define MXC_BD_LED2 (1 << 6) +#define MXC_BD_LED_ON(led) \ + __raw_writew(led, PBC_BCTRL1_SET_REG) +#define MXC_BD_LED_OFF(led) \ + __raw_writew(led, PBC_BCTRL1_CLEAR_REG) + +/* to determine the correct external crystal reference */ +#define CKIH_27MHZ_BIT_SET (1 << 3) + +#endif /* __ASM_ARCH_MXC_BOARD_MX27ADS_H__ */ diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S index 5add48b6665..c6c56805143 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -22,7 +22,9 @@ #ifdef CONFIG_MACH_MX31LITE #include #endif - +#ifdef CONFIG_MACH_MX27ADS +#include +#endif .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? -- cgit v1.2.3-70-g09d2 From 7e5e9f5457f5cd019fd7e2f3da94e9fc72cc9ff6 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:00 +0200 Subject: i.MX27: Adding PCM038 platform support This patch adds support for the phyCORE-i.MX27 cpu module (aka pcm038). It is as generic as possible in order to support any kind of baseboard. Note: This CPU module implementation can't work without a baseboard support. Baseboard support can be added by the PCM-970 (included in this patch stack) or any custom variant. Signed-off-by: Juergen Beisert --- arch/arm/configs/pcm038_defconfig | 1008 +++++++++++++++++++++++++++++++ arch/arm/mach-mx2/Kconfig | 7 + arch/arm/mach-mx2/Makefile | 1 + arch/arm/mach-mx2/pcm038.c | 200 ++++++ include/asm-arm/arch-mxc/board-pcm038.h | 36 ++ include/asm-arm/arch-mxc/debug-macro.S | 3 + 6 files changed, 1255 insertions(+) create mode 100644 arch/arm/configs/pcm038_defconfig create mode 100644 arch/arm/mach-mx2/pcm038.c create mode 100644 include/asm-arm/arch-mxc/board-pcm038.h (limited to 'include/asm-arm') diff --git a/arch/arm/configs/pcm038_defconfig b/arch/arm/configs/pcm038_defconfig new file mode 100644 index 00000000000..6b798c215ca --- /dev/null +++ b/arch/arm/configs/pcm038_defconfig @@ -0,0 +1,1008 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc6 +# Fri Jun 20 16:38:36 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +# CONFIG_COMPAT_BRK is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_KRETPROBES=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +CONFIG_ARCH_MXC=y +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM7X00A is not set + +# +# Boot options +# + +# +# Power management +# + +# +# Freescale MXC Implementations +# +CONFIG_ARCH_MX2=y +# CONFIG_ARCH_MX3 is not set + +# +# MX2 family CPU support +# +CONFIG_MACH_MX27=y + +# +# MX2 Platforms +# +# CONFIG_MACH_MX27ADS is not set +CONFIG_MACH_PCM038=y +CONFIG_MACH_PCM970_BASEBOARD=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_TCPPROBE is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x00000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +CONFIG_FEC_OLD=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_PLATFORM is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_TPS65010 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_HAVE_GPIO_LIB=y + +# +# GPIO Support +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +# CONFIG_LOGO is not set + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_DRV_PCF8563=y +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_UIO is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 6f98355d686..4c19e1c7947 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -16,3 +16,10 @@ config MACH_MX27ADS help Include support for MX27ADS platform. This includes specific configurations for the board and its peripherals. + +config MACH_PCM038 + bool "Phytec phyCORE-i.MX27 CPU module (pcm038)" + depends on MACH_MX27 + help + Include support for phyCORE-i.MX27 (aka pcm038) platform. This + includes specific configurations for the module and its peripherals. diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index f6764eb6471..f8d3836ee2f 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_MACH_MX27) += cpu_imx27.o obj-$(CONFIG_MACH_MX27) += clock_imx27.o obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o +obj-$(CONFIG_MACH_PCM038) += pcm038.o diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c new file mode 100644 index 00000000000..46fc026138c --- /dev/null +++ b/arch/arm/mach-mx2/pcm038.c @@ -0,0 +1,200 @@ +/* + * Copyright 2007 Robert Schwebel , Pengutronix + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Phytec's phyCORE-i.MX27 comes with 32MiB flash, + * 16 bit width + */ +static struct physmap_flash_data pcm038_flash_data = { + .width = 2, +}; + +static struct resource pcm038_flash_resource = { + .start = 0xc0000000, + .end = 0xc1ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device pcm038_nor_mtd_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &pcm038_flash_data, + }, + .num_resources = 1, + .resource = &pcm038_flash_resource, +}; + +static int mxc_uart0_pins[] = { + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + PE14_PF_UART1_CTS, + PE15_PF_UART1_RTS +}; + +static int uart_mxc_port0_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart0_pins, + ARRAY_SIZE(mxc_uart0_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART0"); +} + +static int uart_mxc_port0_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart0_pins, + ARRAY_SIZE(mxc_uart0_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART0"); +} + +static int mxc_uart1_pins[] = { + PE3_PF_UART2_CTS, + PE4_PF_UART2_RTS, + PE6_PF_UART2_TXD, + PE7_PF_UART2_RXD +}; + +static int uart_mxc_port1_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart1_pins, + ARRAY_SIZE(mxc_uart1_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART1"); +} + +static int uart_mxc_port1_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart1_pins, + ARRAY_SIZE(mxc_uart1_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART1"); +} + +static int mxc_uart2_pins[] = { PE10_PF_UART3_CTS, + PE9_PF_UART3_RXD, + PE10_PF_UART3_CTS, + PE9_PF_UART3_RXD }; + +static int uart_mxc_port2_init(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart2_pins, + ARRAY_SIZE(mxc_uart2_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "UART2"); +} + +static int uart_mxc_port2_exit(struct platform_device *pdev) +{ + return mxc_gpio_setup_multiple_pins(mxc_uart2_pins, + ARRAY_SIZE(mxc_uart2_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "UART2"); +} + +static struct imxuart_platform_data uart_pdata[] = { + { + .init = uart_mxc_port0_init, + .exit = uart_mxc_port0_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port1_init, + .exit = uart_mxc_port1_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, { + .init = uart_mxc_port2_init, + .exit = uart_mxc_port2_exit, + .flags = IMXUART_HAVE_RTSCTS, + }, +}; + +static int mxc_fec_pins[] = { + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_CLR, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN +}; + +static void gpio_fec_active(void) +{ + mxc_gpio_setup_multiple_pins(mxc_fec_pins, + ARRAY_SIZE(mxc_fec_pins), + MXC_GPIO_ALLOC_MODE_NORMAL, "FEC"); +} + +static void gpio_fec_inactive(void) +{ + mxc_gpio_setup_multiple_pins(mxc_fec_pins, + ARRAY_SIZE(mxc_fec_pins), + MXC_GPIO_ALLOC_MODE_RELEASE, "FEC"); +} + +static struct platform_device *platform_devices[] __initdata = { + &pcm038_nor_mtd_device, +}; + +static void __init pcm038_init(void) +{ + int i; + gpio_fec_active(); + + for (i = 0; i < 3; i++) + imx_init_uart(i, &uart_pdata[i]); + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} + +static void __init pcm038_timer_init(void) +{ + mxc_clocks_init(26000000); + mxc_timer_init("gpt_clk.0"); +} + +struct sys_timer pcm038_timer = { + .init = pcm038_timer_init, +}; + +MACHINE_START(PCM038, "phyCORE-i.MX27") + .phys_io = AIPI_BASE_ADDR, + .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mxc_map_io, + .init_irq = mxc_init_irq, + .init_machine = pcm038_init, + .timer = &pcm038_timer, +MACHINE_END diff --git a/include/asm-arm/arch-mxc/board-pcm038.h b/include/asm-arm/arch-mxc/board-pcm038.h new file mode 100644 index 00000000000..300467e8db6 --- /dev/null +++ b/include/asm-arm/arch-mxc/board-pcm038.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_PCM038_H__ +#define __ASM_ARCH_MXC_BOARD_PCM038_H__ + +/* mandatory for CONFIG_LL_DEBUG */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000) + +#ifndef __ASSEMBLY__ +/* + * This CPU module needs a baseboard to work. After basic initializing + * its own devices, it calls baseboard's init function. + * TODO: Add your own baseboard init function and call it from + * inside pcm038_init(). + */ +#endif + +#endif /* __ASM_ARCH_MXC_BOARD_PCM038_H__ */ diff --git a/include/asm-arm/arch-mxc/debug-macro.S b/include/asm-arm/arch-mxc/debug-macro.S index c6c56805143..575087f8561 100644 --- a/include/asm-arm/arch-mxc/debug-macro.S +++ b/include/asm-arm/arch-mxc/debug-macro.S @@ -24,6 +24,9 @@ #endif #ifdef CONFIG_MACH_MX27ADS #include +#endif +#ifdef CONFIG_MACH_PCM038 +#include #endif .macro addruart,rx mrc p15, 0, \rx, c1, c0 -- cgit v1.2.3-70-g09d2 From ff6552e4f3505da9c2886098773146be71c872e3 Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Sat, 5 Jul 2008 10:03:01 +0200 Subject: i.MX27 family: Add the Phytec PCM970 evaluation board The Phytec phyCORE-i.MX27 CPU module is delivered with the PCM970 baseboard by default. This patch adds support for the hardware. This code is only an empty stub; it is filled up with functionality in a later patch series. Signed-off-by: Juergen Beisert --- arch/arm/mach-mx2/Kconfig | 14 ++++++++++++++ arch/arm/mach-mx2/Makefile | 1 + arch/arm/mach-mx2/pcm038.c | 4 ++++ arch/arm/mach-mx2/pcm970-baseboard.c | 32 ++++++++++++++++++++++++++++++++ include/asm-arm/arch-mxc/board-pcm038.h | 5 +++++ 5 files changed, 56 insertions(+) create mode 100644 arch/arm/mach-mx2/pcm970-baseboard.c (limited to 'include/asm-arm') diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 4c19e1c7947..1eaa97cb716 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -23,3 +23,17 @@ config MACH_PCM038 help Include support for phyCORE-i.MX27 (aka pcm038) platform. This includes specific configurations for the module and its peripherals. + +choice + prompt "Baseboard" + depends on MACH_PCM038 + default MACH_PCM970_BASEBOARD + +config MACH_PCM970_BASEBOARD + prompt "PHYTEC PCM970 development board" + bool + help + This adds board specific devices that can be found on Phytec's + PCM970 evaluation board. + +endchoice diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index f8d3836ee2f..382d86080e8 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_MACH_MX27) += clock_imx27.o obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o obj-$(CONFIG_MACH_PCM038) += pcm038.o +obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c index 46fc026138c..a9a28f58e71 100644 --- a/arch/arm/mach-mx2/pcm038.c +++ b/arch/arm/mach-mx2/pcm038.c @@ -177,6 +177,10 @@ static void __init pcm038_init(void) imx_init_uart(i, &uart_pdata[i]); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + +#ifdef CONFIG_MACH_PCM970_BASEBOARD + pcm970_baseboard_init(); +#endif } static void __init pcm038_timer_init(void) diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c new file mode 100644 index 00000000000..028ac4d3368 --- /dev/null +++ b/arch/arm/mach-mx2/pcm970-baseboard.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +/* + * system init for baseboard usage. Will be called by pcm038 init. + * + * Add platform devices present on this baseboard and init + * them from CPU side as far as required to use them later on + */ +void __init pcm970_baseboard_init(void) +{ +} diff --git a/include/asm-arm/arch-mxc/board-pcm038.h b/include/asm-arm/arch-mxc/board-pcm038.h index 300467e8db6..750c62afd90 100644 --- a/include/asm-arm/arch-mxc/board-pcm038.h +++ b/include/asm-arm/arch-mxc/board-pcm038.h @@ -30,7 +30,12 @@ * its own devices, it calls baseboard's init function. * TODO: Add your own baseboard init function and call it from * inside pcm038_init(). + * + * This example here is for the development board. Refer pcm970-baseboard.c */ + +extern void pcm970_baseboard_init(void); + #endif #endif /* __ASM_ARCH_MXC_BOARD_PCM038_H__ */ -- cgit v1.2.3-70-g09d2 From 75f10b465af9efd59906e9079ed9cbda7e0f7a43 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 22 May 2008 16:20:18 +0100 Subject: [ARM] 5047/2: Support resetting by asserting GPIO pin This adds support for resetting via assertion of GPIO pin. This e.g. is used on Sharp Zaurus SL-6000. Signed-off-by: Dmitry Baryshkov Acked-by: Eric Miao Signed-off-by: Russell King --- arch/arm/mach-pxa/Makefile | 2 +- arch/arm/mach-pxa/reset.c | 95 +++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/hardware.h | 5 ++ include/asm-arm/arch-pxa/system.h | 17 +------ 4 files changed, 102 insertions(+), 17 deletions(-) create mode 100644 arch/arm/mach-pxa/reset.c (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 0e6d05bb81a..c9e66fbe622 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -4,7 +4,7 @@ # Common support (must be linked before board specific support) obj-y += clock.o devices.o generic.o irq.o dma.o \ - time.o gpio.o + time.o gpio.o reset.o obj-$(CONFIG_PM) += pm.o sleep.o standby.o obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c new file mode 100644 index 00000000000..551f313c94d --- /dev/null +++ b/arch/arm/mach-pxa/reset.c @@ -0,0 +1,95 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include + +static void do_hw_reset(void); + +static int reset_gpio = -1; + +int init_gpio_reset(int gpio) +{ + int rc; + + rc = gpio_request(gpio, "reset generator"); + if (rc) { + printk(KERN_ERR "Can't request reset_gpio\n"); + goto out; + } + + rc = gpio_direction_input(gpio); + if (rc) { + printk(KERN_ERR "Can't configure reset_gpio for input\n"); + gpio_free(gpio); + goto out; + } + +out: + if (!rc) + reset_gpio = gpio; + + return rc; +} + +/* + * Trigger GPIO reset. + * This covers various types of logic connecting gpio pin + * to RESET pins (nRESET or GPIO_RESET): + */ +static void do_gpio_reset(void) +{ + BUG_ON(reset_gpio == -1); + + /* drive it low */ + gpio_direction_output(reset_gpio, 0); + mdelay(2); + /* rising edge or drive high */ + gpio_set_value(reset_gpio, 1); + mdelay(2); + /* falling edge */ + gpio_set_value(reset_gpio, 0); + + /* give it some time */ + mdelay(10); + + WARN_ON(1); + /* fallback */ + do_hw_reset(); +} + +static void do_hw_reset(void) +{ + /* Initialize the watchdog and let it fire */ + OWER = OWER_WME; + OSSR = OSSR_M3; + OSMR3 = OSCR + 368640; /* ... in 100 ms */ +} + +void arch_reset(char mode) +{ + if (cpu_is_pxa2xx()) + RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; + + switch (mode) { + case 's': + /* Jump into ROM at address 0 */ + cpu_reset(0); + break; + case 'h': + do_hw_reset(); + break; + case 'g': + do_gpio_reset(); + break; + } +} + diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index e25558faa5a..5547ec797ad 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -205,6 +205,11 @@ static inline void __deprecated pxa_set_cken(int clock, int enable) */ extern unsigned int get_memclk_frequency_10khz(void); +/* + * register GPIO as reset generator + */ +extern int init_gpio_reset(int gpio); + #endif #if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) diff --git a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h index 9aa6c2e939e..14894ae3fa6 100644 --- a/include/asm-arm/arch-pxa/system.h +++ b/include/asm-arm/arch-pxa/system.h @@ -20,19 +20,4 @@ static inline void arch_idle(void) } -static inline void arch_reset(char mode) -{ - if (cpu_is_pxa2xx()) - RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; - - if (mode == 's') { - /* Jump into ROM at address 0 */ - cpu_reset(0); - } else { - /* Initialize the watchdog and let it fire */ - OWER = OWER_WME; - OSSR = OSSR_M3; - OSMR3 = OSCR + 368640; /* ... in 100 ms */ - } -} - +void arch_reset(char mode); -- cgit v1.2.3-70-g09d2 From b032fccca80cbbedaa80e5a72a202a43f08aa97e Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 12 Jun 2008 11:42:07 +0100 Subject: [ARM] 5083/2: Tosa: fix IrDA transciver powerup. On tosa the tranciver LED isn't powered down if the GPIO47 (STUART_TX) isn't configured as low-level. Power it down if IrDA is off to save a bit of power. Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King --- arch/arm/mach-pxa/tosa.c | 58 ++++++++++++++++++++++++++++++++--------- include/asm-arm/arch-pxa/tosa.h | 1 + 2 files changed, 47 insertions(+), 12 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 9892464d7ab..7a89f764acf 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -117,10 +117,6 @@ static unsigned long tosa_pin_config[] = { GPIO44_BTUART_CTS, GPIO45_BTUART_RTS, - /* IrDA */ - GPIO46_STUART_RXD, - GPIO47_STUART_TXD, - /* Keybd */ GPIO58_GPIO | MFP_LPM_DRIVE_LOW, GPIO59_GPIO | MFP_LPM_DRIVE_LOW, @@ -147,6 +143,17 @@ static unsigned long tosa_pin_config[] = { GPIO83_SSP2_TXD, }; +static unsigned long tosa_pin_irda_off[] = { + GPIO46_STUART_RXD, + GPIO47_GPIO | MFP_LPM_DRIVE_LOW, +}; + +static unsigned long tosa_pin_irda_on[] = { + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, +}; + + /* * SCOOP Device */ @@ -341,29 +348,55 @@ static struct pxamci_platform_data tosa_mci_platform_data = { /* * Irda */ +static void tosa_irda_transceiver_mode(struct device *dev, int mode) +{ + if (mode & IR_OFF) { + gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0); + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); + gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); + } else { + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_on)); + gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1); + } +} + static int tosa_irda_startup(struct device *dev) { int ret; + ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX"); + if (ret) + goto err_tx; + ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); + if (ret) + goto err_tx_dir; + ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown"); if (ret) - return ret; + goto err_pwr; ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0); if (ret) - gpio_free(TOSA_GPIO_IR_POWERDWN); + goto err_pwr_dir; - return ret; - } + tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); -static void tosa_irda_shutdown(struct device *dev) -{ + return 0; + +err_pwr_dir: gpio_free(TOSA_GPIO_IR_POWERDWN); +err_pwr: +err_tx_dir: + gpio_free(TOSA_GPIO_IRDA_TX); +err_tx: + return ret; } -static void tosa_irda_transceiver_mode(struct device *dev, int mode) +static void tosa_irda_shutdown(struct device *dev) { - gpio_set_value(TOSA_GPIO_IR_POWERDWN, !(mode & IR_OFF)); + tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); + gpio_free(TOSA_GPIO_IR_POWERDWN); + gpio_free(TOSA_GPIO_IRDA_TX); } static struct pxaficp_platform_data tosa_ficp_platform_data = { @@ -501,6 +534,7 @@ static void tosa_restart(char mode) static void __init tosa_init(void) { pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); gpio_set_wake(MFP_PIN_GPIO1, 1); /* We can't pass to gpio-keys since it will drop the Reset altfunc */ diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h index c5b6fde6907..18822621615 100644 --- a/include/asm-arm/arch-pxa/tosa.h +++ b/include/asm-arm/arch-pxa/tosa.h @@ -99,6 +99,7 @@ #define TOSA_GPIO_TP_INT (32) /* Touch Panel pen down interrupt */ #define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */ #define TOSA_GPIO_BAT_LOCKED (38) /* Battery locked */ +#define TOSA_GPIO_IRDA_TX (47) #define TOSA_GPIO_TG_SPI_SCLK (81) #define TOSA_GPIO_TG_SPI_CS (82) #define TOSA_GPIO_TG_SPI_MOSI (83) -- cgit v1.2.3-70-g09d2 From bf0116e54e185fd63025f2b975f0f1616ffe41f1 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 14 Jun 2008 11:42:02 +0100 Subject: [ARM] 5097/1: Tosa: support TC6393XB device Add definitions for Toshiba TC6393XB companion chip and register the tc6393xb device. Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King --- arch/arm/mach-pxa/tosa.c | 127 ++++++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/irqs.h | 1 + include/asm-arm/arch-pxa/tosa.h | 44 +++++++++----- 3 files changed, 158 insertions(+), 14 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 7a89f764acf..2fe0998ac3f 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -18,7 +18,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -509,9 +512,127 @@ static struct platform_device tosaled_device = { }, }; +/* + * Toshiba Mobile IO Controller + */ +static struct resource tc6393xb_resources[] = { + [0] = { + .start = TOSA_LCDC_PHYS, + .end = TOSA_LCDC_PHYS + 0x3ffffff, + .flags = IORESOURCE_MEM, + }, + + [1] = { + .start = TOSA_IRQ_GPIO_TC6393XB_INT, + .end = TOSA_IRQ_GPIO_TC6393XB_INT, + .flags = IORESOURCE_IRQ, + }, +}; + + +static int tosa_tc6393xb_enable(struct platform_device *dev) +{ + int rc; + + rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr"); + if (rc) + goto err_req_pclr; + rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend"); + if (rc) + goto err_req_suspend; + rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v"); + if (rc) + goto err_req_l3v; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0); + if (rc) + goto err_dir_l3v; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0); + if (rc) + goto err_dir_suspend; + rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0); + if (rc) + goto err_dir_pclr; + + mdelay(1); + + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); + + mdelay(10); + + gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1); + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); + + return 0; +err_dir_pclr: +err_dir_suspend: +err_dir_l3v: + gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); +err_req_l3v: + gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); +err_req_suspend: + gpio_free(TOSA_GPIO_TC6393XB_REST_IN); +err_req_pclr: + return rc; +} + +static int tosa_tc6393xb_disable(struct platform_device *dev) +{ + gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); + gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); + gpio_free(TOSA_GPIO_TC6393XB_REST_IN); + + return 0; +} + +static int tosa_tc6393xb_resume(struct platform_device *dev) +{ + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); + mdelay(10); + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); + mdelay(10); + + return 0; +} + +static int tosa_tc6393xb_suspend(struct platform_device *dev) +{ + gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0); + gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0); + return 0; +} + +static struct tc6393xb_platform_data tosa_tc6393xb_setup = { + .scr_pll2cr = 0x0cc1, + .scr_gper = 0x3300, + .scr_gpo_dsr = + TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), + .scr_gpo_doecr = + TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), + + .irq_base = IRQ_BOARD_START, + .gpio_base = TOSA_TC6393XB_GPIO_BASE, + + .enable = tosa_tc6393xb_enable, + .disable = tosa_tc6393xb_disable, + .suspend = tosa_tc6393xb_suspend, + .resume = tosa_tc6393xb_resume, +}; + + +static struct platform_device tc6393xb_device = { + .name = "tc6393xb", + .id = -1, + .dev = { + .platform_data = &tosa_tc6393xb_setup, + }, + .num_resources = ARRAY_SIZE(tc6393xb_resources), + .resource = tc6393xb_resources, +}; + static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, + &tc6393xb_device, &tosakbd_device, &tosa_gpio_keys_device, &tosaled_device, @@ -533,6 +654,8 @@ static void tosa_restart(char mode) static void __init tosa_init(void) { + int dummy; + pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); gpio_set_wake(MFP_PIN_GPIO1, 1); @@ -548,6 +671,10 @@ static void __init tosa_init(void) /* enable batt_fault */ PMCR = 0x01; + dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12); + dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12); + dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); + pxa_set_mci_info(&tosa_mci_platform_data); pxa_set_udc_info(&udc_info); pxa_set_ficp_info(&tosa_ficp_platform_data); diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h index b6c8fe37768..fa05e76f64e 100644 --- a/include/asm-arm/arch-pxa/irqs.h +++ b/include/asm-arm/arch-pxa/irqs.h @@ -180,6 +180,7 @@ #define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1) #elif defined(CONFIG_ARCH_LUBBOCK) || \ defined(CONFIG_MACH_LOGICPD_PXA270) || \ + defined(CONFIG_MACH_TOSA) || \ defined(CONFIG_MACH_MAINSTONE) || \ defined(CONFIG_MACH_PCM027) || \ defined(CONFIG_MACH_MAGICIAN) diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h index 18822621615..a16c103b725 100644 --- a/include/asm-arm/arch-pxa/tosa.h +++ b/include/asm-arm/arch-pxa/tosa.h @@ -25,7 +25,7 @@ */ #define TOSA_SCOOP_GPIO_BASE NR_BUILTIN_GPIO #define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11 -#define TOSA_SCOOP_TC6393_REST_IN SCOOP_GPCR_PA12 +#define TOSA_GPIO_TC6393XB_REST_IN (TOSA_SCOOP_GPIO_BASE + 1) #define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2) #define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3) #define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4) @@ -35,11 +35,9 @@ #define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19 /* GPIO Direction 1 : output mode / 0:input mode */ -#define TOSA_SCOOP_IO_DIR ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393_REST_IN | \ +#define TOSA_SCOOP_IO_DIR (TOSA_SCOOP_PXA_VCORE1 | \ TOSA_SCOOP_AUD_PWR_ON |\ - TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN ) -/* GPIO out put level when init 1: Hi */ -#define TOSA_SCOOP_IO_OUT ( TOSA_SCOOP_TC6393_REST_IN ) + TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN) /* * SCOOP2 jacket GPIOs @@ -49,16 +47,34 @@ #define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1) #define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2) #define TOSA_GPIO_USB_PULLUP (TOSA_SCOOP_JC_GPIO_BASE + 3) -#define TOSA_SCOOP_JC_TC6393_SUSPEND SCOOP_GPCR_PA15 -#define TOSA_SCOOP_JC_TC3693_L3V_ON SCOOP_GPCR_PA16 +#define TOSA_GPIO_TC6393XB_SUSPEND (TOSA_SCOOP_JC_GPIO_BASE + 4) +#define TOSA_GPIO_TC6393XB_L3V_ON (TOSA_SCOOP_JC_GPIO_BASE + 5) #define TOSA_SCOOP_JC_WLAN_DETECT SCOOP_GPCR_PA17 #define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7) #define TOSA_SCOOP_JC_CARD_LIMIT_SEL SCOOP_GPCR_PA19 /* GPIO Direction 1 : output mode / 0:input mode */ -#define TOSA_SCOOP_JC_IO_DIR ( \ - TOSA_SCOOP_JC_TC6393_SUSPEND | TOSA_SCOOP_JC_TC3693_L3V_ON | \ - TOSA_SCOOP_JC_CARD_LIMIT_SEL ) +#define TOSA_SCOOP_JC_IO_DIR (TOSA_SCOOP_JC_CARD_LIMIT_SEL) + +/* + * TC6393XB GPIOs + */ +#define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12) +#define TOSA_TC6393XB_GPIO(i) (TOSA_TC6393XB_GPIO_BASE + (i)) +#define TOSA_TC6393XB_GPIO_BIT(gpio) (1 << (gpio - TOSA_TC6393XB_GPIO_BASE)) + +#define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0) +#define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1) +#define TOSA_GPIO_BL_C20MA (TOSA_TC6393XB_GPIO_BASE + 3) +#define TOSA_GPIO_CARD_VCC_ON (TOSA_TC6393XB_GPIO_BASE + 4) +#define TOSA_GPIO_CHARGE_OFF (TOSA_TC6393XB_GPIO_BASE + 6) +#define TOSA_GPIO_CHARGE_OFF_JC (TOSA_TC6393XB_GPIO_BASE + 7) +#define TOSA_GPIO_BAT0_V_ON (TOSA_TC6393XB_GPIO_BASE + 9) +#define TOSA_GPIO_BAT1_V_ON (TOSA_TC6393XB_GPIO_BASE + 10) +#define TOSA_GPIO_BU_CHRG_ON (TOSA_TC6393XB_GPIO_BASE + 11) +#define TOSA_GPIO_BAT_SW_ON (TOSA_TC6393XB_GPIO_BASE + 12) +#define TOSA_GPIO_BAT0_TH_ON (TOSA_TC6393XB_GPIO_BASE + 14) +#define TOSA_GPIO_BAT1_TH_ON (TOSA_TC6393XB_GPIO_BASE + 15) /* * Timing Generator @@ -84,13 +100,13 @@ #define TOSA_GPIO_JACKET_DETECT (7) #define TOSA_GPIO_nSD_DETECT (9) #define TOSA_GPIO_nSD_INT (10) -#define TOSA_GPIO_TC6393_CLK (11) +#define TOSA_GPIO_TC6393XB_CLK (11) #define TOSA_GPIO_BAT1_CRG (12) #define TOSA_GPIO_CF_CD (13) #define TOSA_GPIO_BAT0_CRG (14) -#define TOSA_GPIO_TC6393_INT (15) +#define TOSA_GPIO_TC6393XB_INT (15) #define TOSA_GPIO_BAT0_LOW (17) -#define TOSA_GPIO_TC6393_RDY (18) +#define TOSA_GPIO_TC6393XB_RDY (18) #define TOSA_GPIO_ON_RESET (19) #define TOSA_GPIO_EAR_IN (20) #define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */ @@ -138,7 +154,7 @@ #define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG) #define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD) #define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG) -#define TOSA_IRQ_GPIO_TC6393_INT IRQ_GPIO(TOSA_GPIO_TC6393_INT) +#define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT) #define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW) #define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN) #define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ) -- cgit v1.2.3-70-g09d2 From 16b32fd0a35b30cbd67395cfcbd360354db44f39 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 5 Jul 2008 09:02:48 +0100 Subject: [ARM] 5150/1: Tosa: support built-in bluetooth power-up The driver is pretty much generic and will be later shared with a few other devices, like hx4700 ipaq. Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 8 ++ arch/arm/mach-pxa/Makefile | 2 + arch/arm/mach-pxa/tosa-bt.c | 150 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/tosa.c | 17 ++++- include/asm-arm/arch-pxa/tosa.h | 7 +- include/asm-arm/arch-pxa/tosa_bt.h | 22 ++++++ 6 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-pxa/tosa-bt.c create mode 100644 include/asm-arm/arch-pxa/tosa_bt.h (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5da7a682049..6c162f8fdce 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -273,4 +273,12 @@ config PXA_SSP tristate help Enable support for PXA2xx SSP ports + +config TOSA_BT + tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" + depends on MACH_TOSA + select RFKILL + help + This is a simple driver that is able to control + the state of built in bluetooth chip on tosa. endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c9e66fbe622..18e0b249f7c 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -58,3 +58,5 @@ obj-$(CONFIG_LEDS) += $(led-y) ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o endif + +obj-$(CONFIG_TOSA_BT) += tosa-bt.o diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c new file mode 100644 index 00000000000..7d8505466e5 --- /dev/null +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -0,0 +1,150 @@ +/* + * Bluetooth built-in chip control + * + * Copyright (c) 2008 Dmitry Baryshkov + * + * 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 +#include +#include +#include +#include +#include + +#include + +static void tosa_bt_on(struct tosa_bt_data *data) +{ + gpio_set_value(data->gpio_reset, 0); + gpio_set_value(data->gpio_pwr, 1); + gpio_set_value(data->gpio_reset, 1); + mdelay(20); + gpio_set_value(data->gpio_reset, 0); +} + +static void tosa_bt_off(struct tosa_bt_data *data) +{ + gpio_set_value(data->gpio_reset, 1); + mdelay(10); + gpio_set_value(data->gpio_pwr, 0); + gpio_set_value(data->gpio_reset, 0); +} + +static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) +{ + pr_info("BT_RADIO going: %s\n", + state == RFKILL_STATE_ON ? "on" : "off"); + + if (state == RFKILL_STATE_ON) { + pr_info("TOSA_BT: going ON\n"); + tosa_bt_on(data); + } else { + pr_info("TOSA_BT: going OFF\n"); + tosa_bt_off(data); + } + return 0; +} + +static int tosa_bt_probe(struct platform_device *dev) +{ + int rc; + struct rfkill *rfk; + + struct tosa_bt_data *data = dev->dev.platform_data; + + rc = gpio_request(data->gpio_reset, "Bluetooth reset"); + if (rc) + goto err_reset; + rc = gpio_direction_output(data->gpio_reset, 0); + if (rc) + goto err_reset_dir; + rc = gpio_request(data->gpio_pwr, "Bluetooth power"); + if (rc) + goto err_pwr; + rc = gpio_direction_output(data->gpio_pwr, 0); + if (rc) + goto err_pwr_dir; + + rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); + if (!rfk) { + rc = -ENOMEM; + goto err_rfk_alloc; + } + + rfk->name = "tosa-bt"; + rfk->toggle_radio = tosa_bt_toggle_radio; + rfk->data = data; +#ifdef CONFIG_RFKILL_LEDS + rfk->led_trigger.name = "tosa-bt"; +#endif + + rc = rfkill_register(rfk); + if (rc) + goto err_rfkill; + + platform_set_drvdata(dev, rfk); + + return 0; + +err_rfkill: + if (rfk) + rfkill_free(rfk); + rfk = NULL; +err_rfk_alloc: + tosa_bt_off(data); +err_pwr_dir: + gpio_free(data->gpio_pwr); +err_pwr: +err_reset_dir: + gpio_free(data->gpio_reset); +err_reset: + return rc; +} + +static int __devexit tosa_bt_remove(struct platform_device *dev) +{ + struct tosa_bt_data *data = dev->dev.platform_data; + struct rfkill *rfk = platform_get_drvdata(dev); + + platform_set_drvdata(dev, NULL); + + if (rfk) + rfkill_unregister(rfk); + rfk = NULL; + + tosa_bt_off(data); + + gpio_free(data->gpio_pwr); + gpio_free(data->gpio_reset); + + return 0; +} + +static struct platform_driver tosa_bt_driver = { + .probe = tosa_bt_probe, + .remove = __devexit_p(tosa_bt_remove), + + .driver = { + .name = "tosa-bt", + .owner = THIS_MODULE, + }, +}; + + +static int __init tosa_bt_init(void) +{ + return platform_driver_register(&tosa_bt_driver); +} + +static void __exit tosa_bt_exit(void) +{ + platform_driver_unregister(&tosa_bt_driver); +} + +module_init(tosa_bt_init); +module_exit(tosa_bt_exit); diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index fa903e7ae62..5a9d329f504 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #include #include @@ -562,7 +564,7 @@ static struct gpio_led tosa_gpio_leds[] = { }, { .name = "tosa:blue:bluetooth", - .default_trigger = "none", + .default_trigger = "tosa-bt", .gpio = TOSA_GPIO_BT_LED, }, }; @@ -732,6 +734,18 @@ static struct platform_device tc6393xb_device = { .resource = tc6393xb_resources, }; +static struct tosa_bt_data tosa_bt_data = { + .gpio_pwr = TOSA_GPIO_BT_PWR_EN, + .gpio_reset = TOSA_GPIO_BT_RESET, +}; + +static struct platform_device tosa_bt_device = { + .name = "tosa-bt", + .id = -1, + .dev.platform_data = &tosa_bt_data, +}; + + static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, @@ -740,6 +754,7 @@ static struct platform_device *devices[] __initdata = { &tosakbd_device, &tosa_gpio_keys_device, &tosaled_device, + &tosa_bt_device, }; static void tosa_poweroff(void) diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h index a16c103b725..a72803f0461 100644 --- a/include/asm-arm/arch-pxa/tosa.h +++ b/include/asm-arm/arch-pxa/tosa.h @@ -30,14 +30,13 @@ #define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3) #define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4) #define TOSA_SCOOP_AUD_PWR_ON SCOOP_GPCR_PA16 -#define TOSA_SCOOP_BT_RESET SCOOP_GPCR_PA17 -#define TOSA_SCOOP_BT_PWR_EN SCOOP_GPCR_PA18 +#define TOSA_GPIO_BT_RESET (TOSA_SCOOP_GPIO_BASE + 6) +#define TOSA_GPIO_BT_PWR_EN (TOSA_SCOOP_GPIO_BASE + 7) #define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19 /* GPIO Direction 1 : output mode / 0:input mode */ #define TOSA_SCOOP_IO_DIR (TOSA_SCOOP_PXA_VCORE1 | \ - TOSA_SCOOP_AUD_PWR_ON |\ - TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN) + TOSA_SCOOP_AUD_PWR_ON) /* * SCOOP2 jacket GPIOs diff --git a/include/asm-arm/arch-pxa/tosa_bt.h b/include/asm-arm/arch-pxa/tosa_bt.h new file mode 100644 index 00000000000..efc3c3d3b75 --- /dev/null +++ b/include/asm-arm/arch-pxa/tosa_bt.h @@ -0,0 +1,22 @@ +/* + * Tosa bluetooth built-in chip control. + * + * Later it may be shared with some other platforms. + * + * Copyright (c) 2008 Dmitry Baryshkov + * + * 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 TOSA_BT_H +#define TOSA_BT_H + +struct tosa_bt_data { + int gpio_pwr; + int gpio_reset; +}; + +#endif + -- cgit v1.2.3-70-g09d2 From 5e329d1c7f5fe6adfee99c783fa98bda7dae8ac5 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 6 Jun 2008 10:12:37 +0100 Subject: [ARM] 5079/1: Warn people when using pxa2xx-gpio.h Warn people when using pxa2xx-gpio.h as it is only here for backwards compatibility. The new mfp-pxa2[57]x.h and the relevant API should be used instead. Signed-off-by: Stefan Schmidt Signed-off-by: Russell King --- include/asm-arm/arch-pxa/pxa2xx-gpio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/pxa2xx-gpio.h b/include/asm-arm/arch-pxa/pxa2xx-gpio.h index 763313c5e6b..a6e60f69161 100644 --- a/include/asm-arm/arch-pxa/pxa2xx-gpio.h +++ b/include/asm-arm/arch-pxa/pxa2xx-gpio.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARCH_PXA2XX_GPIO_H #define __ASM_ARCH_PXA2XX_GPIO_H +#warning Please use mfp-pxa2[57]x.h instead of pxa2xx-gpio.h + /* GPIO alternate function assignments */ #define GPIO1_RST 1 /* reset */ -- cgit v1.2.3-70-g09d2 From ff7b04796d9866327ea76e1393f1e902ef032f84 Mon Sep 17 00:00:00 2001 From: Saeed Bishara Date: Tue, 8 Jul 2008 11:58:36 -0700 Subject: dmaengine: DMA engine driver for Marvell XOR engine The XOR engine found in Marvell's SoCs and system controllers provides XOR and DMA operation, iSCSI CRC32C calculation, memory initialization, and memory ECC error cleanup operation support. This driver implements the DMA engine API and supports the following capabilities: - memcpy - xor - memset The XOR engine can be used by DMA engine clients implemented in the kernel, one of those clients is the RAID module. In that case, I observed 20% improvement in the raid5 write throughput, and 40% decrease in the CPU utilization when doing array construction, those results obtained on an 5182 running at 500Mhz. When enabling the NET DMA client, the performance decreased, so meanwhile it is recommended to keep this client off. Signed-off-by: Saeed Bishara Signed-off-by: Lennert Buytenhek Signed-off-by: Nicolas Pitre Acked-by: Maciej Sosnowski Signed-off-by: Dan Williams --- drivers/dma/Kconfig | 8 + drivers/dma/Makefile | 1 + drivers/dma/mv_xor.c | 1364 +++++++++++++++++++++++++++++++++++ drivers/dma/mv_xor.h | 183 +++++ include/asm-arm/plat-orion/mv_xor.h | 28 + 5 files changed, 1584 insertions(+) create mode 100644 drivers/dma/mv_xor.c create mode 100644 drivers/dma/mv_xor.h create mode 100644 include/asm-arm/plat-orion/mv_xor.h (limited to 'include/asm-arm') diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index e4dd0065da3..5af8b1cfc1e 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -47,6 +47,14 @@ config FSL_DMA MPC8560/40, MPC8555, MPC8548 and MPC8641 processors. The MPC8349, MPC8360 is also supported. +config MV_XOR + bool "Marvell XOR engine support" + depends on PLAT_ORION + select ASYNC_CORE + select DMA_ENGINE + ---help--- + Enable support for the Marvell XOR engine. + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index c8036d94590..ee272fd329c 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o obj-$(CONFIG_FSL_DMA) += fsldma.o +obj-$(CONFIG_MV_XOR) += mv_xor.o diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c new file mode 100644 index 00000000000..f0c123ce8ae --- /dev/null +++ b/drivers/dma/mv_xor.c @@ -0,0 +1,1364 @@ +/* + * offload engine driver for the Marvell XOR engine + * Copyright (C) 2007, 2008, Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mv_xor.h" + +static void mv_xor_issue_pending(struct dma_chan *chan); + +#define to_mv_xor_chan(chan) \ + container_of(chan, struct mv_xor_chan, common) + +#define to_mv_xor_device(dev) \ + container_of(dev, struct mv_xor_device, common) + +#define to_mv_xor_slot(tx) \ + container_of(tx, struct mv_xor_desc_slot, async_tx) + +static void mv_desc_init(struct mv_xor_desc_slot *desc, unsigned long flags) +{ + struct mv_xor_desc *hw_desc = desc->hw_desc; + + hw_desc->status = (1 << 31); + hw_desc->phy_next_desc = 0; + hw_desc->desc_command = (1 << 31); +} + +static u32 mv_desc_get_dest_addr(struct mv_xor_desc_slot *desc) +{ + struct mv_xor_desc *hw_desc = desc->hw_desc; + return hw_desc->phy_dest_addr; +} + +static u32 mv_desc_get_src_addr(struct mv_xor_desc_slot *desc, + int src_idx) +{ + struct mv_xor_desc *hw_desc = desc->hw_desc; + return hw_desc->phy_src_addr[src_idx]; +} + + +static void mv_desc_set_byte_count(struct mv_xor_desc_slot *desc, + u32 byte_count) +{ + struct mv_xor_desc *hw_desc = desc->hw_desc; + hw_desc->byte_count = byte_count; +} + +static void mv_desc_set_next_desc(struct mv_xor_desc_slot *desc, + u32 next_desc_addr) +{ + struct mv_xor_desc *hw_desc = desc->hw_desc; + BUG_ON(hw_desc->phy_next_desc); + hw_desc->phy_next_desc = next_desc_addr; +} + +static void mv_desc_clear_next_desc(struct mv_xor_desc_slot *desc) +{ + struct mv_xor_desc *hw_desc = desc->hw_desc; + hw_desc->phy_next_desc = 0; +} + +static void mv_desc_set_block_fill_val(struct mv_xor_desc_slot *desc, u32 val) +{ + desc->value = val; +} + +static void mv_desc_set_dest_addr(struct mv_xor_desc_slot *desc, + dma_addr_t addr) +{ + struct mv_xor_desc *hw_desc = desc->hw_desc; + hw_desc->phy_dest_addr = addr; +} + +static int mv_chan_memset_slot_count(size_t len) +{ + return 1; +} + +#define mv_chan_memcpy_slot_count(c) mv_chan_memset_slot_count(c) + +static void mv_desc_set_src_addr(struct mv_xor_desc_slot *desc, + int index, dma_addr_t addr) +{ + struct mv_xor_desc *hw_desc = desc->hw_desc; + hw_desc->phy_src_addr[index] = addr; + if (desc->type == DMA_XOR) + hw_desc->desc_command |= (1 << index); +} + +static u32 mv_chan_get_current_desc(struct mv_xor_chan *chan) +{ + return __raw_readl(XOR_CURR_DESC(chan)); +} + +static void mv_chan_set_next_descriptor(struct mv_xor_chan *chan, + u32 next_desc_addr) +{ + __raw_writel(next_desc_addr, XOR_NEXT_DESC(chan)); +} + +static void mv_chan_set_dest_pointer(struct mv_xor_chan *chan, u32 desc_addr) +{ + __raw_writel(desc_addr, XOR_DEST_POINTER(chan)); +} + +static void mv_chan_set_block_size(struct mv_xor_chan *chan, u32 block_size) +{ + __raw_writel(block_size, XOR_BLOCK_SIZE(chan)); +} + +static void mv_chan_set_value(struct mv_xor_chan *chan, u32 value) +{ + __raw_writel(value, XOR_INIT_VALUE_LOW(chan)); + __raw_writel(value, XOR_INIT_VALUE_HIGH(chan)); +} + +static void mv_chan_unmask_interrupts(struct mv_xor_chan *chan) +{ + u32 val = __raw_readl(XOR_INTR_MASK(chan)); + val |= XOR_INTR_MASK_VALUE << (chan->idx * 16); + __raw_writel(val, XOR_INTR_MASK(chan)); +} + +static u32 mv_chan_get_intr_cause(struct mv_xor_chan *chan) +{ + u32 intr_cause = __raw_readl(XOR_INTR_CAUSE(chan)); + intr_cause = (intr_cause >> (chan->idx * 16)) & 0xFFFF; + return intr_cause; +} + +static int mv_is_err_intr(u32 intr_cause) +{ + if (intr_cause & ((1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9))) + return 1; + + return 0; +} + +static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan) +{ + u32 val = (1 << (1 + (chan->idx * 16))); + dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val); + __raw_writel(val, XOR_INTR_CAUSE(chan)); +} + +static void mv_xor_device_clear_err_status(struct mv_xor_chan *chan) +{ + u32 val = 0xFFFF0000 >> (chan->idx * 16); + __raw_writel(val, XOR_INTR_CAUSE(chan)); +} + +static int mv_can_chain(struct mv_xor_desc_slot *desc) +{ + struct mv_xor_desc_slot *chain_old_tail = list_entry( + desc->chain_node.prev, struct mv_xor_desc_slot, chain_node); + + if (chain_old_tail->type != desc->type) + return 0; + if (desc->type == DMA_MEMSET) + return 0; + + return 1; +} + +static void mv_set_mode(struct mv_xor_chan *chan, + enum dma_transaction_type type) +{ + u32 op_mode; + u32 config = __raw_readl(XOR_CONFIG(chan)); + + switch (type) { + case DMA_XOR: + op_mode = XOR_OPERATION_MODE_XOR; + break; + case DMA_MEMCPY: + op_mode = XOR_OPERATION_MODE_MEMCPY; + break; + case DMA_MEMSET: + op_mode = XOR_OPERATION_MODE_MEMSET; + break; + default: + dev_printk(KERN_ERR, chan->device->common.dev, + "error: unsupported operation %d.\n", + type); + BUG(); + return; + } + + config &= ~0x7; + config |= op_mode; + __raw_writel(config, XOR_CONFIG(chan)); + chan->current_type = type; +} + +static void mv_chan_activate(struct mv_xor_chan *chan) +{ + u32 activation; + + dev_dbg(chan->device->common.dev, " activate chan.\n"); + activation = __raw_readl(XOR_ACTIVATION(chan)); + activation |= 0x1; + __raw_writel(activation, XOR_ACTIVATION(chan)); +} + +static char mv_chan_is_busy(struct mv_xor_chan *chan) +{ + u32 state = __raw_readl(XOR_ACTIVATION(chan)); + + state = (state >> 4) & 0x3; + + return (state == 1) ? 1 : 0; +} + +static int mv_chan_xor_slot_count(size_t len, int src_cnt) +{ + return 1; +} + +/** + * mv_xor_free_slots - flags descriptor slots for reuse + * @slot: Slot to free + * Caller must hold &mv_chan->lock while calling this function + */ +static void mv_xor_free_slots(struct mv_xor_chan *mv_chan, + struct mv_xor_desc_slot *slot) +{ + dev_dbg(mv_chan->device->common.dev, "%s %d slot %p\n", + __func__, __LINE__, slot); + + slot->slots_per_op = 0; + +} + +/* + * mv_xor_start_new_chain - program the engine to operate on new chain headed by + * sw_desc + * Caller must hold &mv_chan->lock while calling this function + */ +static void mv_xor_start_new_chain(struct mv_xor_chan *mv_chan, + struct mv_xor_desc_slot *sw_desc) +{ + dev_dbg(mv_chan->device->common.dev, "%s %d: sw_desc %p\n", + __func__, __LINE__, sw_desc); + if (sw_desc->type != mv_chan->current_type) + mv_set_mode(mv_chan, sw_desc->type); + + if (sw_desc->type == DMA_MEMSET) { + /* for memset requests we need to program the engine, no + * descriptors used. + */ + struct mv_xor_desc *hw_desc = sw_desc->hw_desc; + mv_chan_set_dest_pointer(mv_chan, hw_desc->phy_dest_addr); + mv_chan_set_block_size(mv_chan, sw_desc->unmap_len); + mv_chan_set_value(mv_chan, sw_desc->value); + } else { + /* set the hardware chain */ + mv_chan_set_next_descriptor(mv_chan, sw_desc->async_tx.phys); + } + mv_chan->pending += sw_desc->slot_cnt; + mv_xor_issue_pending(&mv_chan->common); +} + +static dma_cookie_t +mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc, + struct mv_xor_chan *mv_chan, dma_cookie_t cookie) +{ + BUG_ON(desc->async_tx.cookie < 0); + + if (desc->async_tx.cookie > 0) { + cookie = desc->async_tx.cookie; + + /* call the callback (must not sleep or submit new + * operations to this channel) + */ + if (desc->async_tx.callback) + desc->async_tx.callback( + desc->async_tx.callback_param); + + /* unmap dma addresses + * (unmap_single vs unmap_page?) + */ + if (desc->group_head && desc->unmap_len) { + struct mv_xor_desc_slot *unmap = desc->group_head; + struct device *dev = + &mv_chan->device->pdev->dev; + u32 len = unmap->unmap_len; + u32 src_cnt = unmap->unmap_src_cnt; + dma_addr_t addr = mv_desc_get_dest_addr(unmap); + + dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE); + while (src_cnt--) { + addr = mv_desc_get_src_addr(unmap, src_cnt); + dma_unmap_page(dev, addr, len, DMA_TO_DEVICE); + } + desc->group_head = NULL; + } + } + + /* run dependent operations */ + async_tx_run_dependencies(&desc->async_tx); + + return cookie; +} + +static int +mv_xor_clean_completed_slots(struct mv_xor_chan *mv_chan) +{ + struct mv_xor_desc_slot *iter, *_iter; + + dev_dbg(mv_chan->device->common.dev, "%s %d\n", __func__, __LINE__); + list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots, + completed_node) { + + if (async_tx_test_ack(&iter->async_tx)) { + list_del(&iter->completed_node); + mv_xor_free_slots(mv_chan, iter); + } + } + return 0; +} + +static int +mv_xor_clean_slot(struct mv_xor_desc_slot *desc, + struct mv_xor_chan *mv_chan) +{ + dev_dbg(mv_chan->device->common.dev, "%s %d: desc %p flags %d\n", + __func__, __LINE__, desc, desc->async_tx.flags); + list_del(&desc->chain_node); + /* the client is allowed to attach dependent operations + * until 'ack' is set + */ + if (!async_tx_test_ack(&desc->async_tx)) { + /* move this slot to the completed_slots */ + list_add_tail(&desc->completed_node, &mv_chan->completed_slots); + return 0; + } + + mv_xor_free_slots(mv_chan, desc); + return 0; +} + +static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) +{ + struct mv_xor_desc_slot *iter, *_iter; + dma_cookie_t cookie = 0; + int busy = mv_chan_is_busy(mv_chan); + u32 current_desc = mv_chan_get_current_desc(mv_chan); + int seen_current = 0; + + dev_dbg(mv_chan->device->common.dev, "%s %d\n", __func__, __LINE__); + dev_dbg(mv_chan->device->common.dev, "current_desc %x\n", current_desc); + mv_xor_clean_completed_slots(mv_chan); + + /* free completed slots from the chain starting with + * the oldest descriptor + */ + + list_for_each_entry_safe(iter, _iter, &mv_chan->chain, + chain_node) { + prefetch(_iter); + prefetch(&_iter->async_tx); + + /* do not advance past the current descriptor loaded into the + * hardware channel, subsequent descriptors are either in + * process or have not been submitted + */ + if (seen_current) + break; + + /* stop the search if we reach the current descriptor and the + * channel is busy + */ + if (iter->async_tx.phys == current_desc) { + seen_current = 1; + if (busy) + break; + } + + cookie = mv_xor_run_tx_complete_actions(iter, mv_chan, cookie); + + if (mv_xor_clean_slot(iter, mv_chan)) + break; + } + + if ((busy == 0) && !list_empty(&mv_chan->chain)) { + struct mv_xor_desc_slot *chain_head; + chain_head = list_entry(mv_chan->chain.next, + struct mv_xor_desc_slot, + chain_node); + + mv_xor_start_new_chain(mv_chan, chain_head); + } + + if (cookie > 0) + mv_chan->completed_cookie = cookie; +} + +static void +mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) +{ + spin_lock_bh(&mv_chan->lock); + __mv_xor_slot_cleanup(mv_chan); + spin_unlock_bh(&mv_chan->lock); +} + +static void mv_xor_tasklet(unsigned long data) +{ + struct mv_xor_chan *chan = (struct mv_xor_chan *) data; + __mv_xor_slot_cleanup(chan); +} + +static struct mv_xor_desc_slot * +mv_xor_alloc_slots(struct mv_xor_chan *mv_chan, int num_slots, + int slots_per_op) +{ + struct mv_xor_desc_slot *iter, *_iter, *alloc_start = NULL; + LIST_HEAD(chain); + int slots_found, retry = 0; + + /* start search from the last allocated descrtiptor + * if a contiguous allocation can not be found start searching + * from the beginning of the list + */ +retry: + slots_found = 0; + if (retry == 0) + iter = mv_chan->last_used; + else + iter = list_entry(&mv_chan->all_slots, + struct mv_xor_desc_slot, + slot_node); + + list_for_each_entry_safe_continue( + iter, _iter, &mv_chan->all_slots, slot_node) { + prefetch(_iter); + prefetch(&_iter->async_tx); + if (iter->slots_per_op) { + /* give up after finding the first busy slot + * on the second pass through the list + */ + if (retry) + break; + + slots_found = 0; + continue; + } + + /* start the allocation if the slot is correctly aligned */ + if (!slots_found++) + alloc_start = iter; + + if (slots_found == num_slots) { + struct mv_xor_desc_slot *alloc_tail = NULL; + struct mv_xor_desc_slot *last_used = NULL; + iter = alloc_start; + while (num_slots) { + int i; + + /* pre-ack all but the last descriptor */ + async_tx_ack(&iter->async_tx); + + list_add_tail(&iter->chain_node, &chain); + alloc_tail = iter; + iter->async_tx.cookie = 0; + iter->slot_cnt = num_slots; + iter->xor_check_result = NULL; + for (i = 0; i < slots_per_op; i++) { + iter->slots_per_op = slots_per_op - i; + last_used = iter; + iter = list_entry(iter->slot_node.next, + struct mv_xor_desc_slot, + slot_node); + } + num_slots -= slots_per_op; + } + alloc_tail->group_head = alloc_start; + alloc_tail->async_tx.cookie = -EBUSY; + list_splice(&chain, &alloc_tail->async_tx.tx_list); + mv_chan->last_used = last_used; + mv_desc_clear_next_desc(alloc_start); + mv_desc_clear_next_desc(alloc_tail); + return alloc_tail; + } + } + if (!retry++) + goto retry; + + /* try to free some slots if the allocation fails */ + tasklet_schedule(&mv_chan->irq_tasklet); + + return NULL; +} + +static dma_cookie_t +mv_desc_assign_cookie(struct mv_xor_chan *mv_chan, + struct mv_xor_desc_slot *desc) +{ + dma_cookie_t cookie = mv_chan->common.cookie; + + if (++cookie < 0) + cookie = 1; + mv_chan->common.cookie = desc->async_tx.cookie = cookie; + return cookie; +} + +/************************ DMA engine API functions ****************************/ +static dma_cookie_t +mv_xor_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct mv_xor_desc_slot *sw_desc = to_mv_xor_slot(tx); + struct mv_xor_chan *mv_chan = to_mv_xor_chan(tx->chan); + struct mv_xor_desc_slot *grp_start, *old_chain_tail; + dma_cookie_t cookie; + int new_hw_chain = 1; + + dev_dbg(mv_chan->device->common.dev, + "%s sw_desc %p: async_tx %p\n", + __func__, sw_desc, &sw_desc->async_tx); + + grp_start = sw_desc->group_head; + + spin_lock_bh(&mv_chan->lock); + cookie = mv_desc_assign_cookie(mv_chan, sw_desc); + + if (list_empty(&mv_chan->chain)) + list_splice_init(&sw_desc->async_tx.tx_list, &mv_chan->chain); + else { + new_hw_chain = 0; + + old_chain_tail = list_entry(mv_chan->chain.prev, + struct mv_xor_desc_slot, + chain_node); + list_splice_init(&grp_start->async_tx.tx_list, + &old_chain_tail->chain_node); + + if (!mv_can_chain(grp_start)) + goto submit_done; + + dev_dbg(mv_chan->device->common.dev, "Append to last desc %x\n", + old_chain_tail->async_tx.phys); + + /* fix up the hardware chain */ + mv_desc_set_next_desc(old_chain_tail, grp_start->async_tx.phys); + + /* if the channel is not busy */ + if (!mv_chan_is_busy(mv_chan)) { + u32 current_desc = mv_chan_get_current_desc(mv_chan); + /* + * and the curren desc is the end of the chain before + * the append, then we need to start the channel + */ + if (current_desc == old_chain_tail->async_tx.phys) + new_hw_chain = 1; + } + } + + if (new_hw_chain) + mv_xor_start_new_chain(mv_chan, grp_start); + +submit_done: + spin_unlock_bh(&mv_chan->lock); + + return cookie; +} + +/* returns the number of allocated descriptors */ +static int mv_xor_alloc_chan_resources(struct dma_chan *chan) +{ + char *hw_desc; + int idx; + struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); + struct mv_xor_desc_slot *slot = NULL; + struct mv_xor_platform_data *plat_data = + mv_chan->device->pdev->dev.platform_data; + int num_descs_in_pool = plat_data->pool_size/MV_XOR_SLOT_SIZE; + + /* Allocate descriptor slots */ + idx = mv_chan->slots_allocated; + while (idx < num_descs_in_pool) { + slot = kzalloc(sizeof(*slot), GFP_KERNEL); + if (!slot) { + printk(KERN_INFO "MV XOR Channel only initialized" + " %d descriptor slots", idx); + break; + } + hw_desc = (char *) mv_chan->device->dma_desc_pool_virt; + slot->hw_desc = (void *) &hw_desc[idx * MV_XOR_SLOT_SIZE]; + + dma_async_tx_descriptor_init(&slot->async_tx, chan); + slot->async_tx.tx_submit = mv_xor_tx_submit; + INIT_LIST_HEAD(&slot->chain_node); + INIT_LIST_HEAD(&slot->slot_node); + INIT_LIST_HEAD(&slot->async_tx.tx_list); + hw_desc = (char *) mv_chan->device->dma_desc_pool; + slot->async_tx.phys = + (dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE]; + slot->idx = idx++; + + spin_lock_bh(&mv_chan->lock); + mv_chan->slots_allocated = idx; + list_add_tail(&slot->slot_node, &mv_chan->all_slots); + spin_unlock_bh(&mv_chan->lock); + } + + if (mv_chan->slots_allocated && !mv_chan->last_used) + mv_chan->last_used = list_entry(mv_chan->all_slots.next, + struct mv_xor_desc_slot, + slot_node); + + dev_dbg(mv_chan->device->common.dev, + "allocated %d descriptor slots last_used: %p\n", + mv_chan->slots_allocated, mv_chan->last_used); + + return mv_chan->slots_allocated ? : -ENOMEM; +} + +static struct dma_async_tx_descriptor * +mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, + size_t len, unsigned long flags) +{ + struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); + struct mv_xor_desc_slot *sw_desc, *grp_start; + int slot_cnt; + + dev_dbg(mv_chan->device->common.dev, + "%s dest: %x src %x len: %u flags: %ld\n", + __func__, dest, src, len, flags); + if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) + return NULL; + + BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); + + spin_lock_bh(&mv_chan->lock); + slot_cnt = mv_chan_memcpy_slot_count(len); + sw_desc = mv_xor_alloc_slots(mv_chan, slot_cnt, 1); + if (sw_desc) { + sw_desc->type = DMA_MEMCPY; + sw_desc->async_tx.flags = flags; + grp_start = sw_desc->group_head; + mv_desc_init(grp_start, flags); + mv_desc_set_byte_count(grp_start, len); + mv_desc_set_dest_addr(sw_desc->group_head, dest); + mv_desc_set_src_addr(grp_start, 0, src); + sw_desc->unmap_src_cnt = 1; + sw_desc->unmap_len = len; + } + spin_unlock_bh(&mv_chan->lock); + + dev_dbg(mv_chan->device->common.dev, + "%s sw_desc %p async_tx %p\n", + __func__, sw_desc, sw_desc ? &sw_desc->async_tx : 0); + + return sw_desc ? &sw_desc->async_tx : NULL; +} + +static struct dma_async_tx_descriptor * +mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, + size_t len, unsigned long flags) +{ + struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); + struct mv_xor_desc_slot *sw_desc, *grp_start; + int slot_cnt; + + dev_dbg(mv_chan->device->common.dev, + "%s dest: %x len: %u flags: %ld\n", + __func__, dest, len, flags); + if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) + return NULL; + + BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); + + spin_lock_bh(&mv_chan->lock); + slot_cnt = mv_chan_memset_slot_count(len); + sw_desc = mv_xor_alloc_slots(mv_chan, slot_cnt, 1); + if (sw_desc) { + sw_desc->type = DMA_MEMSET; + sw_desc->async_tx.flags = flags; + grp_start = sw_desc->group_head; + mv_desc_init(grp_start, flags); + mv_desc_set_byte_count(grp_start, len); + mv_desc_set_dest_addr(sw_desc->group_head, dest); + mv_desc_set_block_fill_val(grp_start, value); + sw_desc->unmap_src_cnt = 1; + sw_desc->unmap_len = len; + } + spin_unlock_bh(&mv_chan->lock); + dev_dbg(mv_chan->device->common.dev, + "%s sw_desc %p async_tx %p \n", + __func__, sw_desc, &sw_desc->async_tx); + return sw_desc ? &sw_desc->async_tx : NULL; +} + +static struct dma_async_tx_descriptor * +mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, + unsigned int src_cnt, size_t len, unsigned long flags) +{ + struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); + struct mv_xor_desc_slot *sw_desc, *grp_start; + int slot_cnt; + + if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) + return NULL; + + BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); + + dev_dbg(mv_chan->device->common.dev, + "%s src_cnt: %d len: dest %x %u flags: %ld\n", + __func__, src_cnt, len, dest, flags); + + spin_lock_bh(&mv_chan->lock); + slot_cnt = mv_chan_xor_slot_count(len, src_cnt); + sw_desc = mv_xor_alloc_slots(mv_chan, slot_cnt, 1); + if (sw_desc) { + sw_desc->type = DMA_XOR; + sw_desc->async_tx.flags = flags; + grp_start = sw_desc->group_head; + mv_desc_init(grp_start, flags); + /* the byte count field is the same as in memcpy desc*/ + mv_desc_set_byte_count(grp_start, len); + mv_desc_set_dest_addr(sw_desc->group_head, dest); + sw_desc->unmap_src_cnt = src_cnt; + sw_desc->unmap_len = len; + while (src_cnt--) + mv_desc_set_src_addr(grp_start, src_cnt, src[src_cnt]); + } + spin_unlock_bh(&mv_chan->lock); + dev_dbg(mv_chan->device->common.dev, + "%s sw_desc %p async_tx %p \n", + __func__, sw_desc, &sw_desc->async_tx); + return sw_desc ? &sw_desc->async_tx : NULL; +} + +static void mv_xor_free_chan_resources(struct dma_chan *chan) +{ + struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); + struct mv_xor_desc_slot *iter, *_iter; + int in_use_descs = 0; + + mv_xor_slot_cleanup(mv_chan); + + spin_lock_bh(&mv_chan->lock); + list_for_each_entry_safe(iter, _iter, &mv_chan->chain, + chain_node) { + in_use_descs++; + list_del(&iter->chain_node); + } + list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots, + completed_node) { + in_use_descs++; + list_del(&iter->completed_node); + } + list_for_each_entry_safe_reverse( + iter, _iter, &mv_chan->all_slots, slot_node) { + list_del(&iter->slot_node); + kfree(iter); + mv_chan->slots_allocated--; + } + mv_chan->last_used = NULL; + + dev_dbg(mv_chan->device->common.dev, "%s slots_allocated %d\n", + __func__, mv_chan->slots_allocated); + spin_unlock_bh(&mv_chan->lock); + + if (in_use_descs) + dev_err(mv_chan->device->common.dev, + "freeing %d in use descriptors!\n", in_use_descs); +} + +/** + * mv_xor_is_complete - poll the status of an XOR transaction + * @chan: XOR channel handle + * @cookie: XOR transaction identifier + */ +static enum dma_status mv_xor_is_complete(struct dma_chan *chan, + dma_cookie_t cookie, + dma_cookie_t *done, + dma_cookie_t *used) +{ + struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + enum dma_status ret; + + last_used = chan->cookie; + last_complete = mv_chan->completed_cookie; + mv_chan->is_complete_cookie = cookie; + if (done) + *done = last_complete; + if (used) + *used = last_used; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + if (ret == DMA_SUCCESS) { + mv_xor_clean_completed_slots(mv_chan); + return ret; + } + mv_xor_slot_cleanup(mv_chan); + + last_used = chan->cookie; + last_complete = mv_chan->completed_cookie; + + if (done) + *done = last_complete; + if (used) + *used = last_used; + + return dma_async_is_complete(cookie, last_complete, last_used); +} + +static void mv_dump_xor_regs(struct mv_xor_chan *chan) +{ + u32 val; + + val = __raw_readl(XOR_CONFIG(chan)); + dev_printk(KERN_ERR, chan->device->common.dev, + "config 0x%08x.\n", val); + + val = __raw_readl(XOR_ACTIVATION(chan)); + dev_printk(KERN_ERR, chan->device->common.dev, + "activation 0x%08x.\n", val); + + val = __raw_readl(XOR_INTR_CAUSE(chan)); + dev_printk(KERN_ERR, chan->device->common.dev, + "intr cause 0x%08x.\n", val); + + val = __raw_readl(XOR_INTR_MASK(chan)); + dev_printk(KERN_ERR, chan->device->common.dev, + "intr mask 0x%08x.\n", val); + + val = __raw_readl(XOR_ERROR_CAUSE(chan)); + dev_printk(KERN_ERR, chan->device->common.dev, + "error cause 0x%08x.\n", val); + + val = __raw_readl(XOR_ERROR_ADDR(chan)); + dev_printk(KERN_ERR, chan->device->common.dev, + "error addr 0x%08x.\n", val); +} + +static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan, + u32 intr_cause) +{ + if (intr_cause & (1 << 4)) { + dev_dbg(chan->device->common.dev, + "ignore this error\n"); + return; + } + + dev_printk(KERN_ERR, chan->device->common.dev, + "error on chan %d. intr cause 0x%08x.\n", + chan->idx, intr_cause); + + mv_dump_xor_regs(chan); + BUG(); +} + +static irqreturn_t mv_xor_interrupt_handler(int irq, void *data) +{ + struct mv_xor_chan *chan = data; + u32 intr_cause = mv_chan_get_intr_cause(chan); + + dev_dbg(chan->device->common.dev, "intr cause %x\n", intr_cause); + + if (mv_is_err_intr(intr_cause)) + mv_xor_err_interrupt_handler(chan, intr_cause); + + tasklet_schedule(&chan->irq_tasklet); + + mv_xor_device_clear_eoc_cause(chan); + + return IRQ_HANDLED; +} + +static void mv_xor_issue_pending(struct dma_chan *chan) +{ + struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); + + if (mv_chan->pending >= MV_XOR_THRESHOLD) { + mv_chan->pending = 0; + mv_chan_activate(mv_chan); + } +} + +/* + * Perform a transaction to verify the HW works. + */ +#define MV_XOR_TEST_SIZE 2000 + +static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) +{ + int i; + void *src, *dest; + dma_addr_t src_dma, dest_dma; + struct dma_chan *dma_chan; + dma_cookie_t cookie; + struct dma_async_tx_descriptor *tx; + int err = 0; + struct mv_xor_chan *mv_chan; + + src = kmalloc(sizeof(u8) * MV_XOR_TEST_SIZE, GFP_KERNEL); + if (!src) + return -ENOMEM; + + dest = kzalloc(sizeof(u8) * MV_XOR_TEST_SIZE, GFP_KERNEL); + if (!dest) { + kfree(src); + return -ENOMEM; + } + + /* Fill in src buffer */ + for (i = 0; i < MV_XOR_TEST_SIZE; i++) + ((u8 *) src)[i] = (u8)i; + + /* Start copy, using first DMA channel */ + dma_chan = container_of(device->common.channels.next, + struct dma_chan, + device_node); + if (mv_xor_alloc_chan_resources(dma_chan) < 1) { + err = -ENODEV; + goto out; + } + + dest_dma = dma_map_single(dma_chan->device->dev, dest, + MV_XOR_TEST_SIZE, DMA_FROM_DEVICE); + + src_dma = dma_map_single(dma_chan->device->dev, src, + MV_XOR_TEST_SIZE, DMA_TO_DEVICE); + + tx = mv_xor_prep_dma_memcpy(dma_chan, dest_dma, src_dma, + MV_XOR_TEST_SIZE, 0); + cookie = mv_xor_tx_submit(tx); + mv_xor_issue_pending(dma_chan); + async_tx_ack(tx); + msleep(1); + + if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != + DMA_SUCCESS) { + dev_printk(KERN_ERR, dma_chan->device->dev, + "Self-test copy timed out, disabling\n"); + err = -ENODEV; + goto free_resources; + } + + mv_chan = to_mv_xor_chan(dma_chan); + dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma, + MV_XOR_TEST_SIZE, DMA_FROM_DEVICE); + if (memcmp(src, dest, MV_XOR_TEST_SIZE)) { + dev_printk(KERN_ERR, dma_chan->device->dev, + "Self-test copy failed compare, disabling\n"); + err = -ENODEV; + goto free_resources; + } + +free_resources: + mv_xor_free_chan_resources(dma_chan); +out: + kfree(src); + kfree(dest); + return err; +} + +#define MV_XOR_NUM_SRC_TEST 4 /* must be <= 15 */ +static int __devinit +mv_xor_xor_self_test(struct mv_xor_device *device) +{ + int i, src_idx; + struct page *dest; + struct page *xor_srcs[MV_XOR_NUM_SRC_TEST]; + dma_addr_t dma_srcs[MV_XOR_NUM_SRC_TEST]; + dma_addr_t dest_dma; + struct dma_async_tx_descriptor *tx; + struct dma_chan *dma_chan; + dma_cookie_t cookie; + u8 cmp_byte = 0; + u32 cmp_word; + int err = 0; + struct mv_xor_chan *mv_chan; + + for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) { + xor_srcs[src_idx] = alloc_page(GFP_KERNEL); + if (!xor_srcs[src_idx]) + while (src_idx--) { + __free_page(xor_srcs[src_idx]); + return -ENOMEM; + } + } + + dest = alloc_page(GFP_KERNEL); + if (!dest) + while (src_idx--) { + __free_page(xor_srcs[src_idx]); + return -ENOMEM; + } + + /* Fill in src buffers */ + for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) { + u8 *ptr = page_address(xor_srcs[src_idx]); + for (i = 0; i < PAGE_SIZE; i++) + ptr[i] = (1 << src_idx); + } + + for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) + cmp_byte ^= (u8) (1 << src_idx); + + cmp_word = (cmp_byte << 24) | (cmp_byte << 16) | + (cmp_byte << 8) | cmp_byte; + + memset(page_address(dest), 0, PAGE_SIZE); + + dma_chan = container_of(device->common.channels.next, + struct dma_chan, + device_node); + if (mv_xor_alloc_chan_resources(dma_chan) < 1) { + err = -ENODEV; + goto out; + } + + /* test xor */ + dest_dma = dma_map_page(dma_chan->device->dev, dest, 0, PAGE_SIZE, + DMA_FROM_DEVICE); + + for (i = 0; i < MV_XOR_NUM_SRC_TEST; i++) + dma_srcs[i] = dma_map_page(dma_chan->device->dev, xor_srcs[i], + 0, PAGE_SIZE, DMA_TO_DEVICE); + + tx = mv_xor_prep_dma_xor(dma_chan, dest_dma, dma_srcs, + MV_XOR_NUM_SRC_TEST, PAGE_SIZE, 0); + + cookie = mv_xor_tx_submit(tx); + mv_xor_issue_pending(dma_chan); + async_tx_ack(tx); + msleep(8); + + if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != + DMA_SUCCESS) { + dev_printk(KERN_ERR, dma_chan->device->dev, + "Self-test xor timed out, disabling\n"); + err = -ENODEV; + goto free_resources; + } + + mv_chan = to_mv_xor_chan(dma_chan); + dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma, + PAGE_SIZE, DMA_FROM_DEVICE); + for (i = 0; i < (PAGE_SIZE / sizeof(u32)); i++) { + u32 *ptr = page_address(dest); + if (ptr[i] != cmp_word) { + dev_printk(KERN_ERR, dma_chan->device->dev, + "Self-test xor failed compare, disabling." + " index %d, data %x, expected %x\n", i, + ptr[i], cmp_word); + err = -ENODEV; + goto free_resources; + } + } + +free_resources: + mv_xor_free_chan_resources(dma_chan); +out: + src_idx = MV_XOR_NUM_SRC_TEST; + while (src_idx--) + __free_page(xor_srcs[src_idx]); + __free_page(dest); + return err; +} + +static int __devexit mv_xor_remove(struct platform_device *dev) +{ + struct mv_xor_device *device = platform_get_drvdata(dev); + struct dma_chan *chan, *_chan; + struct mv_xor_chan *mv_chan; + struct mv_xor_platform_data *plat_data = dev->dev.platform_data; + + dma_async_device_unregister(&device->common); + + dma_free_coherent(&dev->dev, plat_data->pool_size, + device->dma_desc_pool_virt, device->dma_desc_pool); + + list_for_each_entry_safe(chan, _chan, &device->common.channels, + device_node) { + mv_chan = to_mv_xor_chan(chan); + list_del(&chan->device_node); + } + + return 0; +} + +static int __devinit mv_xor_probe(struct platform_device *pdev) +{ + int ret = 0; + int irq; + struct mv_xor_device *adev; + struct mv_xor_chan *mv_chan; + struct dma_device *dma_dev; + struct mv_xor_platform_data *plat_data = pdev->dev.platform_data; + + + adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + dma_dev = &adev->common; + + /* allocate coherent memory for hardware descriptors + * note: writecombine gives slightly better performance, but + * requires that we explicitly flush the writes + */ + adev->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev, + plat_data->pool_size, + &adev->dma_desc_pool, + GFP_KERNEL); + if (!adev->dma_desc_pool_virt) + return -ENOMEM; + + adev->id = plat_data->hw_id; + + /* discover transaction capabilites from the platform data */ + dma_dev->cap_mask = plat_data->cap_mask; + adev->pdev = pdev; + platform_set_drvdata(pdev, adev); + + adev->shared = platform_get_drvdata(plat_data->shared); + + INIT_LIST_HEAD(&dma_dev->channels); + + /* set base routines */ + dma_dev->device_alloc_chan_resources = mv_xor_alloc_chan_resources; + dma_dev->device_free_chan_resources = mv_xor_free_chan_resources; + dma_dev->device_is_tx_complete = mv_xor_is_complete; + dma_dev->device_issue_pending = mv_xor_issue_pending; + dma_dev->dev = &pdev->dev; + + /* set prep routines based on capability */ + if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) + dma_dev->device_prep_dma_memcpy = mv_xor_prep_dma_memcpy; + if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)) + dma_dev->device_prep_dma_memset = mv_xor_prep_dma_memset; + if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) { + dma_dev->max_xor = 8; ; + dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor; + } + + mv_chan = devm_kzalloc(&pdev->dev, sizeof(*mv_chan), GFP_KERNEL); + if (!mv_chan) { + ret = -ENOMEM; + goto err_free_dma; + } + mv_chan->device = adev; + mv_chan->idx = plat_data->hw_id; + mv_chan->mmr_base = adev->shared->xor_base; + + if (!mv_chan->mmr_base) { + ret = -ENOMEM; + goto err_free_dma; + } + tasklet_init(&mv_chan->irq_tasklet, mv_xor_tasklet, (unsigned long) + mv_chan); + + /* clear errors before enabling interrupts */ + mv_xor_device_clear_err_status(mv_chan); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = irq; + goto err_free_dma; + } + ret = devm_request_irq(&pdev->dev, irq, + mv_xor_interrupt_handler, + 0, dev_name(&pdev->dev), mv_chan); + if (ret) + goto err_free_dma; + + mv_chan_unmask_interrupts(mv_chan); + + mv_set_mode(mv_chan, DMA_MEMCPY); + + spin_lock_init(&mv_chan->lock); + INIT_LIST_HEAD(&mv_chan->chain); + INIT_LIST_HEAD(&mv_chan->completed_slots); + INIT_LIST_HEAD(&mv_chan->all_slots); + INIT_RCU_HEAD(&mv_chan->common.rcu); + mv_chan->common.device = dma_dev; + + list_add_tail(&mv_chan->common.device_node, &dma_dev->channels); + + if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) { + ret = mv_xor_memcpy_self_test(adev); + dev_dbg(&pdev->dev, "memcpy self test returned %d\n", ret); + if (ret) + goto err_free_dma; + } + + if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) { + ret = mv_xor_xor_self_test(adev); + dev_dbg(&pdev->dev, "xor self test returned %d\n", ret); + if (ret) + goto err_free_dma; + } + + dev_printk(KERN_INFO, &pdev->dev, "Marvell XOR: " + "( %s%s%s%s)\n", + dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "", + dma_has_cap(DMA_MEMSET, dma_dev->cap_mask) ? "fill " : "", + dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "", + dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : ""); + + dma_async_device_register(dma_dev); + goto out; + + err_free_dma: + dma_free_coherent(&adev->pdev->dev, plat_data->pool_size, + adev->dma_desc_pool_virt, adev->dma_desc_pool); + out: + return ret; +} + +static void +mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp, + struct mbus_dram_target_info *dram) +{ + void __iomem *base = msp->xor_base; + u32 win_enable = 0; + int i; + + for (i = 0; i < 8; i++) { + writel(0, base + WINDOW_BASE(i)); + writel(0, base + WINDOW_SIZE(i)); + if (i < 4) + writel(0, base + WINDOW_REMAP_HIGH(i)); + } + + for (i = 0; i < dram->num_cs; i++) { + struct mbus_dram_window *cs = dram->cs + i; + + writel((cs->base & 0xffff0000) | + (cs->mbus_attr << 8) | + dram->mbus_dram_target_id, base + WINDOW_BASE(i)); + writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i)); + + win_enable |= (1 << i); + win_enable |= 3 << (16 + (2 * i)); + } + + writel(win_enable, base + WINDOW_BAR_ENABLE(0)); + writel(win_enable, base + WINDOW_BAR_ENABLE(1)); +} + +static struct platform_driver mv_xor_driver = { + .probe = mv_xor_probe, + .remove = mv_xor_remove, + .driver = { + .owner = THIS_MODULE, + .name = MV_XOR_NAME, + }, +}; + +static int mv_xor_shared_probe(struct platform_device *pdev) +{ + struct mv_xor_platform_shared_data *msd = pdev->dev.platform_data; + struct mv_xor_shared_private *msp; + struct resource *res; + + dev_printk(KERN_NOTICE, &pdev->dev, "Marvell shared XOR driver\n"); + + msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL); + if (!msp) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + msp->xor_base = devm_ioremap(&pdev->dev, res->start, + res->end - res->start + 1); + if (!msp->xor_base) + return -EBUSY; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) + return -ENODEV; + + msp->xor_high_base = devm_ioremap(&pdev->dev, res->start, + res->end - res->start + 1); + if (!msp->xor_high_base) + return -EBUSY; + + platform_set_drvdata(pdev, msp); + + /* + * (Re-)program MBUS remapping windows if we are asked to. + */ + if (msd != NULL && msd->dram != NULL) + mv_xor_conf_mbus_windows(msp, msd->dram); + + return 0; +} + +static int mv_xor_shared_remove(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_driver mv_xor_shared_driver = { + .probe = mv_xor_shared_probe, + .remove = mv_xor_shared_remove, + .driver = { + .owner = THIS_MODULE, + .name = MV_XOR_SHARED_NAME, + }, +}; + + +static int __init mv_xor_init(void) +{ + int rc; + + rc = platform_driver_register(&mv_xor_shared_driver); + if (!rc) { + rc = platform_driver_register(&mv_xor_driver); + if (rc) + platform_driver_unregister(&mv_xor_shared_driver); + } + return rc; +} +module_init(mv_xor_init); + +/* it's currently unsafe to unload this module */ +#if 0 +static void __exit mv_xor_exit(void) +{ + platform_driver_unregister(&mv_xor_driver); + platform_driver_unregister(&mv_xor_shared_driver); + return; +} + +module_exit(mv_xor_exit); +#endif + +MODULE_AUTHOR("Saeed Bishara "); +MODULE_DESCRIPTION("DMA engine driver for Marvell's XOR engine"); +MODULE_LICENSE("GPL"); diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h new file mode 100644 index 00000000000..06cafe1ef52 --- /dev/null +++ b/drivers/dma/mv_xor.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2007, 2008, Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MV_XOR_H +#define MV_XOR_H + +#include +#include +#include +#include + +#define USE_TIMER +#define MV_XOR_SLOT_SIZE 64 +#define MV_XOR_THRESHOLD 1 + +#define XOR_OPERATION_MODE_XOR 0 +#define XOR_OPERATION_MODE_MEMCPY 2 +#define XOR_OPERATION_MODE_MEMSET 4 + +#define XOR_CURR_DESC(chan) (chan->mmr_base + 0x210 + (chan->idx * 4)) +#define XOR_NEXT_DESC(chan) (chan->mmr_base + 0x200 + (chan->idx * 4)) +#define XOR_BYTE_COUNT(chan) (chan->mmr_base + 0x220 + (chan->idx * 4)) +#define XOR_DEST_POINTER(chan) (chan->mmr_base + 0x2B0 + (chan->idx * 4)) +#define XOR_BLOCK_SIZE(chan) (chan->mmr_base + 0x2C0 + (chan->idx * 4)) +#define XOR_INIT_VALUE_LOW(chan) (chan->mmr_base + 0x2E0) +#define XOR_INIT_VALUE_HIGH(chan) (chan->mmr_base + 0x2E4) + +#define XOR_CONFIG(chan) (chan->mmr_base + 0x10 + (chan->idx * 4)) +#define XOR_ACTIVATION(chan) (chan->mmr_base + 0x20 + (chan->idx * 4)) +#define XOR_INTR_CAUSE(chan) (chan->mmr_base + 0x30) +#define XOR_INTR_MASK(chan) (chan->mmr_base + 0x40) +#define XOR_ERROR_CAUSE(chan) (chan->mmr_base + 0x50) +#define XOR_ERROR_ADDR(chan) (chan->mmr_base + 0x60) +#define XOR_INTR_MASK_VALUE 0x3F5 + +#define WINDOW_BASE(w) (0x250 + ((w) << 2)) +#define WINDOW_SIZE(w) (0x270 + ((w) << 2)) +#define WINDOW_REMAP_HIGH(w) (0x290 + ((w) << 2)) +#define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2)) + +struct mv_xor_shared_private { + void __iomem *xor_base; + void __iomem *xor_high_base; +}; + + +/** + * struct mv_xor_device - internal representation of a XOR device + * @pdev: Platform device + * @id: HW XOR Device selector + * @dma_desc_pool: base of DMA descriptor region (DMA address) + * @dma_desc_pool_virt: base of DMA descriptor region (CPU address) + * @common: embedded struct dma_device + */ +struct mv_xor_device { + struct platform_device *pdev; + int id; + dma_addr_t dma_desc_pool; + void *dma_desc_pool_virt; + struct dma_device common; + struct mv_xor_shared_private *shared; +}; + +/** + * struct mv_xor_chan - internal representation of a XOR channel + * @pending: allows batching of hardware operations + * @completed_cookie: identifier for the most recently completed operation + * @lock: serializes enqueue/dequeue operations to the descriptors pool + * @mmr_base: memory mapped register base + * @idx: the index of the xor channel + * @chain: device chain view of the descriptors + * @completed_slots: slots completed by HW but still need to be acked + * @device: parent device + * @common: common dmaengine channel object members + * @last_used: place holder for allocation to continue from where it left off + * @all_slots: complete domain of slots usable by the channel + * @slots_allocated: records the actual size of the descriptor slot pool + * @irq_tasklet: bottom half where mv_xor_slot_cleanup runs + */ +struct mv_xor_chan { + int pending; + dma_cookie_t completed_cookie; + spinlock_t lock; /* protects the descriptor slot pool */ + void __iomem *mmr_base; + unsigned int idx; + enum dma_transaction_type current_type; + struct list_head chain; + struct list_head completed_slots; + struct mv_xor_device *device; + struct dma_chan common; + struct mv_xor_desc_slot *last_used; + struct list_head all_slots; + int slots_allocated; + struct tasklet_struct irq_tasklet; +#ifdef USE_TIMER + unsigned long cleanup_time; + u32 current_on_last_cleanup; + dma_cookie_t is_complete_cookie; +#endif +}; + +/** + * struct mv_xor_desc_slot - software descriptor + * @slot_node: node on the mv_xor_chan.all_slots list + * @chain_node: node on the mv_xor_chan.chain list + * @completed_node: node on the mv_xor_chan.completed_slots list + * @hw_desc: virtual address of the hardware descriptor chain + * @phys: hardware address of the hardware descriptor chain + * @group_head: first operation in a transaction + * @slot_cnt: total slots used in an transaction (group of operations) + * @slots_per_op: number of slots per operation + * @idx: pool index + * @unmap_src_cnt: number of xor sources + * @unmap_len: transaction bytecount + * @async_tx: support for the async_tx api + * @group_list: list of slots that make up a multi-descriptor transaction + * for example transfer lengths larger than the supported hw max + * @xor_check_result: result of zero sum + * @crc32_result: result crc calculation + */ +struct mv_xor_desc_slot { + struct list_head slot_node; + struct list_head chain_node; + struct list_head completed_node; + enum dma_transaction_type type; + void *hw_desc; + struct mv_xor_desc_slot *group_head; + u16 slot_cnt; + u16 slots_per_op; + u16 idx; + u16 unmap_src_cnt; + u32 value; + size_t unmap_len; + struct dma_async_tx_descriptor async_tx; + union { + u32 *xor_check_result; + u32 *crc32_result; + }; +#ifdef USE_TIMER + unsigned long arrival_time; + struct timer_list timeout; +#endif +}; + +/* This structure describes XOR descriptor size 64bytes */ +struct mv_xor_desc { + u32 status; /* descriptor execution status */ + u32 crc32_result; /* result of CRC-32 calculation */ + u32 desc_command; /* type of operation to be carried out */ + u32 phy_next_desc; /* next descriptor address pointer */ + u32 byte_count; /* size of src/dst blocks in bytes */ + u32 phy_dest_addr; /* destination block address */ + u32 phy_src_addr[8]; /* source block addresses */ + u32 reserved0; + u32 reserved1; +}; + +#define to_mv_sw_desc(addr_hw_desc) \ + container_of(addr_hw_desc, struct mv_xor_desc_slot, hw_desc) + +#define mv_hw_desc_slot_idx(hw_desc, idx) \ + ((void *)(((unsigned long)hw_desc) + ((idx) << 5))) + +#define MV_XOR_MIN_BYTE_COUNT (128) +#define XOR_MAX_BYTE_COUNT ((16 * 1024 * 1024) - 1) +#define MV_XOR_MAX_BYTE_COUNT XOR_MAX_BYTE_COUNT + + +#endif diff --git a/include/asm-arm/plat-orion/mv_xor.h b/include/asm-arm/plat-orion/mv_xor.h new file mode 100644 index 00000000000..c349e8ff5cc --- /dev/null +++ b/include/asm-arm/plat-orion/mv_xor.h @@ -0,0 +1,28 @@ +/* + * Marvell XOR platform device data definition file. + */ + +#ifndef __ASM_PLAT_ORION_MV_XOR_H +#define __ASM_PLAT_ORION_MV_XOR_H + +#include +#include + +#define MV_XOR_SHARED_NAME "mv_xor_shared" +#define MV_XOR_NAME "mv_xor" + +struct mbus_dram_target_info; + +struct mv_xor_platform_shared_data { + struct mbus_dram_target_info *dram; +}; + +struct mv_xor_platform_data { + struct platform_device *shared; + int hw_id; + dma_cap_mask_t cap_mask; + size_t pool_size; +}; + + +#endif -- cgit v1.2.3-70-g09d2 From 66a7f72d9892013e9ea663260f407758989ff510 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 2 Jun 2008 16:10:20 +0100 Subject: [ARM] pxa: remove pxa_set_cken() pxa_set_cken() is now unused, remove it. Signed-off-by: Russell King --- arch/arm/mach-pxa/generic.c | 18 ------------------ include/asm-arm/arch-pxa/hardware.h | 9 --------- 2 files changed, 27 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index c2f102339f5..ca053226fba 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -26,7 +26,6 @@ #include #include -#include /* for __pxa_set_cken */ #include "generic.h" @@ -60,23 +59,6 @@ unsigned int get_memclk_frequency_10khz(void) } EXPORT_SYMBOL(get_memclk_frequency_10khz); -/* - * Routine to safely enable or disable a clock in the CKEN - */ -void __pxa_set_cken(int clock, int enable) -{ - unsigned long flags; - local_irq_save(flags); - - if (enable) - CKEN |= (1 << clock); - else - CKEN &= ~(1 << clock); - - local_irq_restore(flags); -} -EXPORT_SYMBOL(__pxa_set_cken); - /* * Intel PXA2xx internal register mapping. * diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index e25558faa5a..d9af6dabc89 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -191,15 +191,6 @@ extern int pxa_gpio_get_value(unsigned gpio); */ extern void pxa_gpio_set_value(unsigned gpio, int value); -/* - * Routine to enable or disable CKEN - */ -static inline void __deprecated pxa_set_cken(int clock, int enable) -{ - extern void __pxa_set_cken(int clock, int enable); - __pxa_set_cken(clock, enable); -} - /* * return current memory and LCD clock frequency in units of 10kHz */ -- cgit v1.2.3-70-g09d2 From 918dbcba4ee3f0ad7d617b3969d5016481b9ceff Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 2 Jul 2008 13:53:45 +0100 Subject: [ARM] 5145/1: PXA2xx: provide api to control IrDA pins state Provide a set of functions to control state of pins dedicated to IrDA. Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King --- arch/arm/mach-pxa/Makefile | 4 ++-- arch/arm/mach-pxa/pxa2xx.c | 46 +++++++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/irda.h | 4 ++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-pxa/pxa2xx.c (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 02cbc3cfbe0..c4dfbe87fc4 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -13,8 +13,8 @@ obj-$(CONFIG_PXA_SSP) += ssp.o obj-$(CONFIG_PXA_PWM) += pwm.o # SoC-specific code -obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa25x.o -obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa27x.o +obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o +obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o obj-$(CONFIG_CPU_PXA300) += pxa300.o obj-$(CONFIG_CPU_PXA320) += pxa320.o diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c new file mode 100644 index 00000000000..d4f6415e841 --- /dev/null +++ b/arch/arm/mach-pxa/pxa2xx.c @@ -0,0 +1,46 @@ +/* + * linux/arch/arm/mach-pxa/pxa2xx.c + * + * code specific to pxa2xx + * + * Copyright (C) 2008 Dmitry Baryshkov + * + * 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 +#include +#include + +#include +#include +#include + +static unsigned long pxa2xx_mfp_fir[] = { + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, +}; + +static unsigned long pxa2xx_mfp_sir[] = { + GPIO46_STUART_RXD, + GPIO47_STUART_TXD, +}; + +static unsigned long pxa2xx_mfp_off[] = { + GPIO46_GPIO | MFP_LPM_DRIVE_LOW, + GPIO47_GPIO | MFP_LPM_DRIVE_LOW, +}; + +void pxa2xx_transceiver_mode(struct device *dev, int mode) +{ + if (mode & IR_OFF) { + pxa2xx_mfp_config(pxa2xx_mfp_off, ARRAY_SIZE(pxa2xx_mfp_off)); + } else if (mode & IR_SIRMODE) { + pxa2xx_mfp_config(pxa2xx_mfp_sir, ARRAY_SIZE(pxa2xx_mfp_sir)); + } else if (mode & IR_FIRMODE) { + pxa2xx_mfp_config(pxa2xx_mfp_fir, ARRAY_SIZE(pxa2xx_mfp_fir)); + } else + BUG(); +} diff --git a/include/asm-arm/arch-pxa/irda.h b/include/asm-arm/arch-pxa/irda.h index 99f4f423a8e..0a50c3c763d 100644 --- a/include/asm-arm/arch-pxa/irda.h +++ b/include/asm-arm/arch-pxa/irda.h @@ -16,4 +16,8 @@ struct pxaficp_platform_data { extern void pxa_set_ficp_info(struct pxaficp_platform_data *info); +#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) +void pxa2xx_transceiver_mode(struct device *dev, int mode); +#endif + #endif -- cgit v1.2.3-70-g09d2 From 9f19d6382854d6b2d58cc364253779479e14facc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 10 Jun 2008 12:30:05 +0100 Subject: [ARM] 5085/2: PXA: Move AC97 over to the new central device declaration model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As well as moving all the device declarations to a single one in devices.c this causes all platforms to register the I/O and interrupt resources for the AC97 controller. Cc: eric miao Cc: Mike Rapoport Cc: Lennert Buytenhek Cc: Jürgen Schindele Cc: Juergen Beisert Signed-off-by: Mark Brown Signed-off-by: Russell King --- arch/arm/mach-pxa/cm-x270.c | 9 ++------- arch/arm/mach-pxa/devices.c | 32 ++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/devices.h | 1 + arch/arm/mach-pxa/em-x270.c | 9 ++------- arch/arm/mach-pxa/lpd270.c | 8 ++------ arch/arm/mach-pxa/lubbock.c | 8 ++------ arch/arm/mach-pxa/mainstone.c | 8 +------- arch/arm/mach-pxa/pcm990-baseboard.c | 34 ++-------------------------------- arch/arm/mach-pxa/trizeps4.c | 10 +--------- include/asm-arm/arch-pxa/audio.h | 2 ++ 10 files changed, 47 insertions(+), 74 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index 6d4416a4f37..b3c3fd72d04 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -81,12 +82,6 @@ static struct platform_device cmx270_device_dm9k = { } }; -/* audio device */ -static struct platform_device cmx270_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - /* touchscreen controller */ static struct platform_device cmx270_ts_device = { .name = "ucb1400_ts", @@ -219,7 +214,6 @@ static struct platform_device cmx270_ata = { /* platform devices */ static struct platform_device *platform_devices[] __initdata = { &cmx270_device_dm9k, - &cmx270_audio_device, &cmx270_rtc_device, &cmx270_2700G, &cmx270_led_device, @@ -594,6 +588,7 @@ static void __init cmx270_init(void) /* register CM-X270 platform devices */ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + pxa_set_ac97_info(NULL); /* set MCI and OHCI platform parameters */ pxa_set_mci_info(&cmx270_mci_platform_data); diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 123ee19ca79..a6f2390ce66 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "devices.h" #include "generic.h" @@ -298,6 +299,37 @@ struct platform_device pxa_device_rtc = { .id = -1, }; +static struct resource pxa_ac97_resources[] = { + [0] = { + .start = 0x40500000, + .end = 0x40500000 + 0xfff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_AC97, + .end = IRQ_AC97, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxa_ac97_dmamask = 0xffffffffUL; + +struct platform_device pxa_device_ac97 = { + .name = "pxa2xx-ac97", + .id = -1, + .dev = { + .dma_mask = &pxa_ac97_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa_ac97_resources), + .resource = pxa_ac97_resources, +}; + +void __init pxa_set_ac97_info(pxa2xx_audio_ops_t *ops) +{ + pxa_register_device(&pxa_device_ac97, ops); +} + #ifdef CONFIG_PXA25x static struct resource pxa25x_resource_pwm0[] = { diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index 881d1a7bf17..b852eb18daa 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -12,6 +12,7 @@ extern struct platform_device pxa_device_i2c; extern struct platform_device pxa_device_i2s; extern struct platform_device pxa_device_ficp; extern struct platform_device pxa_device_rtc; +extern struct platform_device pxa_device_ac97; extern struct platform_device pxa27x_device_i2c_power; extern struct platform_device pxa27x_device_ohci; diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 1269ac99150..e23865affc0 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -73,12 +74,6 @@ static struct platform_device em_x270_dm9k = { } }; -/* audio device */ -static struct platform_device em_x270_audio = { - .name = "pxa2xx-ac97", - .id = -1, -}; - /* WM9712 touchscreen controller. Hopefully the driver will make it to * the mainstream sometime */ static struct platform_device em_x270_ts = { @@ -218,7 +213,6 @@ static struct platform_device em_x270_nand = { /* platform devices */ static struct platform_device *platform_devices[] __initdata = { &em_x270_dm9k, - &em_x270_audio, &em_x270_ts, &em_x270_rtc, &em_x270_nand, @@ -326,6 +320,7 @@ static void __init em_x270_init(void) /* register EM-X270 platform devices */ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + pxa_set_ac97_info(NULL); /* set MCI and OHCI platform parameters */ pxa_set_mci_info(&em_x270_mci_platform_data); diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 183b587672a..cc1c4fa0614 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -168,11 +168,6 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -static struct platform_device lpd270_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct resource lpd270_flash_resources[] = { [0] = { .start = PXA_CS0_PHYS, @@ -412,7 +407,6 @@ __setup("lcd=", lpd270_set_lcd); static struct platform_device *platform_devices[] __initdata = { &smc91x_device, &lpd270_backlight_device, - &lpd270_audio_device, &lpd270_flash_device[0], &lpd270_flash_device[1], }; @@ -456,6 +450,8 @@ static void __init lpd270_init(void) platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + pxa_set_ac97_info(NULL); + if (lpd270_lcd_to_use != NULL) set_pxa_fb_info(lpd270_lcd_to_use); diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 7b9bdd0c666..a3fae413920 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -196,11 +197,6 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = { // no D+ pullup; lubbock can't connect/disconnect in software }; -static struct platform_device lub_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct resource sa1111_resources[] = { [0] = { .start = 0x10000000, @@ -368,7 +364,6 @@ static struct platform_device lubbock_flash_device[2] = { static struct platform_device *devices[] __initdata = { &sa1111_device, - &lub_audio_device, &smc91x_device, &lubbock_flash_device[0], &lubbock_flash_device[1], @@ -494,6 +489,7 @@ static void __init lubbock_init(void) set_pxa_fb_info(&sharp_lm8v31); pxa_set_mci_info(&lubbock_mci_platform_data); pxa_set_ficp_info(&lubbock_ficp_platform_data); + pxa_set_ac97_info(NULL); lubbock_flash_data[0].width = lubbock_flash_data[1].width = (BOOT_DEF & 1) ? 2 : 4; diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 266594426e8..f2e9e7c4da8 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -280,12 +280,6 @@ static pxa2xx_audio_ops_t mst_audio_ops = { .resume = mst_audio_resume, }; -static struct platform_device mst_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, - .dev = { .platform_data = &mst_audio_ops }, -}; - static struct resource flash_resources[] = { [0] = { .start = PXA_CS0_PHYS, @@ -499,7 +493,6 @@ static struct platform_device mst_gpio_keys_device = { static struct platform_device *platform_devices[] __initdata = { &smc91x_device, - &mst_audio_device, &mst_flash_device[0], &mst_flash_device[1], &mst_gpio_keys_device, @@ -609,6 +602,7 @@ static void __init mainstone_init(void) pxa_set_ficp_info(&mainstone_ficp_platform_data); pxa_set_ohci_info(&mainstone_ohci_platform_data); pxa_set_i2c_info(NULL); + pxa_set_ac97_info(&mst_audio_ops); mainstone_init_keypad(); } diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 2564e16e4e2..5d87c7c866e 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -423,36 +424,6 @@ static struct i2c_board_info __initdata pcm990_i2c_devices[] = { }; #endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */ -/* - * AC97 support - * Note: The connected AC97 mixer also reports interrupts at PCM990_AC97_IRQ - */ -static struct resource pxa27x_ac97_resources[] = { - [0] = { - .start = 0x40500000, - .end = 0x40500000 + 0xfff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_AC97, - .end = IRQ_AC97, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 pxa_ac97_dmamask = 0xffffffffUL; - -static struct platform_device pxa27x_device_ac97 = { - .name = "pxa2xx-ac97", - .id = -1, - .dev = { - .dma_mask = &pxa_ac97_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(pxa27x_ac97_resources), - .resource = pxa27x_ac97_resources, -}; - /* * enable generic access to the base board control CPLDs U6 and U7 */ @@ -490,8 +461,6 @@ void __init pcm990_baseboard_init(void) pxa_gpio_mode(GPIO16_PWM0_MD); platform_device_register(&pcm990_backlight_device); - platform_device_register(&pxa27x_device_ac97); - /* MMC */ pxa_set_mci_info(&pcm990_mci_platform_data); @@ -499,6 +468,7 @@ void __init pcm990_baseboard_init(void) pxa_set_ohci_info(&pcm990_ohci_platform_data); pxa_set_i2c_info(NULL); + pxa_set_ac97_info(NULL); #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE) pxa_set_camera_info(&pcm990_pxacamera_platform_data); diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index bc7c465ef32..61e24402308 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -176,19 +176,10 @@ static struct platform_device uart_devices = { .resource = NULL, }; -/******************************************************************************************** - * PXA270 ac97 sound codec - ********************************************************************************************/ -static struct platform_device ac97_audio_device = { - .name = "pxa2xx-ac97", - .id = -1, -}; - static struct platform_device * trizeps4_devices[] __initdata = { &flash_device, &uart_devices, &dm9000_device, - &ac97_audio_device, }; #ifdef CONFIG_MACH_TRIZEPS4_CONXS @@ -439,6 +430,7 @@ static void __init trizeps4_init(void) pxa_set_mci_info(&trizeps4_mci_platform_data); pxa_set_ficp_info(&trizeps4_ficp_platform_data); pxa_set_ohci_info(&trizeps4_ohci_platform_data); + pxa_set_ac97_info(NULL); } static void __init trizeps4_map_io(void) diff --git a/include/asm-arm/arch-pxa/audio.h b/include/asm-arm/arch-pxa/audio.h index 52bbe3bc25e..f82f96dd105 100644 --- a/include/asm-arm/arch-pxa/audio.h +++ b/include/asm-arm/arch-pxa/audio.h @@ -12,4 +12,6 @@ typedef struct { void *priv; } pxa2xx_audio_ops_t; +extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); + #endif -- cgit v1.2.3-70-g09d2 From e172274ccc55d20536fbdceb6131f38e288541e0 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 13 Jun 2008 09:17:31 +0100 Subject: [ARM] 5088/3: pxa2xx: add pxa2xx_set_spi_info to register pxa2xx-spi platform devices Add a function to dynamically allocate and register pxa2xx-spi platform devices, to be used by PXA2xx and PXA3xx based systems. Switch pcm027 and lubbock to use it. Signed-off-by: Guennadi Liakhovetski Acked-by: Eric Miao Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 1 + arch/arm/mach-pxa/devices.c | 18 ++++++++++++++++++ arch/arm/mach-pxa/lubbock.c | 10 +--------- arch/arm/mach-pxa/pcm027.c | 31 +++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/pxa2xx_spi.h | 2 ++ 5 files changed, 53 insertions(+), 9 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 914bb33dab9..ef7271e3781 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -139,6 +139,7 @@ config MACH_PCM027 bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" select PXA27x select IWMMXT + select PXA_SSP endmenu diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index a6f2390ce66..abc161dd083 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -831,3 +832,20 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info) } #endif /* CONFIG_PXA3xx */ + +/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1. + * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */ +void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info) +{ + struct platform_device *pd; + + pd = platform_device_alloc("pxa2xx-spi", id); + if (pd == NULL) { + printk(KERN_ERR "pxa2xx-spi: failed to allocate device id %d\n", + id); + return; + } + + pd->dev.platform_data = info; + platform_device_add(pd); +} diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index a3fae413920..e041cceab16 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -226,14 +226,6 @@ static struct pxa2xx_spi_master pxa_ssp_master_info = { .num_chipselect = 0, }; -static struct platform_device pxa_ssp = { - .name = "pxa2xx-spi", - .id = 1, - .dev = { - .platform_data = &pxa_ssp_master_info, - }, -}; - static int lubbock_ads7846_pendown_state(void) { /* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */ @@ -367,7 +359,6 @@ static struct platform_device *devices[] __initdata = { &smc91x_device, &lubbock_flash_device[0], &lubbock_flash_device[1], - &pxa_ssp, }; static struct pxafb_mode_info sharp_lm8v31_mode = { @@ -501,6 +492,7 @@ static void __init lubbock_init(void) lubbock_flash_data[flashboot].name = "boot-rom"; (void) platform_add_devices(devices, ARRAY_SIZE(devices)); + pxa2xx_set_spi_info(1, &pxa_ssp_master_info); spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); } diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index 3b945eb0aee..377f3be8ce5 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c @@ -24,7 +24,9 @@ #include #include #include +#include #include + #include #include #include @@ -108,6 +110,32 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; +/* + * SPI host and devices + */ +static struct pxa2xx_spi_master pxa_ssp_master_info = { + .num_chipselect = 1, +}; + +static struct max7301_platform_data max7301_info = { + .base = -1, +}; + +/* bus_num must match id in pxa2xx_set_spi_info() call */ +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "max7301", + .platform_data = &max7301_info, + .max_speed_hz = 13000000, + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_0, + }, +}; + +/* + * NOR flash + */ static struct physmap_flash_data pcm027_flash_data = { .width = 4, }; @@ -190,6 +218,9 @@ static void __init pcm027_init(void) #ifdef CONFIG_MACH_PCM990_BASEBOARD pcm990_baseboard_init(); #endif + + pxa2xx_set_spi_info(1, &pxa_ssp_master_info); + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); } static void __init pcm027_map_io(void) diff --git a/include/asm-arm/arch-pxa/pxa2xx_spi.h b/include/asm-arm/arch-pxa/pxa2xx_spi.h index 3459fb26ce9..2206cb61a9f 100644 --- a/include/asm-arm/arch-pxa/pxa2xx_spi.h +++ b/include/asm-arm/arch-pxa/pxa2xx_spi.h @@ -41,4 +41,6 @@ struct pxa2xx_spi_chip { void (*cs_control)(u32 command); }; +extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info); + #endif /*PXA2XX_SPI_H_*/ -- cgit v1.2.3-70-g09d2 From 839257c9a818c81a802fdd705602589355571662 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Tue, 17 Jun 2008 09:49:27 +0100 Subject: [ARM] 5106/1: CM-X270: remove unneeded cm-x270.h The include/asm-arm/arch-pxa/cm-x270.h is not used anymore. Remove it. Signed-off-by: Mike Rapoport Signed-off-by: Russell King --- include/asm-arm/arch-pxa/cm-x270.h | 50 -------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 include/asm-arm/arch-pxa/cm-x270.h (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/cm-x270.h b/include/asm-arm/arch-pxa/cm-x270.h deleted file mode 100644 index f8fac9e1800..00000000000 --- a/include/asm-arm/arch-pxa/cm-x270.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * linux/include/asm/arch-pxa/cm-x270.h - * - * Copyright Compulab Ltd., 2003, 2007 - * Mike Rapoport - * - * 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. - */ - - -/* CM-x270 device physical addresses */ -#define CMX270_CS1_PHYS (PXA_CS1_PHYS) -#define MARATHON_PHYS (PXA_CS2_PHYS) -#define CMX270_IDE104_PHYS (PXA_CS3_PHYS) -#define CMX270_IT8152_PHYS (PXA_CS4_PHYS) - -/* Statically mapped regions */ -#define CMX270_VIRT_BASE (0xe8000000) -#define CMX270_IT8152_VIRT (CMX270_VIRT_BASE) -#define CMX270_IDE104_VIRT (CMX270_IT8152_VIRT + SZ_64M) - -/* GPIO related definitions */ -#define GPIO_IT8152_IRQ (22) - -#define IRQ_GPIO_IT8152_IRQ IRQ_GPIO(GPIO_IT8152_IRQ) -#define PME_IRQ IRQ_GPIO(0) -#define CMX270_IDE_IRQ IRQ_GPIO(100) -#define CMX270_GPIRQ1 IRQ_GPIO(101) -#define CMX270_TOUCHIRQ IRQ_GPIO(96) -#define CMX270_ETHIRQ IRQ_GPIO(10) -#define CMX270_GFXIRQ IRQ_GPIO(95) -#define CMX270_NANDIRQ IRQ_GPIO(89) -#define CMX270_MMC_IRQ IRQ_GPIO(83) - -/* PCMCIA related definitions */ -#define PCC_DETECT(x) (GPLR(84 - (x)) & GPIO_bit(84 - (x))) -#define PCC_READY(x) (GPLR(82 - (x)) & GPIO_bit(82 - (x))) - -#define PCMCIA_S0_CD_VALID IRQ_GPIO(84) -#define PCMCIA_S0_CD_VALID_EDGE GPIO_BOTH_EDGES - -#define PCMCIA_S1_CD_VALID IRQ_GPIO(83) -#define PCMCIA_S1_CD_VALID_EDGE GPIO_BOTH_EDGES - -#define PCMCIA_S0_RDYINT IRQ_GPIO(82) -#define PCMCIA_S1_RDYINT IRQ_GPIO(81) - -#define PCMCIA_RESET_GPIO 53 -- cgit v1.2.3-70-g09d2 From 6d3dfe4a3141476a3cf59ce6d2d1c25f9b5cfae8 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 2 Jun 2008 15:58:03 +0800 Subject: [ARM] pxa: allow display of uncompress message through STUART Some boards use UART other than FFUART for the console, E.g. Marvell PXA3xx Form Factor Platform (aka Littleton) uses STUART. This patch modifies the uncompress.h so that display of the uncompress message is routed to the STUART. Signed-off-by: Eric Miao Signed-off-by: Russell King --- include/asm-arm/arch-pxa/uncompress.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/uncompress.h b/include/asm-arm/arch-pxa/uncompress.h index dadf4c20b62..f4551269aaf 100644 --- a/include/asm-arm/arch-pxa/uncompress.h +++ b/include/asm-arm/arch-pxa/uncompress.h @@ -11,11 +11,11 @@ #include #include +#include -#define __REG(x) ((volatile unsigned long *)x) - -#define UART FFUART +#define __REG(x) ((volatile unsigned long *)x) +static volatile unsigned long *UART = FFUART; static inline void putc(char c) { @@ -33,8 +33,13 @@ static inline void flush(void) { } +static inline void arch_decomp_setup(void) +{ + if (machine_is_littleton()) + UART = STUART; +} + /* * nothing to do */ -#define arch_decomp_setup() #define arch_decomp_wdog() -- cgit v1.2.3-70-g09d2 From 566b450c33ea43f339d54d445f4ea1ab2e021909 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 16 Jun 2008 09:47:47 +0800 Subject: [ARM] pxa: add pxa2xx_mfp_set_lpm() to facilitate low power state change Some boards want to change low power state of pins on-the-fly, this function helps to facilitate that operation instead of switching back-n-forth between two configurations with pxa2xx_mfp_config(). Signed-off-by: Eric Miao Tested-by: Robert Jarzmik Signed-off-by: Russell King --- arch/arm/mach-pxa/mfp-pxa2xx.c | 51 +++++++++++++++++++++++++---------- include/asm-arm/arch-pxa/mfp-pxa2xx.h | 1 + 2 files changed, 38 insertions(+), 14 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index ed91c043471..fd4545eab80 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -39,6 +39,28 @@ struct gpio_desc { static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1]; +static int __mfp_config_lpm(unsigned gpio, unsigned long lpm) +{ + unsigned mask = GPIO_bit(gpio); + + /* low power state */ + switch (lpm) { + case MFP_LPM_DRIVE_HIGH: + PGSR(gpio) |= mask; + break; + case MFP_LPM_DRIVE_LOW: + PGSR(gpio) &= ~mask; + break; + case MFP_LPM_INPUT: + break; + default: + pr_warning("%s: invalid low power state for GPIO%d\n", + __func__, gpio); + return -EINVAL; + } + return 0; +} + static int __mfp_config_gpio(unsigned gpio, unsigned long c) { unsigned long gafr, mask = GPIO_bit(gpio); @@ -57,21 +79,8 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) else GPDR(gpio) &= ~mask; - /* low power state */ - switch (c & MFP_LPM_STATE_MASK) { - case MFP_LPM_DRIVE_HIGH: - PGSR(gpio) |= mask; - break; - case MFP_LPM_DRIVE_LOW: - PGSR(gpio) &= ~mask; - break; - case MFP_LPM_INPUT: - break; - default: - pr_warning("%s: invalid low power state for GPIO%d\n", - __func__, gpio); + if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK)) return -EINVAL; - } /* give early warning if MFP_LPM_CAN_WAKEUP is set on the * configurations of those pins not able to wakeup @@ -124,6 +133,20 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num) } } +void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm) +{ + unsigned long flags; + int gpio; + + gpio = __mfp_validate(mfp); + if (gpio < 0) + return; + + local_irq_save(flags); + __mfp_config_lpm(gpio, lpm); + local_irq_restore(flags); +} + int gpio_set_wake(unsigned int gpio, unsigned int on) { struct gpio_desc *d; diff --git a/include/asm-arm/arch-pxa/mfp-pxa2xx.h b/include/asm-arm/arch-pxa/mfp-pxa2xx.h index db8d890d237..8de1c0dae62 100644 --- a/include/asm-arm/arch-pxa/mfp-pxa2xx.h +++ b/include/asm-arm/arch-pxa/mfp-pxa2xx.h @@ -128,5 +128,6 @@ #define GPIO84_GPIO MFP_CFG_IN(GPIO84, AF0) extern void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num); +extern void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm); extern int gpio_set_wake(unsigned int gpio, unsigned int on); #endif /* __ASM_ARCH_MFP_PXA2XX_H */ -- cgit v1.2.3-70-g09d2 From 9ae819a819b4dfc60ac13dd1f1e1a7eaa3d4a6cb Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 2 Jun 2008 15:22:03 +0800 Subject: [ARM] pxa: add pxa3xx NAND device and clock sources A pxa3xx_set_nand_info() is also introduced to set the PXA3xx NAND driver specific platform_data structure pointer. Signed-off-by: Eric Miao Cc: Sergey Podstavin Signed-off-by: Russell King --- arch/arm/mach-pxa/devices.c | 43 ++++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/devices.h | 2 ++ arch/arm/mach-pxa/pxa300.c | 5 ++++ arch/arm/mach-pxa/pxa320.c | 11 +++++++++ include/asm-arm/arch-pxa/pxa3xx_nand.h | 2 ++ 5 files changed, 63 insertions(+) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index abc161dd083..84489dc51d8 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "devices.h" #include "generic.h" @@ -831,6 +832,48 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info) pxa_register_device(&pxa3xx_device_mci3, info); } +static struct resource pxa3xx_resources_nand[] = { + [0] = { + .start = 0x43100000, + .end = 0x43100053, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NAND, + .end = IRQ_NAND, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* DRCMR for Data DMA */ + .start = 97, + .end = 97, + .flags = IORESOURCE_DMA, + }, + [3] = { + /* DRCMR for Command DMA */ + .start = 99, + .end = 99, + .flags = IORESOURCE_DMA, + }, +}; + +static u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32); + +struct platform_device pxa3xx_device_nand = { + .name = "pxa3xx-nand", + .id = -1, + .dev = { + .dma_mask = &pxa3xx_nand_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(pxa3xx_resources_nand), + .resource = pxa3xx_resources_nand, +}; + +void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_nand, info); +} #endif /* CONFIG_PXA3xx */ /* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1. diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index b852eb18daa..887c738f591 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -31,4 +31,6 @@ extern struct platform_device pxa25x_device_pwm1; extern struct platform_device pxa27x_device_pwm0; extern struct platform_device pxa27x_device_pwm1; +extern struct platform_device pxa3xx_device_nand; + void __init pxa_register_device(struct platform_device *dev, void *data); diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c index a0db6fa7c32..da92e973388 100644 --- a/arch/arm/mach-pxa/pxa300.c +++ b/arch/arm/mach-pxa/pxa300.c @@ -85,6 +85,10 @@ static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = { MFP_ADDR_END, }; +static struct clk common_clks[] = { + PXA3xx_CKEN("NANDCLK", NAND, 156000000, 0, &pxa3xx_device_nand.dev), +}; + static struct clk pxa310_clks[] = { PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev), }; @@ -94,6 +98,7 @@ static int __init pxa300_init(void) if (cpu_is_pxa300() || cpu_is_pxa310()) { pxa3xx_init_mfp(); pxa3xx_mfp_init_addr(pxa300_mfp_addr_map); + clks_register(ARRAY_AND_SIZE(common_clks)); } if (cpu_is_pxa310()) { diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c index 44ef0b95db0..c557c23a1ef 100644 --- a/arch/arm/mach-pxa/pxa320.c +++ b/arch/arm/mach-pxa/pxa320.c @@ -15,11 +15,17 @@ #include #include +#include #include #include +#include #include +#include "generic.h" +#include "devices.h" +#include "clock.h" + static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { MFP_ADDR_X(GPIO0, GPIO4, 0x0124), @@ -74,11 +80,16 @@ static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { MFP_ADDR_END, }; +static struct clk pxa320_clks[] = { + PXA3xx_CKEN("NANDCLK", NAND, 104000000, 0, &pxa3xx_device_nand.dev), +}; + static int __init pxa320_init(void) { if (cpu_is_pxa320()) { pxa3xx_init_mfp(); pxa3xx_mfp_init_addr(pxa320_mfp_addr_map); + clks_register(ARRAY_AND_SIZE(pxa320_clks)); } return 0; diff --git a/include/asm-arm/arch-pxa/pxa3xx_nand.h b/include/asm-arm/arch-pxa/pxa3xx_nand.h index 81a8937486c..eb4b190b665 100644 --- a/include/asm-arm/arch-pxa/pxa3xx_nand.h +++ b/include/asm-arm/arch-pxa/pxa3xx_nand.h @@ -15,4 +15,6 @@ struct pxa3xx_nand_platform_data { struct mtd_partition *parts; unsigned int nr_parts; }; + +extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info); #endif /* __ASM_ARCH_PXA3XX_NAND_H */ -- cgit v1.2.3-70-g09d2 From a1f7fc48c143537e2bf70affee7e8932f5be9bb4 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 28 May 2008 10:44:16 +0800 Subject: [ARM] pxa: add GPIO expander (PCA9539) support for zylonite And also reserve 32 IRQs for the two GPIO expanders. Signed-off-by: Eric Miao Signed-off-by: Russell King --- arch/arm/mach-pxa/zylonite_pxa300.c | 42 +++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/irqs.h | 2 ++ 2 files changed, 44 insertions(+) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 6f7ae972b8d..75bf61f1f1c 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -16,9 +16,12 @@ #include #include #include +#include +#include #include #include +#include #include #include "generic.h" @@ -109,6 +112,10 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO12_MMC2_DAT3, GPIO13_MMC2_CLK, GPIO14_MMC2_CMD, + + /* Standard I2C */ + GPIO21_I2C_SCL, + GPIO22_I2C_SDA, }; static mfp_cfg_t pxa300_mfp_cfg[] __initdata = { @@ -192,6 +199,39 @@ static void __init zylonite_detect_lcd_panel(void) pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]); } +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static struct pca953x_platform_data gpio_exp[] = { + [0] = { + .gpio_base = 128, + }, + [1] = { + .gpio_base = 144, + }, +}; + +struct i2c_board_info zylonite_i2c_board_info[] = { + { + .type = "pca9539", + .addr = 0x74, + .platform_data = &gpio_exp[0], + .irq = IRQ_GPIO(18), + }, { + .type = "pca9539", + .addr = 0x75, + .platform_data = &gpio_exp[1], + .irq = IRQ_GPIO(19), + }, +}; + +static void __init zylonite_init_i2c(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(zylonite_i2c_board_info)); +} +#else +static inline void zylonite_init_i2c(void) {} +#endif + void __init zylonite_pxa300_init(void) { if (cpu_is_pxa300() || cpu_is_pxa310()) { @@ -207,6 +247,8 @@ void __init zylonite_pxa300_init(void) /* WM9713 IRQ */ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26); + + zylonite_init_i2c(); } if (cpu_is_pxa300()) { diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h index b6c8fe37768..d8573604846 100644 --- a/include/asm-arm/arch-pxa/irqs.h +++ b/include/asm-arm/arch-pxa/irqs.h @@ -184,6 +184,8 @@ defined(CONFIG_MACH_PCM027) || \ defined(CONFIG_MACH_MAGICIAN) #define NR_IRQS (IRQ_BOARD_END) +#elif defined(CONFIG_MACH_ZYLONITE) +#define NR_IRQS (IRQ_BOARD_START + 32) #else #define NR_IRQS (IRQ_BOARD_START) #endif -- cgit v1.2.3-70-g09d2 From 5c9f50e90e8056fb5a8bdd479ab0591d5dad79a0 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 17 Jun 2008 19:03:54 +0800 Subject: [ARM] pxa: add simple gpio debug LEDs support for zylonite Signed-off-by: Eric Miao Signed-off-by: Russell King --- arch/arm/mach-pxa/zylonite.c | 39 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/zylonite_pxa300.c | 4 ++++ arch/arm/mach-pxa/zylonite_pxa320.c | 6 ++++++ include/asm-arm/arch-pxa/zylonite.h | 2 ++ 4 files changed, 51 insertions(+) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 13ab2985a02..4a4711d36e7 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -38,6 +38,8 @@ struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS]; int gpio_eth_irq; +int gpio_debug_led1; +int gpio_debug_led2; int wm9713_irq; @@ -64,6 +66,42 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static struct gpio_led zylonite_debug_leds[] = { + [0] = { + .name = "zylonite:yellow:1", + .default_trigger = "heartbeat", + }, + [1] = { + .name = "zylonite:yellow:2", + .default_trigger = "default-on", + }, +}; + +static struct gpio_led_platform_data zylonite_debug_leds_info = { + .leds = zylonite_debug_leds, + .num_leds = ARRAY_SIZE(zylonite_debug_leds), +}; + +static struct platform_device zylonite_device_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &zylonite_debug_leds_info, + } +}; + +static void __init zylonite_init_leds(void) +{ + zylonite_debug_leds[0].gpio = gpio_debug_led1; + zylonite_debug_leds[1].gpio = gpio_debug_led2; + + platform_device_register(&zylonite_device_leds); +} +#else +static inline void zylonite_init_leds(void) {} +#endif + #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) static struct platform_pwm_backlight_data zylonite_backlight_data = { .pwm_id = 3, @@ -395,6 +433,7 @@ static void __init zylonite_init(void) zylonite_init_mmc(); zylonite_init_keypad(); zylonite_init_nand(); + zylonite_init_leds(); } MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 75bf61f1f1c..b28d46e081d 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -264,4 +264,8 @@ void __init zylonite_pxa300_init(void) zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30); zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31); } + + /* GPIOs for Debug LEDs */ + gpio_debug_led1 = EXT_GPIO(25); + gpio_debug_led2 = EXT_GPIO(26); } diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 2b4fc34919a..2b7fba7a292 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -116,6 +116,10 @@ static mfp_cfg_t mfp_cfg[] __initdata = { GPIO27_MMC2_DAT3, GPIO28_MMC2_CLK, GPIO29_MMC2_CMD, + + /* Debug LEDs */ + GPIO1_2_GPIO | MFP_LPM_DRIVE_HIGH, + GPIO4_2_GPIO | MFP_LPM_DRIVE_HIGH, }; #define NUM_LCD_DETECT_PINS 7 @@ -189,6 +193,8 @@ void __init zylonite_pxa320_init(void) /* GPIO pin assignment */ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9); + gpio_debug_led1 = mfp_to_gpio(MFP_PIN_GPIO1_2); + gpio_debug_led2 = mfp_to_gpio(MFP_PIN_GPIO4_2); /* MMC card detect & write protect for controller 0 */ zylonite_mmc_slot[0].gpio_cd = mfp_to_gpio(MFP_PIN_GPIO1); diff --git a/include/asm-arm/arch-pxa/zylonite.h b/include/asm-arm/arch-pxa/zylonite.h index de577de8d18..0d35ca04731 100644 --- a/include/asm-arm/arch-pxa/zylonite.h +++ b/include/asm-arm/arch-pxa/zylonite.h @@ -16,6 +16,8 @@ struct platform_mmc_slot { extern struct platform_mmc_slot zylonite_mmc_slot[]; extern int gpio_eth_irq; +extern int gpio_debug_led1; +extern int gpio_debug_led2; extern int wm9713_irq; -- cgit v1.2.3-70-g09d2 From 63f385cd1f649b3f4f2d59fc609e051981215fd7 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Tue, 8 Jul 2008 23:07:48 +0100 Subject: [ARM] 5160/1: IOP3XX: gpio/gpiolib support This patch brings support for gpio/gpiolib framework to Intel IOP3xx platforms. Signed-off-by: Arnaud Patard Acked-by: Dan Williams Signed-off-by: Russell King --- arch/arm/Kconfig | 4 ++ arch/arm/plat-iop/gpio.c | 43 ++++++++++++++++++++ include/asm-arm/arch-iop32x/gpio.h | 6 +++ include/asm-arm/arch-iop33x/gpio.h | 6 +++ include/asm-arm/hardware/iop3xx-gpio.h | 73 ++++++++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 include/asm-arm/arch-iop32x/gpio.h create mode 100644 include/asm-arm/arch-iop33x/gpio.h create mode 100644 include/asm-arm/hardware/iop3xx-gpio.h (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d..63ef7cf852a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -299,6 +299,8 @@ config ARCH_IOP32X depends on MMU select PLAT_IOP select PCI + select GENERIC_GPIO + select HAVE_GPIO_LIB help Support for Intel's 80219 and IOP32X (XScale) family of processors. @@ -308,6 +310,8 @@ config ARCH_IOP33X depends on MMU select PLAT_IOP select PCI + select GENERIC_GPIO + select HAVE_GPIO_LIB help Support for Intel's IOP33X (XScale) family of processors. diff --git a/arch/arm/plat-iop/gpio.c b/arch/arm/plat-iop/gpio.c index eda43608341..640e498c12e 100644 --- a/arch/arm/plat-iop/gpio.c +++ b/arch/arm/plat-iop/gpio.c @@ -11,6 +11,10 @@ */ #include +#include +#include +#include +#include #include void gpio_line_config(int line, int direction) @@ -46,3 +50,42 @@ void gpio_line_set(int line, int value) local_irq_restore(flags); } EXPORT_SYMBOL(gpio_line_set); + +static int iop3xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + gpio_line_config(gpio, GPIO_IN); + return 0; +} + +static int iop3xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level) +{ + gpio_line_set(gpio, level); + gpio_line_config(gpio, GPIO_OUT); + return 0; +} + +static int iop3xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + return gpio_line_get(gpio); +} + +static void iop3xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) +{ + gpio_line_set(gpio, value); +} + +static struct gpio_chip iop3xx_chip = { + .label = "iop3xx", + .direction_input = iop3xx_gpio_direction_input, + .get = iop3xx_gpio_get_value, + .direction_output = iop3xx_gpio_direction_output, + .set = iop3xx_gpio_set_value, + .base = 0, + .ngpio = IOP3XX_N_GPIOS, +}; + +static int __init iop3xx_gpio_setup(void) +{ + return gpiochip_add(&iop3xx_chip); +} +arch_initcall(iop3xx_gpio_setup); diff --git a/include/asm-arm/arch-iop32x/gpio.h b/include/asm-arm/arch-iop32x/gpio.h new file mode 100644 index 00000000000..708f4ec9db1 --- /dev/null +++ b/include/asm-arm/arch-iop32x/gpio.h @@ -0,0 +1,6 @@ +#ifndef __ASM_ARCH_IOP32X_GPIO_H +#define __ASM_ARCH_IOP32X_GPIO_H + +#include + +#endif diff --git a/include/asm-arm/arch-iop33x/gpio.h b/include/asm-arm/arch-iop33x/gpio.h new file mode 100644 index 00000000000..ddd55bba9bb --- /dev/null +++ b/include/asm-arm/arch-iop33x/gpio.h @@ -0,0 +1,6 @@ +#ifndef __ASM_ARCH_IOP33X_GPIO_H +#define __ASM_ARCH_IOP33X_GPIO_H + +#include + +#endif diff --git a/include/asm-arm/hardware/iop3xx-gpio.h b/include/asm-arm/hardware/iop3xx-gpio.h new file mode 100644 index 00000000000..0c9331f9ac2 --- /dev/null +++ b/include/asm-arm/hardware/iop3xx-gpio.h @@ -0,0 +1,73 @@ +/* + * linux/include/asm-arm/hardware/iop3xx-gpio.h + * + * IOP3xx GPIO wrappers + * + * Copyright (c) 2008 Arnaud Patard + * Based on IXP4XX gpio.h file + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_HARDWARE_IOP3XX_GPIO_H +#define __ASM_ARM_HARDWARE_IOP3XX_GPIO_H + +#include +#include + +#define IOP3XX_N_GPIOS 8 + +static inline int gpio_get_value(unsigned gpio) +{ + if (gpio > IOP3XX_N_GPIOS) + return __gpio_get_value(gpio); + + return gpio_line_get(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + if (gpio > IOP3XX_N_GPIOS) { + __gpio_set_value(gpio, value); + return; + } + gpio_line_set(gpio, value); +} + +static inline int gpio_cansleep(unsigned gpio) +{ + if (gpio < IOP3XX_N_GPIOS) + return 0; + else + return __gpio_cansleep(gpio); +} + +/* + * The GPIOs are not generating any interrupt + * Note : manuals are not clear about this + */ +static inline int gpio_to_irq(int gpio) +{ + return -EINVAL; +} + +static inline int irq_to_gpio(int gpio) +{ + return -EINVAL; +} + +#endif + -- cgit v1.2.3-70-g09d2 From aa9ae8eb1a917c8794bceef0a8e6ff1f4d7c46de Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Wed, 25 Jun 2008 22:17:16 +0100 Subject: Fix serial broken-ness on PXA250 PXA255 and 26x are the only PXA CPUs with HWUART. This patch prevents bogus initialisation on other models. Signed-off-by: Ian Molton --- arch/arm/mach-pxa/pxa25x.c | 4 ++-- include/asm-arm/arch-pxa/hardware.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 4cd50e3005e..90b441f5df5 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -293,7 +293,7 @@ static int __init pxa25x_init(void) int i, ret = 0; /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ - if (cpu_is_pxa25x()) + if (cpu_is_pxa255()) clks_register(&pxa25x_hwuart_clk, 1); if (cpu_is_pxa21x() || cpu_is_pxa25x()) { @@ -317,7 +317,7 @@ static int __init pxa25x_init(void) } /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ - if (cpu_is_pxa25x()) + if (cpu_is_pxa255()) ret = platform_device_register(&pxa_device_hwuart); clks_register(&gpio7_clk, 1); diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index d9af6dabc89..b6a8317c2ec 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -69,6 +69,12 @@ _id == 0x212; \ }) +#define __cpu_is_pxa255(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x2d0; \ + }) + #define __cpu_is_pxa25x(id) \ ({ \ unsigned int _id = (id) >> 4 & 0xfff; \ @@ -76,6 +82,7 @@ }) #else #define __cpu_is_pxa21x(id) (0) +#define __cpu_is_pxa255(id) (0) #define __cpu_is_pxa25x(id) (0) #endif @@ -124,6 +131,11 @@ __cpu_is_pxa21x(read_cpuid_id()); \ }) +#define cpu_is_pxa255() \ + ({ \ + __cpu_is_pxa255(read_cpuid_id()); \ + }) + #define cpu_is_pxa25x() \ ({ \ __cpu_is_pxa25x(read_cpuid_id()); \ -- cgit v1.2.3-70-g09d2 From 613526677a74c2b3d1b1696ea7334b2cf35155b3 Mon Sep 17 00:00:00 2001 From: sedji gaouaou Date: Thu, 10 Jul 2008 10:15:35 +0100 Subject: [ARM] 5130/4: Support for the at91sam9g20 Support for the at91sam9g20 : Atmel 400Mhz ARM 926ej-s SOC. AT91sam9g20 is an evolution of the at91sam9260 with a faster clock speed. We created a new board for this device but based the chip support directly on 9260 files with little updates. Here is the chip page on Atmel wabsite: http://atmel.com/dyn/products/product_card.asp?part_id=4337 Signed-off-by: Sedji Gaouaou Signed-off-by: Justin Waters Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/Kconfig | 29 +++- arch/arm/mach-at91/Makefile | 4 + arch/arm/mach-at91/at91sam9260.c | 16 +++ arch/arm/mach-at91/at91sam9260_devices.c | 44 +++++-- arch/arm/mach-at91/board-sam9g20ek.c | 218 +++++++++++++++++++++++++++++++ arch/arm/mach-at91/clock.c | 19 ++- arch/arm/mach-at91/pm.c | 2 +- arch/arm/mm/Kconfig | 4 +- drivers/net/Kconfig | 2 +- drivers/usb/gadget/at91_udc.c | 4 +- include/asm-arm/arch-at91/at91sam9260.h | 11 ++ include/asm-arm/arch-at91/board.h | 2 +- include/asm-arm/arch-at91/cpu.h | 7 + include/asm-arm/arch-at91/hardware.h | 2 +- include/asm-arm/arch-at91/timex.h | 5 + sound/soc/at91/at91-ssc.c | 2 +- 16 files changed, 342 insertions(+), 29 deletions(-) create mode 100644 arch/arm/mach-at91/board-sam9g20ek.c (limited to 'include/asm-arm') diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index cae5c67dc31..5bad6b9b00d 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -30,6 +30,11 @@ config ARCH_AT91SAM9RL select GENERIC_TIME select GENERIC_CLOCKEVENTS +config ARCH_AT91SAM9G20 + bool "AT91SAM9G20" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + config ARCH_AT91CAP9 bool "AT91CAP9" select GENERIC_TIME @@ -239,6 +244,20 @@ endif # ---------------------------------------------------------- +if ARCH_AT91SAM9G20 + +comment "AT91SAM9G20 Board Type" + +config MACH_AT91SAM9G20EK + bool "Atmel AT91SAM9G20-EK Evaluation Kit" + depends on ARCH_AT91SAM9G20 + help + Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. + +endif + +# ---------------------------------------------------------- + if ARCH_AT91CAP9 comment "AT91CAP9 Board Type" @@ -274,13 +293,13 @@ comment "AT91 Board Options" config MTD_AT91_DATAFLASH_CARD bool "Enable DataFlash Card support" - depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK || MACH_SAM9_L9260 || MACH_ECBAT91) + depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK) help Enable support for the DataFlash card. config MTD_NAND_AT91_BUSWIDTH_16 bool "Enable 16-bit data bus interface to NAND flash" - depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91CAP9ADK) + depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK) help On AT91SAM926x boards both types of NAND flash can be present (8 and 16 bit data bus width). @@ -329,15 +348,15 @@ config AT91_EARLY_USART2 config AT91_EARLY_USART3 bool "USART3" - depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260) + depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20) config AT91_EARLY_USART4 bool "USART4" - depends on ARCH_AT91SAM9260 + depends on ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 config AT91_EARLY_USART5 bool "USART5" - depends on ARCH_AT91SAM9260 + depends on ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 endchoice diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 932d17109e8..7d641f97516 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o @@ -49,6 +50,9 @@ obj-$(CONFIG_MACH_USB_A9263) += board-usb-a9263.o # AT91SAM9RL board-specific support obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o +# AT91SAM9G20 board-specific support +obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o + # AT91CAP9 board-specific support obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index ee26550cdc2..380f12a1220 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -47,6 +47,20 @@ static struct map_desc at91sam9260_sram_desc[] __initdata = { } }; +static struct map_desc at91sam9g20_sram_desc[] __initdata = { + { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE, + .pfn = __phys_to_pfn(AT91SAM9G20_SRAM0_BASE), + .length = AT91SAM9G20_SRAM0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE - AT91SAM9G20_SRAM1_SIZE, + .pfn = __phys_to_pfn(AT91SAM9G20_SRAM1_BASE), + .length = AT91SAM9G20_SRAM1_SIZE, + .type = MT_DEVICE, + } +}; + static struct map_desc at91sam9xe_sram_desc[] __initdata = { { .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE), @@ -307,6 +321,8 @@ void __init at91sam9260_initialize(unsigned long main_clock) if (cpu_is_at91sam9xe()) at91sam9xe_initialize(); + else if (cpu_is_at91sam9g20()) + iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc)); else iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 26f5cacbec3..86cba4ac29b 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -320,20 +321,41 @@ void __init at91_add_device_nand(struct at91_nand_data *data) csa = at91_sys_read(AT91_MATRIX_EBICSA); at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); - /* set the bus interface characteristics */ - at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) - | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); + if (cpu_is_at91sam9260()) { + /* Timing for sam9260 */ + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); - at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) - | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); + at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) + | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); - at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); + at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); - if (data->bus_width_16) - mode = AT91_SMC_DBW_16; - else - mode = AT91_SMC_DBW_8; - at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2)); + if (data->bus_width_16) + mode = AT91_SMC_DBW_16; + else + mode = AT91_SMC_DBW_8; + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2)); + } + + if (cpu_is_at91sam9g20()) { + /* Timing for sam9g20 */ + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(0)); + + at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(4) + | AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(4)); + + at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); + + if (data->bus_width_16) + mode = AT91_SMC_DBW_16; + else + mode = AT91_SMC_DBW_8; + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(3)); + } /* enable pin */ if (data->enable_pin) diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c new file mode 100644 index 00000000000..45617c20124 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2005 SAN People + * Copyright (C) 2008 Atmel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "generic.h" + + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* DGBU on ttyS0. (Rx & Tx only) */ + at91_register_uart(0, 0, 0); + + /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ + at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS + | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD + | ATMEL_UART_RI); + + /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ + at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); + + /* set serial console to ttyS0 (ie, DBGU) */ + at91_set_serial_console(0); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct at91_eth_data __initdata ek_macb_data = { + .phy_irq_pin = AT91_PIN_PA7, + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Bootstrap", + .offset = 0, + .size = 4 * 1024 * 1024, + }, + { + .name = "Partition 1", + .offset = 4 * 1024 * 1024, + .size = 60 * 1024 * 1024, + }, + { + .name = "Partition 2", + .offset = 64 * 1024 * 1024, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +/* det_pin is not connected */ +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + + +/* + * MCI (SD/MMC) + * det_pin, wp_pin and vcc_pin are not connected + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 1, + .wire4 = 1, +}; + + +/* + * LEDs + */ +static struct gpio_led ek_leds[] = { + { /* "bottom" led, green, userled1 to be defined */ + .name = "ds5", + .gpio = AT91_PIN_PA6, + .active_low = 1, + .default_trigger = "none", + }, + { /* "power" led, yellow */ + .name = "ds1", + .gpio = AT91_PIN_PA9, + .default_trigger = "heartbeat", + } +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mmc(0, &ek_mmc_data); + /* I2C */ + at91_add_device_i2c(NULL, 0); + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); +} + +MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") + /* Maintainer: Atmel */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index e8ce8f0f3ed..464bdbbf74d 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -515,14 +515,19 @@ static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) /* * PLL input between 1MHz and 32MHz per spec, but lower * frequences seem necessary in some cases so allow 100K. + * Warning: some newer products need 2MHz min. */ input = main_freq / i; + if (cpu_is_at91sam9g20() && input < 2000000) + continue; if (input < 100000) continue; if (input > 32000000) continue; mul1 = out_freq / input; + if (cpu_is_at91sam9g20() && mul > 63) + continue; if (mul1 > 2048) continue; if (mul1 < 2) @@ -582,7 +587,8 @@ int __init at91_clock_init(unsigned long main_clock) /* report if PLLA is more than mildly overclocked */ plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); - if (plla.rate_hz > 209000000) + if ((!cpu_is_at91sam9g20() && plla.rate_hz > 209000000) + || (cpu_is_at91sam9g20() && plla.rate_hz > 800000000)) pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); /* @@ -597,7 +603,7 @@ int __init at91_clock_init(unsigned long main_clock) uhpck.pmc_mask = AT91RM9200_PMC_UHP; udpck.pmc_mask = AT91RM9200_PMC_UDP; at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); - } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { uhpck.pmc_mask = AT91SAM926x_PMC_UHP; udpck.pmc_mask = AT91SAM926x_PMC_UDP; } else if (cpu_is_at91cap9()) { @@ -629,8 +635,13 @@ int __init at91_clock_init(unsigned long main_clock) freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ if (cpu_is_at91rm9200()) mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ - else - mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ + else if (cpu_is_at91sam9g20()) { + mck.rate_hz = (mckr & AT91_PMC_MDIV) ? + freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ + if (mckr & AT91_PMC_PDIV) + freq /= 2; /* processor clock division */ + } else + mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ /* Register the PMC's standard clocks */ for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index aa863c15770..8ab4feb1ec5 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -202,7 +202,7 @@ static int at91_pm_verify_clocks(void) pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; } - } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); return 0; diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 33ed048502a..750d895cd28 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -180,8 +180,8 @@ config CPU_ARM925T # ARM926T config CPU_ARM926T bool "Support ARM926T processor" - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI - default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI + depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI + default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_PABRT_NOIFAR diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9f6cc8a5607..be3b13cf417 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -217,7 +217,7 @@ config MII config MACB tristate "Atmel MACB support" - depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91CAP9 + depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 select PHYLIB help The Atmel MACB ethernet interface is found on many AT32 and AT91 diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 274c60a970c..b6b2a0a5ba3 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -888,7 +888,7 @@ static void pullup(struct at91_udc *udc, int is_on) at91_udp_write(udc, AT91_UDP_TXVC, 0); if (cpu_is_at91rm9200()) gpio_set_value(udc->board.pullup_pin, active); - else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { + else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); txvc |= AT91_UDP_TXVC_PUON; @@ -906,7 +906,7 @@ static void pullup(struct at91_udc *udc, int is_on) at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); if (cpu_is_at91rm9200()) gpio_set_value(udc->board.pullup_pin, !active); - else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) { + else if (cpu_is_at91sam9260() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); txvc &= ~AT91_UDP_TXVC_PUON; diff --git a/include/asm-arm/arch-at91/at91sam9260.h b/include/asm-arm/arch-at91/at91sam9260.h index c8934fe34dc..889872a3f2a 100644 --- a/include/asm-arm/arch-at91/at91sam9260.h +++ b/include/asm-arm/arch-at91/at91sam9260.h @@ -6,6 +6,8 @@ * Common definitions. * Based on AT91SAM9260 datasheet revision A (Preliminary). * + * Includes also definitions for AT91SAM9XE and AT91SAM9G families + * * 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 @@ -123,5 +125,14 @@ #define AT91SAM9XE_FLASH_BASE 0x00200000 /* Internal FLASH base address */ #define AT91SAM9XE_SRAM_BASE 0x00300000 /* Internal SRAM base address */ +#define AT91SAM9G20_ROM_BASE 0x00100000 /* Internal ROM base address */ +#define AT91SAM9G20_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ + +#define AT91SAM9G20_SRAM0_BASE 0x00200000 /* Internal SRAM 0 base address */ +#define AT91SAM9G20_SRAM0_SIZE SZ_16K /* Internal SRAM 0 size (16Kb) */ +#define AT91SAM9G20_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */ +#define AT91SAM9G20_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */ + +#define AT91SAM9G20_UHP_BASE 0x00500000 /* USB Host controller */ #endif diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h index 1f247028686..94de788da76 100644 --- a/include/asm-arm/arch-at91/board.h +++ b/include/asm-arm/arch-at91/board.h @@ -77,7 +77,7 @@ struct at91_eth_data { }; extern void __init at91_add_device_eth(struct at91_eth_data *data); -#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) +#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) #define eth_platform_data at91_eth_data #endif diff --git a/include/asm-arm/arch-at91/cpu.h b/include/asm-arm/arch-at91/cpu.h index 7145166826a..52df794205c 100644 --- a/include/asm-arm/arch-at91/cpu.h +++ b/include/asm-arm/arch-at91/cpu.h @@ -21,6 +21,7 @@ #define ARCH_ID_AT91SAM9260 0x019803a0 #define ARCH_ID_AT91SAM9261 0x019703a0 #define ARCH_ID_AT91SAM9263 0x019607a0 +#define ARCH_ID_AT91SAM9G20 0x019905a0 #define ARCH_ID_AT91SAM9RL64 0x019b03a0 #define ARCH_ID_AT91CAP9 0x039A03A0 @@ -63,6 +64,12 @@ static inline unsigned long at91_arch_identify(void) #define cpu_is_at91sam9260() (0) #endif +#ifdef CONFIG_ARCH_AT91SAM9G20 +#define cpu_is_at91sam9g20() (at91_cpu_identify() == ARCH_ID_AT91SAM9G20) +#else +#define cpu_is_at91sam9g20() (0) +#endif + #ifdef CONFIG_ARCH_AT91SAM9261 #define cpu_is_at91sam9261() (at91_cpu_identify() == ARCH_ID_AT91SAM9261) #else diff --git a/include/asm-arm/arch-at91/hardware.h b/include/asm-arm/arch-at91/hardware.h index 2c826d8247a..016a3a3f663 100644 --- a/include/asm-arm/arch-at91/hardware.h +++ b/include/asm-arm/arch-at91/hardware.h @@ -18,7 +18,7 @@ #if defined(CONFIG_ARCH_AT91RM9200) #include -#elif defined(CONFIG_ARCH_AT91SAM9260) +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) #include #elif defined(CONFIG_ARCH_AT91SAM9261) #include diff --git a/include/asm-arm/arch-at91/timex.h b/include/asm-arm/arch-at91/timex.h index 6e084eb839d..298d8313cda 100644 --- a/include/asm-arm/arch-at91/timex.h +++ b/include/asm-arm/arch-at91/timex.h @@ -57,6 +57,11 @@ #define AT91SAM9_MASTER_CLOCK 100000000 #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) +#elif defined(CONFIG_ARCH_AT91SAM9G20) + +#define AT91SAM9_MASTER_CLOCK 132096000 +#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) + #elif defined(CONFIG_ARCH_AT91CAP9) #define AT91CAP9_MASTER_CLOCK 100000000 diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c index bc35d00a38f..1a426095014 100644 --- a/sound/soc/at91/at91-ssc.c +++ b/sound/soc/at91/at91-ssc.c @@ -41,7 +41,7 @@ #define DBG(x...) #endif -#if defined(CONFIG_ARCH_AT91SAM9260) +#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) #define NUM_SSC_DEVICES 1 #else #define NUM_SSC_DEVICES 3 -- cgit v1.2.3-70-g09d2 From b5e4ad57eeffef0ac274413f83be4ef903719ea4 Mon Sep 17 00:00:00 2001 From: Marek Vašut Date: Mon, 7 Jul 2008 17:25:46 +0100 Subject: [ARM] 5153/1: Add support for PalmTX handheld computer PalmTX is PXA27x based device with wifi, bluetooth, touchscreen, sdio slot, irda, keypad, nand flash, pxa framebuffer, serial and usb gadget interface. Supported by this patch is pxafb, touchscreen, irda, keypad and sdio slot. Signed-off-by: Marek Vasut Signed-off-by: Russell King --- MAINTAINERS | 6 + arch/arm/mach-pxa/Kconfig | 14 ++ arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/palmtx.c | 342 ++++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/palmtx.h | 106 ++++++++++++ 5 files changed, 469 insertions(+) create mode 100644 arch/arm/mach-pxa/palmtx.c create mode 100644 include/asm-arm/arch-pxa/palmtx.h (limited to 'include/asm-arm') diff --git a/MAINTAINERS b/MAINTAINERS index 8f0ec46a709..5375740cac6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -571,6 +571,12 @@ P: Dirk Opfer M: dirk@opfer-online.de S: Maintained +ARM/PALMTX SUPPORT +P: Marek Vasut +M: marek.vasut@gmail.com +W: http://hackndev.com +S: Maintained + ARM/PLEB SUPPORT P: Peter Chubb M: pleb@gelato.unsw.edu.au diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index faa2c3f6c1a..2793076bd33 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -199,6 +199,20 @@ config MACH_PCM027 select IWMMXT select PXA_SSP +config ARCH_PXA_PALM + bool "PXA based Palm PDAs" + select HAVE_PWM + +config MACH_PALMTX + bool "Palm T|X" + default y + depends on ARCH_PXA_PALM + select PXA27x + select IWMMXT + help + Say Y here if you intend to run this kernel on a Palm T|X + handheld computer. + config MACH_PCM990_BASEBOARD bool "PHYTEC PCM-990 development board" select HAVE_PWM diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c4dfbe87fc4..d7dc3a76e33 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_MACH_TOSA) += tosa.o obj-$(CONFIG_MACH_EM_X270) += em-x270.o obj-$(CONFIG_MACH_MAGICIAN) += magician.o obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o +obj-$(CONFIG_MACH_PALMTX)+= palmtx.o ifeq ($(CONFIG_MACH_ZYLONITE),y) obj-y += zylonite.o diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c new file mode 100644 index 00000000000..ae8973279c2 --- /dev/null +++ b/arch/arm/mach-pxa/palmtx.c @@ -0,0 +1,342 @@ +/* + * Hardware definitions for PalmTX + * + * Author: Marek Vasut + * + * Based on work of: + * Alex Osborne + * Cristiano P. + * Jan Herman <2hp@seznam.cz> + * Michal Hrusecky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * (find more info at www.hackndev.com) + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "generic.h" +#include "devices.h" + +/****************************************************************************** + * Pin configuration + ******************************************************************************/ +static unsigned long palmtx_pin_config[] __initdata = { + /* MMC */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + + /* AC97 */ + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + + /* IrDA */ + GPIO46_FICP_RXD, + GPIO47_FICP_TXD, + + /* PWM */ + GPIO16_PWM0_OUT, + + /* USB */ + GPIO13_GPIO, +}; + +/****************************************************************************** + * SD/MMC card controller + ******************************************************************************/ +static int palmtx_mci_init(struct device *dev, irq_handler_t palmtx_detect_int, + void *data) +{ + int err = 0; + + /* Setup an interrupt for detecting card insert/remove events */ + err = request_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, palmtx_detect_int, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM | + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "SD/MMC card detect", data); + if (err) { + printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n", + __func__); + return err; + } + + err = gpio_request(GPIO_NR_PALMTX_SD_POWER, "SD_POWER"); + if (err) + goto pwr_err; + + err = gpio_request(GPIO_NR_PALMTX_SD_READONLY, "SD_READONLY"); + if (err) + goto ro_err; + + printk(KERN_DEBUG "%s: irq registered\n", __func__); + + return 0; + +ro_err: + gpio_free(GPIO_NR_PALMTX_SD_POWER); +pwr_err: + free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data); + return err; +} + +static void palmtx_mci_exit(struct device *dev, void *data) +{ + gpio_free(GPIO_NR_PALMTX_SD_READONLY); + gpio_free(GPIO_NR_PALMTX_SD_POWER); + free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data); +} + +static void palmtx_mci_power(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data *p_d = dev->platform_data; + gpio_set_value(GPIO_NR_PALMTX_SD_POWER, p_d->ocr_mask & (1 << vdd)); +} + +static int palmtx_mci_get_ro(struct device *dev) +{ + return gpio_get_value(GPIO_NR_PALMTX_SD_READONLY); +} + +static struct pxamci_platform_data palmtx_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .setpower = palmtx_mci_power, + .get_ro = palmtx_mci_get_ro, + .init = palmtx_mci_init, + .exit = palmtx_mci_exit, +}; + +/****************************************************************************** + * GPIO keyboard + ******************************************************************************/ +static unsigned int palmtx_matrix_keys[] = { + KEY(0, 0, KEY_POWER), + KEY(0, 1, KEY_F1), + KEY(0, 2, KEY_ENTER), + + KEY(1, 0, KEY_F2), + KEY(1, 1, KEY_F3), + KEY(1, 2, KEY_F4), + + KEY(2, 0, KEY_UP), + KEY(2, 2, KEY_DOWN), + + KEY(3, 0, KEY_RIGHT), + KEY(3, 2, KEY_LEFT), + +}; + +static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = { + .matrix_key_rows = 4, + .matrix_key_cols = 3, + .matrix_key_map = palmtx_matrix_keys, + .matrix_key_map_size = ARRAY_SIZE(palmtx_matrix_keys), + + .debounce_interval = 30, +}; + +/****************************************************************************** + * GPIO keys + ******************************************************************************/ +static struct gpio_keys_button palmtx_pxa_buttons[] = { + {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" }, +}; + +static struct gpio_keys_platform_data palmtx_pxa_keys_data = { + .buttons = palmtx_pxa_buttons, + .nbuttons = ARRAY_SIZE(palmtx_pxa_buttons), +}; + +static struct platform_device palmtx_pxa_keys = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &palmtx_pxa_keys_data, + }, +}; + +/****************************************************************************** + * Backlight + ******************************************************************************/ +static int palmtx_backlight_init(struct device *dev) +{ + int ret; + + ret = gpio_request(GPIO_NR_PALMTX_BL_POWER, "BL POWER"); + if (ret) + goto err; + ret = gpio_request(GPIO_NR_PALMTX_LCD_POWER, "LCD POWER"); + if (ret) + goto err2; + + return 0; +err2: + gpio_free(GPIO_NR_PALMTX_BL_POWER); +err: + return ret; +} + +static int palmtx_backlight_notify(int brightness) +{ + gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness); + gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness); + return brightness; +} + +static void palmtx_backlight_exit(struct device *dev) +{ + gpio_free(GPIO_NR_PALMTX_BL_POWER); + gpio_free(GPIO_NR_PALMTX_LCD_POWER); +} + +static struct platform_pwm_backlight_data palmtx_backlight_data = { + .pwm_id = 0, + .max_brightness = PALMTX_MAX_INTENSITY, + .dft_brightness = PALMTX_MAX_INTENSITY, + .pwm_period_ns = PALMTX_PERIOD_NS, + .init = palmtx_backlight_init, + .notify = palmtx_backlight_notify, + .exit = palmtx_backlight_exit, +}; + +static struct platform_device palmtx_backlight = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &palmtx_backlight_data, + }, +}; + +/****************************************************************************** + * IrDA + ******************************************************************************/ +static void palmtx_irda_transceiver_mode(struct device *dev, int mode) +{ + gpio_set_value(GPIO_NR_PALMTX_IR_DISABLE, mode & IR_OFF); + pxa2xx_transceiver_mode(dev, mode); +} + +static struct pxaficp_platform_data palmtx_ficp_platform_data = { + .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, + .transceiver_mode = palmtx_irda_transceiver_mode, +}; + +/****************************************************************************** + * UDC + ******************************************************************************/ +static void palmtx_udc_command(int cmd) +{ + gpio_set_value(GPIO_NR_PALMTX_USB_POWER, !cmd); + udelay(50); + gpio_set_value(GPIO_NR_PALMTX_USB_PULLUP, !cmd); +} + +static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = { + .gpio_vbus = GPIO_NR_PALMTX_USB_DETECT_N, + .gpio_vbus_inverted = 1, + .udc_command = palmtx_udc_command, +}; + +/****************************************************************************** + * Framebuffer + ******************************************************************************/ +static struct pxafb_mode_info palmtx_lcd_modes[] = { +{ + .pixclock = 57692, + .xres = 320, + .yres = 480, + .bpp = 16, + + .left_margin = 32, + .right_margin = 1, + .upper_margin = 7, + .lower_margin = 1, + + .hsync_len = 4, + .vsync_len = 1, +}, +}; + +static struct pxafb_mach_info palmtx_lcd_screen = { + .modes = palmtx_lcd_modes, + .num_modes = ARRAY_SIZE(palmtx_lcd_modes), + .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, +}; + +/****************************************************************************** + * Machine init + ******************************************************************************/ +static struct platform_device *devices[] __initdata = { +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + &palmtx_pxa_keys, +#endif + &palmtx_backlight, +}; + +static struct map_desc palmtx_io_desc[] __initdata = { +{ + .virtual = PALMTX_PCMCIA_VIRT, + .pfn = __phys_to_pfn(PALMTX_PCMCIA_PHYS), + .length = PALMTX_PCMCIA_SIZE, + .type = MT_DEVICE +}, +}; + +static void __init palmtx_map_io(void) +{ + pxa_map_io(); + iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc)); +} + +static void __init palmtx_init(void) +{ + pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config)); + + set_pxa_fb_info(&palmtx_lcd_screen); + pxa_set_mci_info(&palmtx_mci_platform_data); + pxa_set_udc_info(&palmtx_udc_info); + pxa_set_ac97_info(NULL); + pxa_set_ficp_info(&palmtx_ficp_platform_data); + pxa_set_keypad_info(&palmtx_keypad_platform_data); + + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +MACHINE_START(PALMTX, "Palm T|X") + .phys_io = PALMTX_PHYS_IO_START, + .io_pg_offst = io_p2v(0x40000000), + .boot_params = 0xa0000100, + .map_io = palmtx_map_io, + .init_irq = pxa27x_init_irq, + .timer = &pxa_timer, + .init_machine = palmtx_init +MACHINE_END diff --git a/include/asm-arm/arch-pxa/palmtx.h b/include/asm-arm/arch-pxa/palmtx.h new file mode 100644 index 00000000000..1e8bccbda51 --- /dev/null +++ b/include/asm-arm/arch-pxa/palmtx.h @@ -0,0 +1,106 @@ +/* + * GPIOs and interrupts for Palm T|X Handheld Computer + * + * Based on palmld-gpio.h by Alex Osborne + * + * Authors: Marek Vasut + * Cristiano P. + * Jan Herman <2hp@seznam.cz> + * + * 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 _INCLUDE_PALMTX_H_ +#define _INCLUDE_PALMTX_H_ + +/** HERE ARE GPIOs **/ + +/* GPIOs */ +#define GPIO_NR_PALMTX_GPIO_RESET 1 + +#define GPIO_NR_PALMTX_POWER_DETECT 12 /* 90 */ +#define GPIO_NR_PALMTX_HOTSYNC_BUTTON_N 10 +#define GPIO_NR_PALMTX_EARPHONE_DETECT 107 + +/* SD/MMC */ +#define GPIO_NR_PALMTX_SD_DETECT_N 14 +#define GPIO_NR_PALMTX_SD_POWER 114 /* probably */ +#define GPIO_NR_PALMTX_SD_READONLY 115 /* probably */ + +/* TOUCHSCREEN */ +#define GPIO_NR_PALMTX_WM9712_IRQ 27 + +/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */ +#define GPIO_NR_PALMTX_IR_DISABLE 40 + +/* USB */ +#define GPIO_NR_PALMTX_USB_DETECT_N 13 +#define GPIO_NR_PALMTX_USB_POWER 95 +#define GPIO_NR_PALMTX_USB_PULLUP 93 + +/* LCD/BACKLIGHT */ +#define GPIO_NR_PALMTX_BL_POWER 84 +#define GPIO_NR_PALMTX_LCD_POWER 96 + +/* LCD BORDER */ +#define GPIO_NR_PALMTX_BORDER_SWITCH 98 +#define GPIO_NR_PALMTX_BORDER_SELECT 22 + +/* BLUETOOTH */ +#define GPIO_NR_PALMTX_BT_POWER 17 +#define GPIO_NR_PALMTX_BT_RESET 83 + +/* PCMCIA (WiFi) */ +#define GPIO_NR_PALMTX_PCMCIA_POWER1 94 +#define GPIO_NR_PALMTX_PCMCIA_POWER2 108 +#define GPIO_NR_PALMTX_PCMCIA_RESET 79 +#define GPIO_NR_PALMTX_PCMCIA_READY 116 + +/* NAND Flash ... this GPIO may be incorrect! */ +#define GPIO_NR_PALMTX_NAND_BUFFER_DIR 79 + +/* INTERRUPTS */ +#define IRQ_GPIO_PALMTX_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMTX_SD_DETECT_N) +#define IRQ_GPIO_PALMTX_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMTX_WM9712_IRQ) +#define IRQ_GPIO_PALMTX_USB_DETECT IRQ_GPIO(GPIO_NR_PALMTX_USB_DETECT) +#define IRQ_GPIO_PALMTX_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMTX_GPIO_RESET) + +/** HERE ARE INIT VALUES **/ + +/* Various addresses */ +#define PALMTX_PCMCIA_PHYS 0x28000000 +#define PALMTX_PCMCIA_VIRT 0xf0000000 +#define PALMTX_PCMCIA_SIZE 0x100000 + +#define PALMTX_PHYS_RAM_START 0xa0000000 +#define PALMTX_PHYS_IO_START 0x40000000 + +#define PALMTX_PHYS_FLASH_START PXA_CS0_PHYS /* ChipSelect 0 */ +#define PALMTX_PHYS_NAND_START PXA_CS1_PHYS /* ChipSelect 1 */ + +/* TOUCHSCREEN */ +#define AC97_LINK_FRAME 21 + + +/* BATTERY */ +#define PALMTX_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */ +#define PALMTX_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */ +#define PALMTX_BAT_MAX_CURRENT 0 /* unknokn */ +#define PALMTX_BAT_MIN_CURRENT 0 /* unknown */ +#define PALMTX_BAT_MAX_CHARGE 1 /* unknown */ +#define PALMTX_BAT_MIN_CHARGE 1 /* unknown */ +#define PALMTX_MAX_LIFE_MINS 360 /* on-life in minutes */ + +#define PALMTX_BAT_MEASURE_DELAY (HZ * 1) + +/* BACKLIGHT */ +#define PALMTX_MAX_INTENSITY 0xFE +#define PALMTX_DEFAULT_INTENSITY 0x7E +#define PALMTX_LIMIT_MASK 0x7F +#define PALMTX_PRESCALER 0x3F +#define PALMTX_PERIOD_NS 3500 + +#endif -- cgit v1.2.3-70-g09d2 From 00249adc0ebf9bc5e1b7b53dee37601fd7291396 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 9 Jul 2008 08:05:42 +0100 Subject: [ARM] 5165/1: pxafb: More LCCR3 depth defines Add missing depth definitions to LCCR3. Signed-off-by: Daniel Ribeiro Acked-by: Eric Miao Signed-off-by: Russell King --- include/asm-arm/arch-pxa/regs-lcd.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/regs-lcd.h b/include/asm-arm/arch-pxa/regs-lcd.h index f762493f514..999b2a02ce2 100644 --- a/include/asm-arm/arch-pxa/regs-lcd.h +++ b/include/asm-arm/arch-pxa/regs-lcd.h @@ -24,6 +24,12 @@ #define LCCR3_4BPP (2 << 24) #define LCCR3_8BPP (3 << 24) #define LCCR3_16BPP (4 << 24) +#define LCCR3_18BPP (5 << 24) +#define LCCR3_18BPP_P (6 << 24) +#define LCCR3_19BPP (7 << 24) +#define LCCR3_19BPP_P (1 << 29) +#define LCCR3_24BPP ((1 << 29) | (1 << 24)) +#define LCCR3_25BPP ((1 << 29) | (2 << 24)) #define LCCR3_PDFOR_0 (0 << 30) #define LCCR3_PDFOR_1 (1 << 30) -- cgit v1.2.3-70-g09d2 From c1450f156fda8921a55e3f4fe596274278010f31 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 9 Jul 2008 08:06:32 +0100 Subject: [ARM] 5164/1: pxafb: Support for RGB666, RGBT666, RGB888 and RGBT888 Add the .depth field to pxafb_mode_info and use it to set pixel data format as 18(RGB666), 19(RGBT666), 24(RGB888) or 25(RGBT888) Signed-off-by: Daniel Ribeiro Acked-by: Eric Miao Signed-off-by: Russell King --- drivers/video/pxafb.c | 64 ++++++++++++++++++++++++++++++++++++++-- include/asm-arm/arch-pxa/pxafb.h | 3 +- 2 files changed, 63 insertions(+), 4 deletions(-) (limited to 'include/asm-arm') diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3682bbd7e50..295ff4e1955 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -227,6 +227,22 @@ static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var) case 4: ret = LCCR3_4BPP; break; case 8: ret = LCCR3_8BPP; break; case 16: ret = LCCR3_16BPP; break; + case 24: + switch (var->red.length + var->green.length + + var->blue.length + var->transp.length) { + case 18: ret = LCCR3_18BPP_P | LCCR3_PDFOR_3; break; + case 19: ret = LCCR3_19BPP_P; break; + } + break; + case 32: + switch (var->red.length + var->green.length + + var->blue.length + var->transp.length) { + case 18: ret = LCCR3_18BPP | LCCR3_PDFOR_3; break; + case 19: ret = LCCR3_19BPP; break; + case 24: ret = LCCR3_24BPP | LCCR3_PDFOR_3; break; + case 25: ret = LCCR3_25BPP; break; + } + break; } return ret; } @@ -345,6 +361,41 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->green.offset = 5; var->green.length = 6; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = var->transp.length = 0; + } else if (var->bits_per_pixel > 16) { + struct pxafb_mode_info *mode; + + mode = pxafb_getmode(inf, var); + if (!mode) + return -EINVAL; + + switch (mode->depth) { + case 18: /* RGB666 */ + var->transp.offset = var->transp.length = 0; + var->red.offset = 12; var->red.length = 6; + var->green.offset = 6; var->green.length = 6; + var->blue.offset = 0; var->blue.length = 6; + break; + case 19: /* RGBT666 */ + var->transp.offset = 18; var->transp.length = 1; + var->red.offset = 12; var->red.length = 6; + var->green.offset = 6; var->green.length = 6; + var->blue.offset = 0; var->blue.length = 6; + break; + case 24: /* RGB888 */ + var->transp.offset = var->transp.length = 0; + var->red.offset = 16; var->red.length = 8; + var->green.offset = 8; var->green.length = 8; + var->blue.offset = 0; var->blue.length = 8; + break; + case 25: /* RGBT888 */ + var->transp.offset = 24; var->transp.length = 1; + var->red.offset = 16; var->red.length = 8; + var->green.offset = 8; var->green.length = 8; + var->blue.offset = 0; var->blue.length = 8; + break; + default: + return -EINVAL; + } } else { var->red.offset = var->green.offset = 0; var->blue.offset = var->transp.offset = 0; @@ -376,7 +427,7 @@ static int pxafb_set_par(struct fb_info *info) struct pxafb_info *fbi = (struct pxafb_info *)info; struct fb_var_screeninfo *var = &info->var; - if (var->bits_per_pixel == 16) + if (var->bits_per_pixel >= 16) fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR; else if (!fbi->cmap_static) fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR; @@ -391,7 +442,7 @@ static int pxafb_set_par(struct fb_info *info) fbi->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; - if (var->bits_per_pixel == 16) + if (var->bits_per_pixel >= 16) fbi->palette_size = 0; else fbi->palette_size = var->bits_per_pixel == 1 ? @@ -404,7 +455,7 @@ static int pxafb_set_par(struct fb_info *info) */ pxafb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR); - if (fbi->fb.var.bits_per_pixel == 16) + if (fbi->fb.var.bits_per_pixel >= 16) fb_dealloc_cmap(&fbi->fb.cmap); else fb_alloc_cmap(&fbi->fb.cmap, 1<fb.var.bits_per_pixel, 0); @@ -831,6 +882,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, case 4: case 8: case 16: + case 24: + case 32: break; default: printk(KERN_ERR "%s: invalid bit depth %d\n", @@ -968,6 +1021,11 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi) for (gpio = 58; ldd_bits; gpio++, ldd_bits--) pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT); + /* 18 bit interface */ + if (fbi->fb.var.bits_per_pixel > 16) { + pxa_gpio_mode(86 | GPIO_ALT_FN_2_OUT); + pxa_gpio_mode(87 | GPIO_ALT_FN_2_OUT); + } pxa_gpio_mode(GPIO74_LCD_FCLK_MD); pxa_gpio_mode(GPIO75_LCD_LCLK_MD); pxa_gpio_mode(GPIO76_LCD_PCLK_MD); diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h index bbd22396841..daf018d0c60 100644 --- a/include/asm-arm/arch-pxa/pxafb.h +++ b/include/asm-arm/arch-pxa/pxafb.h @@ -71,7 +71,8 @@ struct pxafb_mode_info { u_char bpp; u_int cmap_greyscale:1, - unused:31; + depth:8, + unused:23; /* Parallel Mode Timing */ u_char hsync_len; -- cgit v1.2.3-70-g09d2 From 390d452fa1d912b6e76744a34777d7390ab1fa1c Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 9 Jul 2008 08:07:29 +0100 Subject: [ARM] 5163/1: pxa27x_udc: Allow choosing the bits in UP2OCR_SEOS Allow choosing the bits in UP2OCR_SEOS. Signed-off-by: Daniel Ribeiro Acked-by: Eric Miao Signed-off-by: Russell King --- include/asm-arm/arch-pxa/pxa27x-udc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/pxa27x-udc.h b/include/asm-arm/arch-pxa/pxa27x-udc.h index bc1cf7d0773..ab1443f8bd8 100644 --- a/include/asm-arm/arch-pxa/pxa27x-udc.h +++ b/include/asm-arm/arch-pxa/pxa27x-udc.h @@ -97,7 +97,7 @@ #define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ #define UP2OCR_HXS (1 << 16) /* Host Port 2 Transceiver Output Select */ #define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */ -#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ +#define UP2OCR_SEOS(x) ((x & 7) << 24) /* Single-Ended Output Select */ #define UDCCSN(x) __REG2(0x40600100, (x) << 2) #define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ -- cgit v1.2.3-70-g09d2 From 54b238469bce3a1b5012b2f0ebf261cf1c53e664 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 19 Jun 2008 03:11:49 +0100 Subject: [ARM] 5113/1: PXA SSP: Additional register definitions for PXA3xx SSP Also add some white space for a little clarity. Signed-off-by: Mark Brown Acked-by: Eric Miao Signed-off-by: Russell King --- include/asm-arm/arch-pxa/regs-ssp.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/regs-ssp.h b/include/asm-arm/arch-pxa/regs-ssp.h index 0255328c3c1..3c04cde2cf1 100644 --- a/include/asm-arm/arch-pxa/regs-ssp.h +++ b/include/asm-arm/arch-pxa/regs-ssp.h @@ -20,6 +20,10 @@ #define SSTSS (0x38) /* SSP Timeslot Status */ #define SSACD (0x3C) /* SSP Audio Clock Divider */ +#if defined(CONFIG_PXA3xx) +#define SSACDD (0x40) /* SSP Audio Clock Dither Divider */ +#endif + /* Common PXA2xx bits first */ #define SSCR0_DSS (0x0000000f) /* Data Size Select (mask) */ #define SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..16] */ @@ -29,10 +33,12 @@ #define SSCR0_National (0x2 << 4) /* National Microwire */ #define SSCR0_ECS (1 << 6) /* External clock select */ #define SSCR0_SSE (1 << 7) /* Synchronous Serial Port Enable */ + #if defined(CONFIG_PXA25x) #define SSCR0_SCR (0x0000ff00) /* Serial Clock Rate (mask) */ #define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */ -#elif defined(CONFIG_PXA27x) + +#elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #define SSCR0_SCR (0x000fff00) /* Serial Clock Rate (mask) */ #define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */ #define SSCR0_EDSS (1 << 20) /* Extended data size select */ @@ -45,6 +51,10 @@ #define SSCR0_MOD (1 << 31) /* Mode (normal or network) */ #endif +#if defined(CONFIG_PXA3xx) +#define SSCR0_FPCKE (1 << 29) /* FIFO packing enable */ +#endif + #define SSCR1_RIE (1 << 0) /* Receive FIFO Interrupt Enable */ #define SSCR1_TIE (1 << 1) /* Transmit FIFO Interrupt Enable */ #define SSCR1_LBM (1 << 2) /* Loop-Back Mode */ @@ -109,5 +119,9 @@ #define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */ #define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ #define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */ +#if defined(CONFIG_PXA3xx) +#define SSACD_SCDX8 (1 << 7) /* SYSCLK division ratio select */ +#endif + #endif /* __ASM_ARCH_REGS_SSP_H */ -- cgit v1.2.3-70-g09d2 From c316f101a10f2681618ffb537ecba6084d5a137e Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Thu, 10 Jul 2008 20:01:07 +0100 Subject: E-series GPIO / IRQ definitions. --- include/asm-arm/arch-pxa/eseries-gpio.h | 50 +++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/eseries-irq.h | 27 ++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 include/asm-arm/arch-pxa/eseries-gpio.h create mode 100644 include/asm-arm/arch-pxa/eseries-irq.h (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/eseries-gpio.h b/include/asm-arm/arch-pxa/eseries-gpio.h new file mode 100644 index 00000000000..4c90b131027 --- /dev/null +++ b/include/asm-arm/arch-pxa/eseries-gpio.h @@ -0,0 +1,50 @@ +/* + * eseries-gpio.h + * + * Copyright (C) Ian Molton + * + * 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. + * + */ + +/* e-series power button */ +#define GPIO_ESERIES_POWERBTN 0 + +/* UDC GPIO definitions */ +#define GPIO_E7XX_USB_DISC 13 +#define GPIO_E7XX_USB_PULLUP 3 + +#define GPIO_E800_USB_DISC 4 +#define GPIO_E800_USB_PULLUP 84 + +/* e740 PCMCIA GPIO definitions */ +/* Note: PWR1 seems to be inverted */ +#define GPIO_E740_PCMCIA_CD0 8 +#define GPIO_E740_PCMCIA_CD1 44 +#define GPIO_E740_PCMCIA_RDY0 11 +#define GPIO_E740_PCMCIA_RDY1 6 +#define GPIO_E740_PCMCIA_RST0 27 +#define GPIO_E740_PCMCIA_RST1 24 +#define GPIO_E740_PCMCIA_PWR0 20 +#define GPIO_E740_PCMCIA_PWR1 23 + +/* e750 PCMCIA GPIO definitions */ +#define GPIO_E750_PCMCIA_CD0 8 +#define GPIO_E750_PCMCIA_RDY0 12 +#define GPIO_E750_PCMCIA_RST0 27 +#define GPIO_E750_PCMCIA_PWR0 20 + +/* e800 PCMCIA GPIO definitions */ +#define GPIO_E800_PCMCIA_RST0 69 +#define GPIO_E800_PCMCIA_RST1 72 +#define GPIO_E800_PCMCIA_PWR0 20 +#define GPIO_E800_PCMCIA_PWR1 73 + +/* e7xx IrDA power control */ +#define GPIO_E7XX_IR_ON 38 + +/* ASIC related GPIOs */ +#define GPIO_ESERIES_TMIO_IRQ 5 +#define GPIO_E800_ANGELX_IRQ 8 diff --git a/include/asm-arm/arch-pxa/eseries-irq.h b/include/asm-arm/arch-pxa/eseries-irq.h new file mode 100644 index 00000000000..f2a93d5e31d --- /dev/null +++ b/include/asm-arm/arch-pxa/eseries-irq.h @@ -0,0 +1,27 @@ +/* + * eseries-irq.h + * + * Copyright (C) Ian Molton + * + * 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. + * + */ + +#define ANGELX_IRQ_BASE (IRQ_BOARD_START+8) +#define IRQ_ANGELX(n) (ANGELX_IRQ_BASE + (n)) + +#define ANGELX_RDY0_IRQ IRQ_ANGELX(0) +#define ANGELX_ST0_IRQ IRQ_ANGELX(1) +#define ANGELX_CD0_IRQ IRQ_ANGELX(2) +#define ANGELX_RDY1_IRQ IRQ_ANGELX(3) +#define ANGELX_ST1_IRQ IRQ_ANGELX(4) +#define ANGELX_CD1_IRQ IRQ_ANGELX(5) + +#define TMIO_IRQ_BASE (IRQ_BOARD_START+0) +#define IRQ_TMIO(n) (TMIO_IRQ_BASE + (n)) + +#define TMIO_SD_IRQ IRQ_TMIO(1) +#define TMIO_USB_IRQ IRQ_TMIO(2) + -- cgit v1.2.3-70-g09d2 From 8fb105f5cc7f31ff37755945378a668f4c21590e Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Wed, 25 Jun 2008 22:34:51 +0100 Subject: PXA UDC - allow use of inverted GPIO for pullup Signed-off-by: Ian Molton --- drivers/usb/gadget/pxa25x_udc.c | 6 ++++-- include/asm-arm/mach/udc_pxa2xx.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/asm-arm') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 031dceb9302..5d50031938a 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -152,9 +152,10 @@ static int is_vbus_present(void) static void pullup_off(void) { struct pxa2xx_udc_mach_info *mach = the_controller->mach; + int off_level = mach->gpio_pullup_inverted; if (mach->gpio_pullup) - gpio_set_value(mach->gpio_pullup, 0); + gpio_set_value(mach->gpio_pullup, off_level); else if (mach->udc_command) mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); } @@ -162,9 +163,10 @@ static void pullup_off(void) static void pullup_on(void) { struct pxa2xx_udc_mach_info *mach = the_controller->mach; + int on_level = !mach->gpio_pullup_inverted; if (mach->gpio_pullup) - gpio_set_value(mach->gpio_pullup, 1); + gpio_set_value(mach->gpio_pullup, on_level); else if (mach->udc_command) mach->udc_command(PXA2XX_UDC_CMD_CONNECT); } diff --git a/include/asm-arm/mach/udc_pxa2xx.h b/include/asm-arm/mach/udc_pxa2xx.h index f9f3606986c..9e5ed7c0f27 100644 --- a/include/asm-arm/mach/udc_pxa2xx.h +++ b/include/asm-arm/mach/udc_pxa2xx.h @@ -23,6 +23,7 @@ struct pxa2xx_udc_mach_info { */ bool gpio_vbus_inverted; u16 gpio_vbus; /* high == vbus present */ + bool gpio_pullup_inverted; u16 gpio_pullup; /* high == pullup activated */ }; -- cgit v1.2.3-70-g09d2 From 5d31e43589589e63f5b96abc62372d2ef331c14a Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 11 Jul 2008 12:45:39 +0800 Subject: [ARM] pxa: add base support for PXA930 (aka Tavor-P) Signed-off-by: Eric Miao Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 3 + arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/pxa930.c | 190 +++++++++++++ include/asm-arm/arch-pxa/hardware.h | 16 ++ include/asm-arm/arch-pxa/mfp-pxa930.h | 491 ++++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/mfp.h | 8 + 6 files changed, 709 insertions(+) create mode 100644 arch/arm/mach-pxa/pxa930.c create mode 100644 include/asm-arm/arch-pxa/mfp-pxa930.h (limited to 'include/asm-arm') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 3e28521b9eb..d64b40c8e42 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -16,6 +16,9 @@ config CPU_PXA310 config CPU_PXA320 bool "PXA320 (codename Monahans-P)" +config CPU_PXA930 + bool "PXA930 (codename Tavor-P)" + endmenu endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 5220a5c3fe9..d04014e67c0 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o obj-$(CONFIG_CPU_PXA300) += pxa300.o obj-$(CONFIG_CPU_PXA320) += pxa320.o +obj-$(CONFIG_CPU_PXA930) += pxa930.o # Specific board support obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c new file mode 100644 index 00000000000..9503897d049 --- /dev/null +++ b/arch/arm/mach-pxa/pxa930.c @@ -0,0 +1,190 @@ +/* + * linux/arch/arm/mach-pxa/pxa930.c + * + * Code specific to PXA930 + * + * Copyright (C) 2007-2008 Marvell Internation Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#include +#include + +static struct pxa3xx_mfp_addr_map pxa930_mfp_addr_map[] __initdata = { + + MFP_ADDR(GPIO0, 0x02e0), + MFP_ADDR(GPIO1, 0x02dc), + MFP_ADDR(GPIO2, 0x02e8), + MFP_ADDR(GPIO3, 0x02d8), + MFP_ADDR(GPIO4, 0x02e4), + MFP_ADDR(GPIO5, 0x02ec), + MFP_ADDR(GPIO6, 0x02f8), + MFP_ADDR(GPIO7, 0x02fc), + MFP_ADDR(GPIO8, 0x0300), + MFP_ADDR(GPIO9, 0x02d4), + MFP_ADDR(GPIO10, 0x02f4), + MFP_ADDR(GPIO11, 0x02f0), + MFP_ADDR(GPIO12, 0x0304), + MFP_ADDR(GPIO13, 0x0310), + MFP_ADDR(GPIO14, 0x0308), + MFP_ADDR(GPIO15, 0x030c), + MFP_ADDR(GPIO16, 0x04e8), + MFP_ADDR(GPIO17, 0x04f4), + MFP_ADDR(GPIO18, 0x04f8), + MFP_ADDR(GPIO19, 0x04fc), + MFP_ADDR(GPIO20, 0x0518), + MFP_ADDR(GPIO21, 0x051c), + MFP_ADDR(GPIO22, 0x04ec), + MFP_ADDR(GPIO23, 0x0500), + MFP_ADDR(GPIO24, 0x04f0), + MFP_ADDR(GPIO25, 0x0504), + MFP_ADDR(GPIO26, 0x0510), + MFP_ADDR(GPIO27, 0x0514), + MFP_ADDR(GPIO28, 0x0520), + MFP_ADDR(GPIO29, 0x0600), + MFP_ADDR(GPIO30, 0x0618), + MFP_ADDR(GPIO31, 0x0610), + MFP_ADDR(GPIO32, 0x060c), + MFP_ADDR(GPIO33, 0x061c), + MFP_ADDR(GPIO34, 0x0620), + MFP_ADDR(GPIO35, 0x0628), + MFP_ADDR(GPIO36, 0x062c), + MFP_ADDR(GPIO37, 0x0630), + MFP_ADDR(GPIO38, 0x0634), + MFP_ADDR(GPIO39, 0x0638), + MFP_ADDR(GPIO40, 0x063c), + MFP_ADDR(GPIO41, 0x0614), + MFP_ADDR(GPIO42, 0x0624), + MFP_ADDR(GPIO43, 0x0608), + MFP_ADDR(GPIO44, 0x0604), + MFP_ADDR(GPIO45, 0x050c), + MFP_ADDR(GPIO46, 0x0508), + MFP_ADDR(GPIO47, 0x02bc), + MFP_ADDR(GPIO48, 0x02b4), + MFP_ADDR(GPIO49, 0x02b8), + MFP_ADDR(GPIO50, 0x02c8), + MFP_ADDR(GPIO51, 0x02c0), + MFP_ADDR(GPIO52, 0x02c4), + MFP_ADDR(GPIO53, 0x02d0), + MFP_ADDR(GPIO54, 0x02cc), + MFP_ADDR(GPIO55, 0x029c), + MFP_ADDR(GPIO56, 0x02a0), + MFP_ADDR(GPIO57, 0x0294), + MFP_ADDR(GPIO58, 0x0298), + MFP_ADDR(GPIO59, 0x02a4), + MFP_ADDR(GPIO60, 0x02a8), + MFP_ADDR(GPIO61, 0x02b0), + MFP_ADDR(GPIO62, 0x02ac), + MFP_ADDR(GPIO63, 0x0640), + MFP_ADDR(GPIO64, 0x065c), + MFP_ADDR(GPIO65, 0x0648), + MFP_ADDR(GPIO66, 0x0644), + MFP_ADDR(GPIO67, 0x0674), + MFP_ADDR(GPIO68, 0x0658), + MFP_ADDR(GPIO69, 0x0654), + MFP_ADDR(GPIO70, 0x0660), + MFP_ADDR(GPIO71, 0x0668), + MFP_ADDR(GPIO72, 0x0664), + MFP_ADDR(GPIO73, 0x0650), + MFP_ADDR(GPIO74, 0x066c), + MFP_ADDR(GPIO75, 0x064c), + MFP_ADDR(GPIO76, 0x0670), + MFP_ADDR(GPIO77, 0x0678), + MFP_ADDR(GPIO78, 0x067c), + MFP_ADDR(GPIO79, 0x0694), + MFP_ADDR(GPIO80, 0x069c), + MFP_ADDR(GPIO81, 0x06a0), + MFP_ADDR(GPIO82, 0x06a4), + MFP_ADDR(GPIO83, 0x0698), + MFP_ADDR(GPIO84, 0x06bc), + MFP_ADDR(GPIO85, 0x06b4), + MFP_ADDR(GPIO86, 0x06b0), + MFP_ADDR(GPIO87, 0x06c0), + MFP_ADDR(GPIO88, 0x06c4), + MFP_ADDR(GPIO89, 0x06ac), + MFP_ADDR(GPIO90, 0x0680), + MFP_ADDR(GPIO91, 0x0684), + MFP_ADDR(GPIO92, 0x0688), + MFP_ADDR(GPIO93, 0x0690), + MFP_ADDR(GPIO94, 0x068c), + MFP_ADDR(GPIO95, 0x06a8), + MFP_ADDR(GPIO96, 0x06b8), + MFP_ADDR(GPIO97, 0x0410), + MFP_ADDR(GPIO98, 0x0418), + MFP_ADDR(GPIO99, 0x041c), + MFP_ADDR(GPIO100, 0x0414), + MFP_ADDR(GPIO101, 0x0408), + MFP_ADDR(GPIO102, 0x0324), + MFP_ADDR(GPIO103, 0x040c), + MFP_ADDR(GPIO104, 0x0400), + MFP_ADDR(GPIO105, 0x0328), + MFP_ADDR(GPIO106, 0x0404), + + MFP_ADDR(nXCVREN, 0x0204), + MFP_ADDR(DF_CLE_nOE, 0x020c), + MFP_ADDR(DF_nADV1_ALE, 0x0218), + MFP_ADDR(DF_SCLK_E, 0x0214), + MFP_ADDR(DF_SCLK_S, 0x0210), + MFP_ADDR(nBE0, 0x021c), + MFP_ADDR(nBE1, 0x0220), + MFP_ADDR(DF_nADV2_ALE, 0x0224), + MFP_ADDR(DF_INT_RnB, 0x0228), + MFP_ADDR(DF_nCS0, 0x022c), + MFP_ADDR(DF_nCS1, 0x0230), + MFP_ADDR(nLUA, 0x0254), + MFP_ADDR(nLLA, 0x0258), + MFP_ADDR(DF_nWE, 0x0234), + MFP_ADDR(DF_nRE_nOE, 0x0238), + MFP_ADDR(DF_ADDR0, 0x024c), + MFP_ADDR(DF_ADDR1, 0x0250), + MFP_ADDR(DF_ADDR2, 0x025c), + MFP_ADDR(DF_ADDR3, 0x0260), + MFP_ADDR(DF_IO0, 0x023c), + MFP_ADDR(DF_IO1, 0x0240), + MFP_ADDR(DF_IO2, 0x0244), + MFP_ADDR(DF_IO3, 0x0248), + MFP_ADDR(DF_IO4, 0x0264), + MFP_ADDR(DF_IO5, 0x0268), + MFP_ADDR(DF_IO6, 0x026c), + MFP_ADDR(DF_IO7, 0x0270), + MFP_ADDR(DF_IO8, 0x0274), + MFP_ADDR(DF_IO9, 0x0278), + MFP_ADDR(DF_IO10, 0x027c), + MFP_ADDR(DF_IO11, 0x0280), + MFP_ADDR(DF_IO12, 0x0284), + MFP_ADDR(DF_IO13, 0x0288), + MFP_ADDR(DF_IO14, 0x028c), + MFP_ADDR(DF_IO15, 0x0290), + + MFP_ADDR(GSIM_UIO, 0x0314), + MFP_ADDR(GSIM_UCLK, 0x0318), + MFP_ADDR(GSIM_UDET, 0x031c), + MFP_ADDR(GSIM_nURST, 0x0320), + + MFP_ADDR(PMIC_INT, 0x06c8), + + MFP_ADDR(RDY, 0x0200), + + MFP_ADDR_END, +}; + +static int __init pxa930_init(void) +{ + if (cpu_is_pxa930()) { + pxa3xx_init_mfp(); + pxa3xx_mfp_init_addr(pxa930_mfp_addr_map); + } + + return 0; +} + +core_initcall(pxa930_init); diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index 09868de841a..979a45695d7 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -126,6 +126,16 @@ #define __cpu_is_pxa320(id) (0) #endif +#ifdef CONFIG_CPU_PXA930 +#define __cpu_is_pxa930(id) \ + ({ \ + unsigned int _id = (id) >> 4 & 0xfff; \ + _id == 0x683; \ + }) +#else +#define __cpu_is_pxa930(id) (0) +#endif + #define cpu_is_pxa21x() \ ({ \ __cpu_is_pxa21x(read_cpuid_id()); \ @@ -161,6 +171,12 @@ __cpu_is_pxa320(read_cpuid_id()); \ }) +#define cpu_is_pxa930() \ + ({ \ + unsigned int id = read_cpuid(CPUID_ID); \ + __cpu_is_pxa930(id); \ + }) + /* * CPUID Core Generation Bit * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x diff --git a/include/asm-arm/arch-pxa/mfp-pxa930.h b/include/asm-arm/arch-pxa/mfp-pxa930.h new file mode 100644 index 00000000000..c4e945ab192 --- /dev/null +++ b/include/asm-arm/arch-pxa/mfp-pxa930.h @@ -0,0 +1,491 @@ +/* + * linux/include/asm-arm/arch-pxa/mfp-pxa930.h + * + * PXA930 specific MFP configuration definitions + * + * Copyright (C) 2007-2008 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_MFP_PXA9xx_H +#define __ASM_ARCH_MFP_PXA9xx_H + +#include +#include + +/* GPIO */ +#define GPIO46_GPIO MFP_CFG(GPIO46, AF0) +#define GPIO49_GPIO MFP_CFG(GPIO49, AF0) +#define GPIO50_GPIO MFP_CFG(GPIO50, AF0) +#define GPIO51_GPIO MFP_CFG(GPIO51, AF0) +#define GPIO52_GPIO MFP_CFG(GPIO52, AF0) +#define GPIO56_GPIO MFP_CFG(GPIO56, AF0) +#define GPIO58_GPIO MFP_CFG(GPIO58, AF0) +#define GPIO59_GPIO MFP_CFG(GPIO59, AF0) +#define GPIO60_GPIO MFP_CFG(GPIO60, AF0) +#define GPIO61_GPIO MFP_CFG(GPIO61, AF0) +#define GPIO62_GPIO MFP_CFG(GPIO62, AF0) + +#define GSIM_UCLK_GPIO_79 MFP_CFG(GSIM_UCLK, AF0) +#define GSIM_UIO_GPIO_80 MFP_CFG(GSIM_UIO, AF0) +#define GSIM_nURST_GPIO_81 MFP_CFG(GSIM_nURST, AF0) +#define GSIM_UDET_GPIO_82 MFP_CFG(GSIM_UDET, AF0) + +#define DF_IO15_GPIO_28 MFP_CFG(DF_IO15, AF0) +#define DF_IO14_GPIO_29 MFP_CFG(DF_IO14, AF0) +#define DF_IO13_GPIO_30 MFP_CFG(DF_IO13, AF0) +#define DF_IO12_GPIO_31 MFP_CFG(DF_IO12, AF0) +#define DF_IO11_GPIO_32 MFP_CFG(DF_IO11, AF0) +#define DF_IO10_GPIO_33 MFP_CFG(DF_IO10, AF0) +#define DF_IO9_GPIO_34 MFP_CFG(DF_IO9, AF0) +#define DF_IO8_GPIO_35 MFP_CFG(DF_IO8, AF0) +#define DF_IO7_GPIO_36 MFP_CFG(DF_IO7, AF0) +#define DF_IO6_GPIO_37 MFP_CFG(DF_IO6, AF0) +#define DF_IO5_GPIO_38 MFP_CFG(DF_IO5, AF0) +#define DF_IO4_GPIO_39 MFP_CFG(DF_IO4, AF0) +#define DF_IO3_GPIO_40 MFP_CFG(DF_IO3, AF0) +#define DF_IO2_GPIO_41 MFP_CFG(DF_IO2, AF0) +#define DF_IO1_GPIO_42 MFP_CFG(DF_IO1, AF0) +#define DF_IO0_GPIO_43 MFP_CFG(DF_IO0, AF0) +#define DF_nCS0_GPIO_44 MFP_CFG(DF_nCS0, AF0) +#define DF_nCS1_GPIO_45 MFP_CFG(DF_nCS1, AF0) +#define DF_nWE_GPIO_46 MFP_CFG(DF_nWE, AF0) +#define DF_nRE_nOE_GPIO_47 MFP_CFG(DF_nRE_nOE, AF0) +#define DF_CLE_nOE_GPIO_48 MFP_CFG(DF_CLE_nOE, AF0) +#define DF_nADV1_ALE_GPIO_49 MFP_CFG(DF_nADV1_ALE, AF0) +#define DF_nADV2_ALE_GPIO_50 MFP_CFG(DF_nADV2_ALE, AF0) +#define DF_INT_RnB_GPIO_51 MFP_CFG(DF_INT_RnB, AF0) +#define DF_SCLK_E_GPIO_52 MFP_CFG(DF_SCLK_E, AF0) + +#define DF_ADDR0_GPIO_53 MFP_CFG(DF_ADDR0, AF0) +#define DF_ADDR1_GPIO_54 MFP_CFG(DF_ADDR1, AF0) +#define DF_ADDR2_GPIO_55 MFP_CFG(DF_ADDR2, AF0) +#define DF_ADDR3_GPIO_56 MFP_CFG(DF_ADDR3, AF0) +#define nXCVREN_GPIO_57 MFP_CFG(nXCVREN, AF0) +#define nLUA_GPIO_58 MFP_CFG(nLUA, AF0) +#define nLLA_GPIO_59 MFP_CFG(nLLA, AF0) +#define nBE0_GPIO_60 MFP_CFG(nBE0, AF0) +#define nBE1_GPIO_61 MFP_CFG(nBE1, AF0) +#define RDY_GPIO_62 MFP_CFG(RDY, AF0) + +/* Chip Select */ +#define DF_nCS0_nCS2 MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH) +#define DF_nCS1_nCS3 MFP_CFG_LPM(DF_nCS1, AF3, PULL_HIGH) + +/* AC97 */ +#define GPIO83_BAC97_SYSCLK MFP_CFG(GPIO83, AF3) +#define GPIO84_BAC97_SDATA_IN0 MFP_CFG(GPIO84, AF3) +#define GPIO85_BAC97_BITCLK MFP_CFG(GPIO85, AF3) +#define GPIO86_BAC97_nRESET MFP_CFG(GPIO86, AF3) +#define GPIO87_BAC97_SYNC MFP_CFG(GPIO87, AF3) +#define GPIO88_BAC97_SDATA_OUT MFP_CFG(GPIO88, AF3) + +/* I2C */ +#define GPIO39_CI2C_SCL MFP_CFG_LPM(GPIO39, AF3, PULL_HIGH) +#define GPIO40_CI2C_SDA MFP_CFG_LPM(GPIO40, AF3, PULL_HIGH) + +#define GPIO51_CI2C_SCL MFP_CFG_LPM(GPIO51, AF3, PULL_HIGH) +#define GPIO52_CI2C_SDA MFP_CFG_LPM(GPIO52, AF3, PULL_HIGH) + +#define GPIO63_CI2C_SCL MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH) +#define GPIO64_CI2C_SDA MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH) + +#define GPIO77_CI2C_SCL MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH) +#define GPIO78_CI2C_SDA MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH) + +#define GPIO89_CI2C_SCL MFP_CFG_LPM(GPIO89, AF1, PULL_HIGH) +#define GPIO90_CI2C_SDA MFP_CFG_LPM(GPIO90, AF1, PULL_HIGH) + +#define GPIO95_CI2C_SCL MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH) +#define GPIO96_CI2C_SDA MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH) + +#define GPIO97_CI2C_SCL MFP_CFG_LPM(GPIO97, AF3, PULL_HIGH) +#define GPIO98_CI2C_SDA MFP_CFG_LPM(GPIO98, AF3, PULL_HIGH) + +/* QCI */ +#define GPIO63_CI_DD_9 MFP_CFG_LPM(GPIO63, AF1, PULL_LOW) +#define GPIO64_CI_DD_8 MFP_CFG_LPM(GPIO64, AF1, PULL_LOW) +#define GPIO65_CI_DD_7 MFP_CFG_LPM(GPIO65, AF1, PULL_LOW) +#define GPIO66_CI_DD_6 MFP_CFG_LPM(GPIO66, AF1, PULL_LOW) +#define GPIO67_CI_DD_5 MFP_CFG_LPM(GPIO67, AF1, PULL_LOW) +#define GPIO68_CI_DD_4 MFP_CFG_LPM(GPIO68, AF1, PULL_LOW) +#define GPIO69_CI_DD_3 MFP_CFG_LPM(GPIO69, AF1, PULL_LOW) +#define GPIO70_CI_DD_2 MFP_CFG_LPM(GPIO70, AF1, PULL_LOW) +#define GPIO71_CI_DD_1 MFP_CFG_LPM(GPIO71, AF1, PULL_LOW) +#define GPIO72_CI_DD_0 MFP_CFG_LPM(GPIO72, AF1, PULL_LOW) +#define GPIO73_CI_HSYNC MFP_CFG_LPM(GPIO73, AF1, PULL_LOW) +#define GPIO74_CI_VSYNC MFP_CFG_LPM(GPIO74, AF1, PULL_LOW) +#define GPIO75_CI_MCLK MFP_CFG_LPM(GPIO75, AF1, PULL_LOW) +#define GPIO76_CI_PCLK MFP_CFG_LPM(GPIO76, AF1, PULL_LOW) + +/* KEYPAD */ +#define GPIO4_KP_DKIN_4 MFP_CFG_LPM(GPIO4, AF3, FLOAT) +#define GPIO5_KP_DKIN_5 MFP_CFG_LPM(GPIO5, AF3, FLOAT) +#define GPIO6_KP_DKIN_6 MFP_CFG_LPM(GPIO6, AF3, FLOAT) +#define GPIO7_KP_DKIN_7 MFP_CFG_LPM(GPIO7, AF3, FLOAT) +#define GPIO8_KP_DKIN_4 MFP_CFG_LPM(GPIO8, AF3, FLOAT) +#define GPIO9_KP_DKIN_5 MFP_CFG_LPM(GPIO9, AF3, FLOAT) +#define GPIO10_KP_DKIN_6 MFP_CFG_LPM(GPIO10, AF3, FLOAT) +#define GPIO11_KP_DKIN_7 MFP_CFG_LPM(GPIO11, AF3, FLOAT) + +#define GPIO12_KP_DKIN_0 MFP_CFG_LPM(GPIO12, AF2, FLOAT) +#define GPIO13_KP_DKIN_1 MFP_CFG_LPM(GPIO13, AF2, FLOAT) +#define GPIO14_KP_DKIN_2 MFP_CFG_LPM(GPIO14, AF2, FLOAT) +#define GPIO15_KP_DKIN_3 MFP_CFG_LPM(GPIO15, AF2, FLOAT) + +#define GPIO41_KP_DKIN_0 MFP_CFG_LPM(GPIO41, AF2, FLOAT) +#define GPIO42_KP_DKIN_1 MFP_CFG_LPM(GPIO42, AF2, FLOAT) +#define GPIO43_KP_DKIN_2 MFP_CFG_LPM(GPIO43, AF2, FLOAT) +#define GPIO44_KP_DKIN_3 MFP_CFG_LPM(GPIO44, AF2, FLOAT) +#define GPIO41_KP_DKIN_4 MFP_CFG_LPM(GPIO41, AF4, FLOAT) +#define GPIO42_KP_DKIN_5 MFP_CFG_LPM(GPIO42, AF4, FLOAT) + +#define GPIO0_KP_MKIN_0 MFP_CFG_LPM(GPIO0, AF1, FLOAT) +#define GPIO2_KP_MKIN_1 MFP_CFG_LPM(GPIO2, AF1, FLOAT) +#define GPIO4_KP_MKIN_2 MFP_CFG_LPM(GPIO4, AF1, FLOAT) +#define GPIO6_KP_MKIN_3 MFP_CFG_LPM(GPIO6, AF1, FLOAT) +#define GPIO8_KP_MKIN_4 MFP_CFG_LPM(GPIO8, AF1, FLOAT) +#define GPIO10_KP_MKIN_5 MFP_CFG_LPM(GPIO10, AF1, FLOAT) +#define GPIO12_KP_MKIN_6 MFP_CFG_LPM(GPIO12, AF1, FLOAT) +#define GPIO14_KP_MKIN_7 MFP_CFG(GPIO14, AF1) +#define GPIO35_KP_MKIN_5 MFP_CFG(GPIO35, AF4) + +#define GPIO1_KP_MKOUT_0 MFP_CFG_LPM(GPIO1, AF1, DRIVE_HIGH) +#define GPIO3_KP_MKOUT_1 MFP_CFG_LPM(GPIO3, AF1, DRIVE_HIGH) +#define GPIO5_KP_MKOUT_2 MFP_CFG_LPM(GPIO5, AF1, DRIVE_HIGH) +#define GPIO7_KP_MKOUT_3 MFP_CFG_LPM(GPIO7, AF1, DRIVE_HIGH) +#define GPIO9_KP_MKOUT_4 MFP_CFG_LPM(GPIO9, AF1, DRIVE_HIGH) +#define GPIO11_KP_MKOUT_5 MFP_CFG_LPM(GPIO11, AF1, DRIVE_HIGH) +#define GPIO13_KP_MKOUT_6 MFP_CFG_LPM(GPIO13, AF1, DRIVE_HIGH) +#define GPIO15_KP_MKOUT_7 MFP_CFG_LPM(GPIO15, AF1, DRIVE_HIGH) +#define GPIO36_KP_MKOUT_5 MFP_CFG_LPM(GPIO36, AF4, DRIVE_HIGH) + +/* LCD */ +#define GPIO17_LCD_FCLK_RD MFP_CFG(GPIO17, AF1) +#define GPIO18_LCD_LCLK_A0 MFP_CFG(GPIO18, AF1) +#define GPIO19_LCD_PCLK_WR MFP_CFG(GPIO19, AF1) +#define GPIO20_LCD_BIAS MFP_CFG(GPIO20, AF1) +#define GPIO21_LCD_CS MFP_CFG(GPIO21, AF1) +#define GPIO22_LCD_CS2 MFP_CFG(GPIO22, AF2) +#define GPIO22_LCD_VSYNC MFP_CFG(GPIO22, AF1) +#define GPIO23_LCD_DD0 MFP_CFG(GPIO23, AF1) +#define GPIO24_LCD_DD1 MFP_CFG(GPIO24, AF1) +#define GPIO25_LCD_DD2 MFP_CFG(GPIO25, AF1) +#define GPIO26_LCD_DD3 MFP_CFG(GPIO26, AF1) +#define GPIO27_LCD_DD4 MFP_CFG(GPIO27, AF1) +#define GPIO28_LCD_DD5 MFP_CFG(GPIO28, AF1) +#define GPIO29_LCD_DD6 MFP_CFG(GPIO29, AF1) +#define GPIO30_LCD_DD7 MFP_CFG(GPIO30, AF1) +#define GPIO31_LCD_DD8 MFP_CFG(GPIO31, AF1) +#define GPIO32_LCD_DD9 MFP_CFG(GPIO32, AF1) +#define GPIO33_LCD_DD10 MFP_CFG(GPIO33, AF1) +#define GPIO34_LCD_DD11 MFP_CFG(GPIO34, AF1) +#define GPIO35_LCD_DD12 MFP_CFG(GPIO35, AF1) +#define GPIO36_LCD_DD13 MFP_CFG(GPIO36, AF1) +#define GPIO37_LCD_DD14 MFP_CFG(GPIO37, AF1) +#define GPIO38_LCD_DD15 MFP_CFG(GPIO38, AF1) +#define GPIO39_LCD_DD16 MFP_CFG(GPIO39, AF1) +#define GPIO40_LCD_DD17 MFP_CFG(GPIO40, AF1) +#define GPIO41_LCD_CS2 MFP_CFG(GPIO41, AF3) +#define GPIO42_LCD_VSYNC2 MFP_CFG(GPIO42, AF3) +#define GPIO44_LCD_DD7 MFP_CFG(GPIO44, AF1) + +/* Mini-LCD */ +#define GPIO17_MLCD_FCLK MFP_CFG(GPIO17, AF3) +#define GPIO18_MLCD_LCLK MFP_CFG(GPIO18, AF3) +#define GPIO19_MLCD_PCLK MFP_CFG(GPIO19, AF3) +#define GPIO20_MLCD_BIAS MFP_CFG(GPIO20, AF3) +#define GPIO23_MLCD_DD0 MFP_CFG(GPIO23, AF3) +#define GPIO24_MLCD_DD1 MFP_CFG(GPIO24, AF3) +#define GPIO25_MLCD_DD2 MFP_CFG(GPIO25, AF3) +#define GPIO26_MLCD_DD3 MFP_CFG(GPIO26, AF3) +#define GPIO27_MLCD_DD4 MFP_CFG(GPIO27, AF3) +#define GPIO28_MLCD_DD5 MFP_CFG(GPIO28, AF3) +#define GPIO29_MLCD_DD6 MFP_CFG(GPIO29, AF3) +#define GPIO30_MLCD_DD7 MFP_CFG(GPIO30, AF3) +#define GPIO31_MLCD_DD8 MFP_CFG(GPIO31, AF3) +#define GPIO32_MLCD_DD9 MFP_CFG(GPIO32, AF3) +#define GPIO33_MLCD_DD10 MFP_CFG(GPIO33, AF3) +#define GPIO34_MLCD_DD11 MFP_CFG(GPIO34, AF3) +#define GPIO35_MLCD_DD12 MFP_CFG(GPIO35, AF3) +#define GPIO36_MLCD_DD13 MFP_CFG(GPIO36, AF3) +#define GPIO37_MLCD_DD14 MFP_CFG(GPIO37, AF3) +#define GPIO38_MLCD_DD15 MFP_CFG(GPIO38, AF3) +#define GPIO44_MLCD_DD7 MFP_CFG(GPIO44, AF5) + +/* MMC1 */ +#define GPIO10_MMC1_DAT3 MFP_CFG(GPIO10, AF4) +#define GPIO11_MMC1_DAT2 MFP_CFG(GPIO11, AF4) +#define GPIO12_MMC1_DAT1 MFP_CFG(GPIO12, AF4) +#define GPIO13_MMC1_DAT0 MFP_CFG(GPIO13, AF4) +#define GPIO14_MMC1_CMD MFP_CFG(GPIO14, AF4) +#define GPIO15_MMC1_CLK MFP_CFG(GPIO15, AF4) +#define GPIO55_MMC1_CMD MFP_CFG(GPIO55, AF3) +#define GPIO56_MMC1_CLK MFP_CFG(GPIO56, AF3) +#define GPIO57_MMC1_DAT0 MFP_CFG(GPIO57, AF3) +#define GPIO58_MMC1_DAT1 MFP_CFG(GPIO58, AF3) +#define GPIO59_MMC1_DAT2 MFP_CFG(GPIO59, AF3) +#define GPIO60_MMC1_DAT3 MFP_CFG(GPIO60, AF3) + +#define DF_ADDR0_MMC1_CLK MFP_CFG(DF_ADDR0, AF2) +#define DF_ADDR1_MMC1_CMD MFP_CFG(DF_ADDR1, AF2) +#define DF_ADDR2_MMC1_DAT0 MFP_CFG(DF_ADDR2, AF2) +#define DF_ADDR3_MMC1_DAT1 MFP_CFG(DF_ADDR3, AF3) +#define nXCVREN_MMC1_DAT2 MFP_CFG(nXCVREN, AF2) + +/* MMC2 */ +#define GPIO31_MMC2_CMD MFP_CFG(GPIO31, AF7) +#define GPIO32_MMC2_CLK MFP_CFG(GPIO32, AF7) +#define GPIO33_MMC2_DAT0 MFP_CFG(GPIO33, AF7) +#define GPIO34_MMC2_DAT1 MFP_CFG(GPIO34, AF7) +#define GPIO35_MMC2_DAT2 MFP_CFG(GPIO35, AF7) +#define GPIO36_MMC2_DAT3 MFP_CFG(GPIO36, AF7) + +#define GPIO101_MMC2_DAT3 MFP_CFG(GPIO101, AF1) +#define GPIO102_MMC2_DAT2 MFP_CFG(GPIO102, AF1) +#define GPIO103_MMC2_DAT1 MFP_CFG(GPIO103, AF1) +#define GPIO104_MMC2_DAT0 MFP_CFG(GPIO104, AF1) +#define GPIO105_MMC2_CMD MFP_CFG(GPIO105, AF1) +#define GPIO106_MMC2_CLK MFP_CFG(GPIO106, AF1) + +#define DF_IO10_MMC2_DAT3 MFP_CFG(DF_IO10, AF3) +#define DF_IO11_MMC2_DAT2 MFP_CFG(DF_IO11, AF3) +#define DF_IO12_MMC2_DAT1 MFP_CFG(DF_IO12, AF3) +#define DF_IO13_MMC2_DAT0 MFP_CFG(DF_IO13, AF3) +#define DF_IO14_MMC2_CLK MFP_CFG(DF_IO14, AF3) +#define DF_IO15_MMC2_CMD MFP_CFG(DF_IO15, AF3) + +/* BSSP1 */ +#define GPIO12_BSSP1_CLK MFP_CFG(GPIO12, AF3) +#define GPIO13_BSSP1_FRM MFP_CFG(GPIO13, AF3) +#define GPIO14_BSSP1_RXD MFP_CFG(GPIO14, AF3) +#define GPIO15_BSSP1_TXD MFP_CFG(GPIO15, AF3) +#define GPIO97_BSSP1_CLK MFP_CFG(GPIO97, AF5) +#define GPIO98_BSSP1_FRM MFP_CFG(GPIO98, AF5) + +/* BSSP2 */ +#define GPIO84_BSSP2_SDATA_IN MFP_CFG(GPIO84, AF1) +#define GPIO85_BSSP2_BITCLK MFP_CFG(GPIO85, AF1) +#define GPIO86_BSSP2_SYSCLK MFP_CFG(GPIO86, AF1) +#define GPIO87_BSSP2_SYNC MFP_CFG(GPIO87, AF1) +#define GPIO88_BSSP2_DATA_OUT MFP_CFG(GPIO88, AF1) +#define GPIO86_BSSP2_SDATA_IN MFP_CFG(GPIO86, AF4) + +/* BSSP3 */ +#define GPIO79_BSSP3_CLK MFP_CFG(GPIO79, AF1) +#define GPIO80_BSSP3_FRM MFP_CFG(GPIO80, AF1) +#define GPIO81_BSSP3_TXD MFP_CFG(GPIO81, AF1) +#define GPIO82_BSSP3_RXD MFP_CFG(GPIO82, AF1) +#define GPIO83_BSSP3_SYSCLK MFP_CFG(GPIO83, AF1) + +/* BSSP4 */ +#define GPIO43_BSSP4_CLK MFP_CFG(GPIO43, AF4) +#define GPIO44_BSSP4_FRM MFP_CFG(GPIO44, AF4) +#define GPIO45_BSSP4_TXD MFP_CFG(GPIO45, AF4) +#define GPIO46_BSSP4_RXD MFP_CFG(GPIO46, AF4) + +#define GPIO51_BSSP4_CLK MFP_CFG(GPIO51, AF4) +#define GPIO52_BSSP4_FRM MFP_CFG(GPIO52, AF4) +#define GPIO53_BSSP4_TXD MFP_CFG(GPIO53, AF4) +#define GPIO54_BSSP4_RXD MFP_CFG(GPIO54, AF4) + +/* GSSP1 */ +#define GPIO79_GSSP1_CLK MFP_CFG(GPIO79, AF2) +#define GPIO80_GSSP1_FRM MFP_CFG(GPIO80, AF2) +#define GPIO81_GSSP1_TXD MFP_CFG(GPIO81, AF2) +#define GPIO82_GSSP1_RXD MFP_CFG(GPIO82, AF2) +#define GPIO83_GSSP1_SYSCLK MFP_CFG(GPIO83, AF2) + +#define GPIO93_GSSP1_CLK MFP_CFG(GPIO93, AF4) +#define GPIO94_GSSP1_FRM MFP_CFG(GPIO94, AF4) +#define GPIO95_GSSP1_TXD MFP_CFG(GPIO95, AF4) +#define GPIO96_GSSP1_RXD MFP_CFG(GPIO96, AF4) + +/* GSSP2 */ +#define GPIO47_GSSP2_CLK MFP_CFG(GPIO47, AF4) +#define GPIO48_GSSP2_FRM MFP_CFG(GPIO48, AF4) +#define GPIO49_GSSP2_RXD MFP_CFG(GPIO49, AF4) +#define GPIO50_GSSP2_TXD MFP_CFG(GPIO50, AF4) + +#define GPIO69_GSSP2_CLK MFP_CFG(GPIO69, AF4) +#define GPIO70_GSSP2_FRM MFP_CFG(GPIO70, AF4) +#define GPIO71_GSSP2_RXD MFP_CFG(GPIO71, AF4) +#define GPIO72_GSSP2_TXD MFP_CFG(GPIO72, AF4) + +#define GPIO84_GSSP2_RXD MFP_CFG(GPIO84, AF2) +#define GPIO85_GSSP2_CLK MFP_CFG(GPIO85, AF2) +#define GPIO86_GSSP2_SYSCLK MFP_CFG(GPIO86, AF2) +#define GPIO87_GSSP2_FRM MFP_CFG(GPIO87, AF2) +#define GPIO88_GSSP2_TXD MFP_CFG(GPIO88, AF2) +#define GPIO86_GSSP2_RXD MFP_CFG(GPIO86, AF5) + +#define GPIO103_GSSP2_CLK MFP_CFG(GPIO103, AF2) +#define GPIO104_GSSP2_FRM MFP_CFG(GPIO104, AF2) +#define GPIO105_GSSP2_RXD MFP_CFG(GPIO105, AF2) +#define GPIO106_GSSP2_TXD MFP_CFG(GPIO106, AF2) + +/* UART1 - FFUART */ +#define GPIO47_UART1_DSR_N MFP_CFG(GPIO47, AF1) +#define GPIO48_UART1_DTR_N MFP_CFG(GPIO48, AF1) +#define GPIO49_UART1_RI MFP_CFG(GPIO49, AF1) +#define GPIO50_UART1_DCD MFP_CFG(GPIO50, AF1) +#define GPIO51_UART1_CTS MFP_CFG(GPIO51, AF1) +#define GPIO52_UART1_RTS MFP_CFG(GPIO52, AF1) +#define GPIO53_UART1_RXD MFP_CFG(GPIO53, AF1) +#define GPIO54_UART1_TXD MFP_CFG(GPIO54, AF1) + +#define GPIO63_UART1_TXD MFP_CFG(GPIO63, AF2) +#define GPIO64_UART1_RXD MFP_CFG(GPIO64, AF2) +#define GPIO65_UART1_DSR MFP_CFG(GPIO65, AF2) +#define GPIO66_UART1_DTR MFP_CFG(GPIO66, AF2) +#define GPIO67_UART1_RI MFP_CFG(GPIO67, AF2) +#define GPIO68_UART1_DCD MFP_CFG(GPIO68, AF2) +#define GPIO69_UART1_CTS MFP_CFG(GPIO69, AF2) +#define GPIO70_UART1_RTS MFP_CFG(GPIO70, AF2) + +/* UART2 - BTUART */ +#define GPIO91_UART2_RXD MFP_CFG(GPIO91, AF1) +#define GPIO92_UART2_TXD MFP_CFG(GPIO92, AF1) +#define GPIO93_UART2_CTS MFP_CFG(GPIO93, AF1) +#define GPIO94_UART2_RTS MFP_CFG(GPIO94, AF1) + +/* UART3 - STUART */ +#define GPIO43_UART3_RTS MFP_CFG(GPIO43, AF3) +#define GPIO44_UART3_CTS MFP_CFG(GPIO44, AF3) +#define GPIO45_UART3_RXD MFP_CFG(GPIO45, AF3) +#define GPIO46_UART3_TXD MFP_CFG(GPIO46, AF3) + +#define GPIO75_UART3_RTS MFP_CFG(GPIO75, AF5) +#define GPIO76_UART3_CTS MFP_CFG(GPIO76, AF5) +#define GPIO77_UART3_TXD MFP_CFG(GPIO77, AF5) +#define GPIO78_UART3_RXD MFP_CFG(GPIO78, AF5) + +/* DFI */ +#define DF_IO0_DF_IO0 MFP_CFG(DF_IO0, AF2) +#define DF_IO1_DF_IO1 MFP_CFG(DF_IO1, AF2) +#define DF_IO2_DF_IO2 MFP_CFG(DF_IO2, AF2) +#define DF_IO3_DF_IO3 MFP_CFG(DF_IO3, AF2) +#define DF_IO4_DF_IO4 MFP_CFG(DF_IO4, AF2) +#define DF_IO5_DF_IO5 MFP_CFG(DF_IO5, AF2) +#define DF_IO6_DF_IO6 MFP_CFG(DF_IO6, AF2) +#define DF_IO7_DF_IO7 MFP_CFG(DF_IO7, AF2) +#define DF_IO8_DF_IO8 MFP_CFG(DF_IO8, AF2) +#define DF_IO9_DF_IO9 MFP_CFG(DF_IO9, AF2) +#define DF_IO10_DF_IO10 MFP_CFG(DF_IO10, AF2) +#define DF_IO11_DF_IO11 MFP_CFG(DF_IO11, AF2) +#define DF_IO12_DF_IO12 MFP_CFG(DF_IO12, AF2) +#define DF_IO13_DF_IO13 MFP_CFG(DF_IO13, AF2) +#define DF_IO14_DF_IO14 MFP_CFG(DF_IO14, AF2) +#define DF_IO15_DF_IO15 MFP_CFG(DF_IO15, AF2) +#define DF_nADV1_ALE_DF_nADV1 MFP_CFG(DF_nADV1_ALE, AF2) +#define DF_nADV2_ALE_DF_nADV2 MFP_CFG(DF_nADV2_ALE, AF2) +#define DF_nCS0_DF_nCS0 MFP_CFG(DF_nCS0, AF2) +#define DF_nCS1_DF_nCS1 MFP_CFG(DF_nCS1, AF2) +#define DF_nRE_nOE_DF_nOE MFP_CFG(DF_nRE_nOE, AF2) +#define DF_nWE_DF_nWE MFP_CFG(DF_nWE, AF2) + +/* DFI - NAND */ +#define DF_CLE_nOE_ND_CLE MFP_CFG_LPM(DF_CLE_nOE, AF1, PULL_HIGH) +#define DF_INT_RnB_ND_INT_RnB MFP_CFG_LPM(DF_INT_RnB, AF1, PULL_LOW) +#define DF_IO0_ND_IO0 MFP_CFG_LPM(DF_IO0, AF1, PULL_LOW) +#define DF_IO1_ND_IO1 MFP_CFG_LPM(DF_IO1, AF1, PULL_LOW) +#define DF_IO2_ND_IO2 MFP_CFG_LPM(DF_IO2, AF1, PULL_LOW) +#define DF_IO3_ND_IO3 MFP_CFG_LPM(DF_IO3, AF1, PULL_LOW) +#define DF_IO4_ND_IO4 MFP_CFG_LPM(DF_IO4, AF1, PULL_LOW) +#define DF_IO5_ND_IO5 MFP_CFG_LPM(DF_IO5, AF1, PULL_LOW) +#define DF_IO6_ND_IO6 MFP_CFG_LPM(DF_IO6, AF1, PULL_LOW) +#define DF_IO7_ND_IO7 MFP_CFG_LPM(DF_IO7, AF1, PULL_LOW) +#define DF_IO8_ND_IO8 MFP_CFG_LPM(DF_IO8, AF1, PULL_LOW) +#define DF_IO9_ND_IO9 MFP_CFG_LPM(DF_IO9, AF1, PULL_LOW) +#define DF_IO10_ND_IO10 MFP_CFG_LPM(DF_IO10, AF1, PULL_LOW) +#define DF_IO11_ND_IO11 MFP_CFG_LPM(DF_IO11, AF1, PULL_LOW) +#define DF_IO12_ND_IO12 MFP_CFG_LPM(DF_IO12, AF1, PULL_LOW) +#define DF_IO13_ND_IO13 MFP_CFG_LPM(DF_IO13, AF1, PULL_LOW) +#define DF_IO14_ND_IO14 MFP_CFG_LPM(DF_IO14, AF1, PULL_LOW) +#define DF_IO15_ND_IO15 MFP_CFG_LPM(DF_IO15, AF1, PULL_LOW) +#define DF_nADV1_ALE_ND_ALE MFP_CFG_LPM(DF_nADV1_ALE, AF1, PULL_HIGH) +#define DF_nADV2_ALE_ND_ALE MFP_CFG_LPM(DF_nADV2_ALE, AF1, PULL_HIGH) +#define DF_nADV2_ALE_nCS3 MFP_CFG_LPM(DF_nADV2_ALE, AF3, PULL_HIGH) +#define DF_nCS0_ND_nCS0 MFP_CFG_LPM(DF_nCS0, AF1, PULL_HIGH) +#define DF_nCS1_ND_nCS1 MFP_CFG_LPM(DF_nCS1, AF1, PULL_HIGH) +#define DF_nRE_nOE_ND_nRE MFP_CFG_LPM(DF_nRE_nOE, AF1, PULL_HIGH) +#define DF_nWE_ND_nWE MFP_CFG_LPM(DF_nWE, AF1, PULL_HIGH) + +/* PWM */ +#define GPIO41_PWM0 MFP_CFG_LPM(GPIO41, AF1, PULL_LOW) +#define GPIO42_PWM1 MFP_CFG_LPM(GPIO42, AF1, PULL_LOW) +#define GPIO43_PWM3 MFP_CFG_LPM(GPIO43, AF1, PULL_LOW) +#define GPIO20_PWM0 MFP_CFG_LPM(GPIO20, AF2, PULL_LOW) +#define GPIO21_PWM2 MFP_CFG_LPM(GPIO21, AF3, PULL_LOW) +#define GPIO22_PWM3 MFP_CFG_LPM(GPIO22, AF3, PULL_LOW) + +/* CIR */ +#define GPIO46_CIR_OUT MFP_CFG(GPIO46, AF1) +#define GPIO77_CIR_OUT MFP_CFG(GPIO77, AF3) + +/* USB P2 */ +#define GPIO0_USB_P2_7 MFP_CFG(GPIO0, AF3) +#define GPIO15_USB_P2_7 MFP_CFG(GPIO15, AF5) +#define GPIO16_USB_P2_7 MFP_CFG(GPIO16, AF2) +#define GPIO48_USB_P2_7 MFP_CFG(GPIO48, AF7) +#define GPIO49_USB_P2_7 MFP_CFG(GPIO49, AF6) +#define DF_IO9_USB_P2_7 MFP_CFG(DF_IO9, AF3) + +#define GPIO48_USB_P2_8 MFP_CFG(GPIO48, AF2) +#define GPIO50_USB_P2_7 MFP_CFG_X(GPIO50, AF2, DS02X, FLOAT) +#define GPIO51_USB_P2_5 MFP_CFG(GPIO51, AF2) +#define GPIO47_USB_P2_4 MFP_CFG(GPIO47, AF2) +#define GPIO53_USB_P2_3 MFP_CFG(GPIO53, AF2) +#define GPIO54_USB_P2_6 MFP_CFG(GPIO54, AF2) +#define GPIO49_USB_P2_2 MFP_CFG(GPIO49, AF2) +#define GPIO52_USB_P2_1 MFP_CFG(GPIO52, AF2) + +#define GPIO63_USB_P2_8 MFP_CFG(GPIO63, AF3) +#define GPIO64_USB_P2_7 MFP_CFG(GPIO64, AF3) +#define GPIO65_USB_P2_6 MFP_CFG(GPIO65, AF3) +#define GPIO66_USG_P2_5 MFP_CFG(GPIO66, AF3) +#define GPIO67_USB_P2_4 MFP_CFG(GPIO67, AF3) +#define GPIO68_USB_P2_3 MFP_CFG(GPIO68, AF3) +#define GPIO69_USB_P2_2 MFP_CFG(GPIO69, AF3) +#define GPIO70_USB_P2_1 MFP_CFG(GPIO70, AF3) + +/* ULPI */ +#define GPIO31_USB_ULPI_D0 MFP_CFG(GPIO31, AF4) +#define GPIO30_USB_ULPI_D1 MFP_CFG(GPIO30, AF7) +#define GPIO33_USB_ULPI_D2 MFP_CFG(GPIO33, AF5) +#define GPIO34_USB_ULPI_D3 MFP_CFG(GPIO34, AF5) +#define GPIO35_USB_ULPI_D4 MFP_CFG(GPIO35, AF5) +#define GPIO36_USB_ULPI_D5 MFP_CFG(GPIO36, AF5) +#define GPIO41_USB_ULPI_D6 MFP_CFG(GPIO41, AF5) +#define GPIO42_USB_ULPI_D7 MFP_CFG(GPIO42, AF5) +#define GPIO37_USB_ULPI_DIR MFP_CFG(GPIO37, AF4) +#define GPIO38_USB_ULPI_CLK MFP_CFG(GPIO38, AF4) +#define GPIO39_USB_ULPI_STP MFP_CFG(GPIO39, AF4) +#define GPIO40_USB_ULPI_NXT MFP_CFG(GPIO40, AF4) + +#define GPIO3_CLK26MOUTDMD MFP_CFG(GPIO3, AF3) +#define GPIO40_CLK26MOUTDMD MFP_CFG(GPIO40, AF7) +#define GPIO94_CLK26MOUTDMD MFP_CFG(GPIO94, AF5) +#define GPIO104_CLK26MOUTDMD MFP_CFG(GPIO104, AF4) +#define DF_ADDR1_CLK26MOUTDMD MFP_CFG(DF_ADDR2, AF3) +#define DF_ADDR3_CLK26MOUTDMD MFP_CFG(DF_ADDR3, AF3) + +#define GPIO14_CLK26MOUT MFP_CFG(GPIO14, AF5) +#define GPIO38_CLK26MOUT MFP_CFG(GPIO38, AF7) +#define GPIO92_CLK26MOUT MFP_CFG(GPIO92, AF5) +#define GPIO105_CLK26MOUT MFP_CFG(GPIO105, AF4) + +#define GPIO2_CLK13MOUTDMD MFP_CFG(GPIO2, AF3) +#define GPIO39_CLK13MOUTDMD MFP_CFG(GPIO39, AF7) +#define GPIO50_CLK13MOUTDMD MFP_CFG(GPIO50, AF3) +#define GPIO93_CLK13MOUTDMD MFP_CFG(GPIO93, AF5) +#define GPIO103_CLK13MOUTDMD MFP_CFG(GPIO103, AF4) +#define DF_ADDR2_CLK13MOUTDMD MFP_CFG(DF_ADDR2, AF3) + +/* 1 wire */ +#define GPIO95_OW_DQ_IN MFP_CFG(GPIO95, AF5) + +#endif /* __ASM_ARCH_MFP_PXA9xx_H */ diff --git a/include/asm-arm/arch-pxa/mfp.h b/include/asm-arm/arch-pxa/mfp.h index 02f6157396d..e7d58798da6 100644 --- a/include/asm-arm/arch-pxa/mfp.h +++ b/include/asm-arm/arch-pxa/mfp.h @@ -210,6 +210,14 @@ enum { MFP_PIN_DF_IO14, MFP_PIN_DF_IO15, + /* additional pins on PXA930 */ + MFP_PIN_GSIM_UIO, + MFP_PIN_GSIM_UCLK, + MFP_PIN_GSIM_UDET, + MFP_PIN_GSIM_nURST, + MFP_PIN_PMIC_INT, + MFP_PIN_RDY, + MFP_PIN_MAX, }; -- cgit v1.2.3-70-g09d2 From c5a89c6c0805959f813e8342d6f4040860f6d7db Mon Sep 17 00:00:00 2001 From: Marc Pignat Date: Fri, 30 May 2008 14:07:47 +0200 Subject: mmc: at91_mci: avoid timeouts The at91 mci controller internal state machine seems to often crash. This can be fixed by resetting the controller after each command for at91rm9200 and by setting the MCI_BLKR register on at91sam926*. Signed-off-by: Marc Pignat Signed-off-by: Hans J Koch Signed-off-by: Nicolas Ferre Signed-off-by: Pierre Ossman --- drivers/mmc/host/at91_mci.c | 48 ++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-at91/at91_mci.h | 4 +++ 2 files changed, 52 insertions(+) (limited to 'include/asm-arm') diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index fce171c7c67..e9242110ce2 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -130,6 +130,43 @@ struct at91mci_host struct timer_list timer; }; +/* + * Reset the controller and restore most of the state + */ +static void at91_reset_host(struct at91mci_host *host) +{ + unsigned long flags; + u32 mr; + u32 sdcr; + u32 dtor; + u32 imr; + + local_irq_save(flags); + imr = at91_mci_read(host, AT91_MCI_IMR); + + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); + + /* save current state */ + mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; + sdcr = at91_mci_read(host, AT91_MCI_SDCR); + dtor = at91_mci_read(host, AT91_MCI_DTOR); + + /* reset the controller */ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); + + /* restore state */ + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); + at91_mci_write(host, AT91_MCI_MR, mr); + at91_mci_write(host, AT91_MCI_SDCR, sdcr); + at91_mci_write(host, AT91_MCI_DTOR, dtor); + at91_mci_write(host, AT91_MCI_IER, imr); + + /* make sure sdio interrupts will fire */ + at91_mci_read(host, AT91_MCI_SR); + + local_irq_restore(flags); +} + static void at91_timeout_timer(unsigned long data) { struct at91mci_host *host; @@ -148,6 +185,7 @@ static void at91_timeout_timer(unsigned long data) host->request->cmd->error = -ETIMEDOUT; } + at91_reset_host(host); mmc_request_done(host->mmc, host->request); } } @@ -512,6 +550,11 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command mr |= AT91_MCI_PDCMODE; at91_mci_write(host, AT91_MCI_MR, mr); + if (!cpu_is_at91rm9200()) + at91_mci_write(host, AT91_MCI_BLKR, + AT91_MCI_BLKR_BCNT(blocks) | + AT91_MCI_BLKR_BLKLEN(block_length)); + /* * Disable the PDC controller */ @@ -584,6 +627,11 @@ static void at91_mci_process_next(struct at91mci_host *host) at91_mci_send_command(host, host->request->stop); } else { del_timer(&host->timer); + /* the at91rm9200 mci controller hangs after some transfers, + * and the workaround is to reset it after each transfer. + */ + if (cpu_is_at91rm9200()) + at91_reset_host(host); mmc_request_done(host->mmc, host->request); } } diff --git a/include/asm-arm/arch-at91/at91_mci.h b/include/asm-arm/arch-at91/at91_mci.h index 1551fc24eb4..400ec10014b 100644 --- a/include/asm-arm/arch-at91/at91_mci.h +++ b/include/asm-arm/arch-at91/at91_mci.h @@ -75,6 +75,10 @@ #define AT91_MCI_TRTYP_MULTIPLE (1 << 19) #define AT91_MCI_TRTYP_STREAM (2 << 19) +#define AT91_MCI_BLKR 0x18 /* Block Register */ +#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ +#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block lenght */ + #define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */ #define AT91_MCR_RDR 0x30 /* Receive Data Register */ #define AT91_MCR_TDR 0x34 /* Transmit Data Register */ -- cgit v1.2.3-70-g09d2 From be518018c6b9224c02284fb243207ef741c31ec6 Mon Sep 17 00:00:00 2001 From: Thomas Kleffel Date: Mon, 30 Jun 2008 22:40:24 +0100 Subject: MMC: S3C24XX MMC/SD driver. This is the latest S3C MMC/SD driver by Thomas Kleffel with cleanups as suggested by AKPM done by Ben Dooks. Signed-off-by: Ben Dooks Signed-off-by: Thomas Kleffel Signed-off-by: Pierre Ossman --- drivers/mmc/host/Kconfig | 11 + drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/s3cmci.c | 1343 +++++++++++++++++++++++++++++++ drivers/mmc/host/s3cmci.h | 69 ++ include/asm-arm/arch-s3c2410/regs-sdi.h | 20 +- 5 files changed, 1441 insertions(+), 4 deletions(-) create mode 100644 drivers/mmc/host/s3cmci.c create mode 100644 drivers/mmc/host/s3cmci.h (limited to 'include/asm-arm') diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index f9cbcb891e9..dc88c03662a 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -143,3 +143,14 @@ config MMC_SPI If unsure, or if your system has no SPI master driver, say N. +config MMC_S3C + tristate "Samsung S3C SD/MMC Card Interface support" + depends on ARCH_S3C2410 && MMC + help + This selects a driver for the MCI interface found in + Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs. + If you have a board based on one of those and a MMC/SD + slot, say Y or M here. + + If unsure, say N. + diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 3027250b855..b3e023bf8c7 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,4 +18,4 @@ obj-$(CONFIG_MMC_OMAP) += omap.o obj-$(CONFIG_MMC_AT91) += at91_mci.o obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o - +obj-$(CONFIG_MMC_S3C) += s3cmci.o diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c new file mode 100644 index 00000000000..c6a4d3cadf2 --- /dev/null +++ b/drivers/mmc/host/s3cmci.c @@ -0,0 +1,1343 @@ +/* + * linux/drivers/mmc/s3cmci.h - Samsung S3C MCI driver + * + * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "s3cmci.h" + +#define DRIVER_NAME "s3c-mci" + +enum dbg_channels { + dbg_err = (1 << 0), + dbg_debug = (1 << 1), + dbg_info = (1 << 2), + dbg_irq = (1 << 3), + dbg_sg = (1 << 4), + dbg_dma = (1 << 5), + dbg_pio = (1 << 6), + dbg_fail = (1 << 7), + dbg_conf = (1 << 8), +}; + +static const int dbgmap_err = dbg_err | dbg_fail; +static const int dbgmap_info = dbg_info | dbg_conf; +static const int dbgmap_debug = dbg_debug; + +#define dbg(host, channels, args...) \ + do { \ + if (dbgmap_err & channels) \ + dev_err(&host->pdev->dev, args); \ + else if (dbgmap_info & channels) \ + dev_info(&host->pdev->dev, args); \ + else if (dbgmap_debug & channels) \ + dev_dbg(&host->pdev->dev, args); \ + } while (0) + +#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1) + +static struct s3c2410_dma_client s3cmci_dma_client = { + .name = "s3c-mci", +}; + +static void finalize_request(struct s3cmci_host *host); +static void s3cmci_send_request(struct mmc_host *mmc); +static void s3cmci_reset(struct s3cmci_host *host); + +#ifdef CONFIG_MMC_DEBUG + +static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) +{ + u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer, bsize; + u32 datcon, datcnt, datsta, fsta, imask; + + con = readl(host->base + S3C2410_SDICON); + pre = readl(host->base + S3C2410_SDIPRE); + cmdarg = readl(host->base + S3C2410_SDICMDARG); + cmdcon = readl(host->base + S3C2410_SDICMDCON); + cmdsta = readl(host->base + S3C2410_SDICMDSTAT); + r0 = readl(host->base + S3C2410_SDIRSP0); + r1 = readl(host->base + S3C2410_SDIRSP1); + r2 = readl(host->base + S3C2410_SDIRSP2); + r3 = readl(host->base + S3C2410_SDIRSP3); + timer = readl(host->base + S3C2410_SDITIMER); + bsize = readl(host->base + S3C2410_SDIBSIZE); + datcon = readl(host->base + S3C2410_SDIDCON); + datcnt = readl(host->base + S3C2410_SDIDCNT); + datsta = readl(host->base + S3C2410_SDIDSTA); + fsta = readl(host->base + S3C2410_SDIFSTA); + imask = readl(host->base + host->sdiimsk); + + dbg(host, dbg_debug, "%s CON:[%08x] PRE:[%08x] TMR:[%08x]\n", + prefix, con, pre, timer); + + dbg(host, dbg_debug, "%s CCON:[%08x] CARG:[%08x] CSTA:[%08x]\n", + prefix, cmdcon, cmdarg, cmdsta); + + dbg(host, dbg_debug, "%s DCON:[%08x] FSTA:[%08x]" + " DSTA:[%08x] DCNT:[%08x]\n", + prefix, datcon, fsta, datsta, datcnt); + + dbg(host, dbg_debug, "%s R0:[%08x] R1:[%08x]" + " R2:[%08x] R3:[%08x]\n", + prefix, r0, r1, r2, r3); +} + +static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd, + int stop) +{ + snprintf(host->dbgmsg_cmd, 300, + "#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u", + host->ccnt, (stop ? " (STOP)" : ""), + cmd->opcode, cmd->arg, cmd->flags, cmd->retries); + + if (cmd->data) { + snprintf(host->dbgmsg_dat, 300, + "#%u bsize:%u blocks:%u bytes:%u", + host->dcnt, cmd->data->blksz, + cmd->data->blocks, + cmd->data->blocks * cmd->data->blksz); + } else { + host->dbgmsg_dat[0] = '\0'; + } +} + +static void dbg_dumpcmd(struct s3cmci_host *host, struct mmc_command *cmd, + int fail) +{ + unsigned int dbglvl = fail ? dbg_fail : dbg_debug; + + if (!cmd) + return; + + if (cmd->error == 0) { + dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n", + host->dbgmsg_cmd, cmd->resp[0]); + } else { + dbg(host, dbglvl, "CMD[ERR %i] %s Status:%s\n", + cmd->error, host->dbgmsg_cmd, host->status); + } + + if (!cmd->data) + return; + + if (cmd->data->error == 0) { + dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat); + } else { + dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n", + cmd->data->error, host->dbgmsg_dat, + readl(host->base + S3C2410_SDIDCNT)); + } +} +#else +static void dbg_dumpcmd(struct s3cmci_host *host, + struct mmc_command *cmd, int fail) { } + +static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd, + int stop) { } + +static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { } + +#endif /* CONFIG_MMC_DEBUG */ + +static inline u32 enable_imask(struct s3cmci_host *host, u32 imask) +{ + u32 newmask; + + newmask = readl(host->base + host->sdiimsk); + newmask |= imask; + + writel(newmask, host->base + host->sdiimsk); + + return newmask; +} + +static inline u32 disable_imask(struct s3cmci_host *host, u32 imask) +{ + u32 newmask; + + newmask = readl(host->base + host->sdiimsk); + newmask &= ~imask; + + writel(newmask, host->base + host->sdiimsk); + + return newmask; +} + +static inline void clear_imask(struct s3cmci_host *host) +{ + writel(0, host->base + host->sdiimsk); +} + +static inline int get_data_buffer(struct s3cmci_host *host, + u32 *words, u32 **pointer) +{ + struct scatterlist *sg; + + if (host->pio_active == XFER_NONE) + return -EINVAL; + + if ((!host->mrq) || (!host->mrq->data)) + return -EINVAL; + + if (host->pio_sgptr >= host->mrq->data->sg_len) { + dbg(host, dbg_debug, "no more buffers (%i/%i)\n", + host->pio_sgptr, host->mrq->data->sg_len); + return -EBUSY; + } + sg = &host->mrq->data->sg[host->pio_sgptr]; + + *words = sg->length >> 2; + *pointer = sg_virt(sg); + + host->pio_sgptr++; + + dbg(host, dbg_sg, "new buffer (%i/%i)\n", + host->pio_sgptr, host->mrq->data->sg_len); + + return 0; +} + +static inline u32 fifo_count(struct s3cmci_host *host) +{ + u32 fifostat = readl(host->base + S3C2410_SDIFSTA); + + fifostat &= S3C2410_SDIFSTA_COUNTMASK; + return fifostat >> 2; +} + +static inline u32 fifo_free(struct s3cmci_host *host) +{ + u32 fifostat = readl(host->base + S3C2410_SDIFSTA); + + fifostat &= S3C2410_SDIFSTA_COUNTMASK; + return (63 - fifostat) >> 2; +} + +static void do_pio_read(struct s3cmci_host *host) +{ + int res; + u32 fifo; + void __iomem *from_ptr; + + /* write real prescaler to host, it might be set slow to fix */ + writel(host->prescaler, host->base + S3C2410_SDIPRE); + + from_ptr = host->base + host->sdidata; + + while ((fifo = fifo_count(host))) { + if (!host->pio_words) { + res = get_data_buffer(host, &host->pio_words, + &host->pio_ptr); + if (res) { + host->pio_active = XFER_NONE; + host->complete_what = COMPLETION_FINALIZE; + + dbg(host, dbg_pio, "pio_read(): " + "complete (no more data).\n"); + return; + } + + dbg(host, dbg_pio, + "pio_read(): new target: [%i]@[%p]\n", + host->pio_words, host->pio_ptr); + } + + dbg(host, dbg_pio, + "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", + fifo, host->pio_words, + readl(host->base + S3C2410_SDIDCNT)); + + if (fifo > host->pio_words) + fifo = host->pio_words; + + host->pio_words -= fifo; + host->pio_count += fifo; + + while (fifo--) + *(host->pio_ptr++) = readl(from_ptr); + } + + if (!host->pio_words) { + res = get_data_buffer(host, &host->pio_words, &host->pio_ptr); + if (res) { + dbg(host, dbg_pio, + "pio_read(): complete (no more buffers).\n"); + host->pio_active = XFER_NONE; + host->complete_what = COMPLETION_FINALIZE; + + return; + } + } + + enable_imask(host, + S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST); +} + +static void do_pio_write(struct s3cmci_host *host) +{ + void __iomem *to_ptr; + int res; + u32 fifo; + + to_ptr = host->base + host->sdidata; + + while ((fifo = fifo_free(host))) { + if (!host->pio_words) { + res = get_data_buffer(host, &host->pio_words, + &host->pio_ptr); + if (res) { + dbg(host, dbg_pio, + "pio_write(): complete (no more data).\n"); + host->pio_active = XFER_NONE; + + return; + } + + dbg(host, dbg_pio, + "pio_write(): new source: [%i]@[%p]\n", + host->pio_words, host->pio_ptr); + + } + + if (fifo > host->pio_words) + fifo = host->pio_words; + + host->pio_words -= fifo; + host->pio_count += fifo; + + while (fifo--) + writel(*(host->pio_ptr++), to_ptr); + } + + enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); +} + +static void pio_tasklet(unsigned long data) +{ + struct s3cmci_host *host = (struct s3cmci_host *) data; + + + if (host->pio_active == XFER_WRITE) + do_pio_write(host); + + if (host->pio_active == XFER_READ) + do_pio_read(host); + + if (host->complete_what == COMPLETION_FINALIZE) { + clear_imask(host); + if (host->pio_active != XFER_NONE) { + dbg(host, dbg_err, "unfinished %s " + "- pio_count:[%u] pio_words:[%u]\n", + (host->pio_active == XFER_READ) ? "read" : "write", + host->pio_count, host->pio_words); + + host->mrq->data->error = -EINVAL; + } + + disable_irq(host->irq); + finalize_request(host); + } +} + +/* + * ISR for SDI Interface IRQ + * Communication between driver and ISR works as follows: + * host->mrq points to current request + * host->complete_what Indicates when the request is considered done + * COMPLETION_CMDSENT when the command was sent + * COMPLETION_RSPFIN when a response was received + * COMPLETION_XFERFINISH when the data transfer is finished + * COMPLETION_XFERFINISH_RSPFIN both of the above. + * host->complete_request is the completion-object the driver waits for + * + * 1) Driver sets up host->mrq and host->complete_what + * 2) Driver prepares the transfer + * 3) Driver enables interrupts + * 4) Driver starts transfer + * 5) Driver waits for host->complete_rquest + * 6) ISR checks for request status (errors and success) + * 6) ISR sets host->mrq->cmd->error and host->mrq->data->error + * 7) ISR completes host->complete_request + * 8) ISR disables interrupts + * 9) Driver wakes up and takes care of the request + * + * Note: "->error"-fields are expected to be set to 0 before the request + * was issued by mmc.c - therefore they are only set, when an error + * contition comes up + */ + +static irqreturn_t s3cmci_irq(int irq, void *dev_id) +{ + struct s3cmci_host *host = dev_id; + struct mmc_command *cmd; + u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk; + u32 mci_cclear, mci_dclear; + unsigned long iflags; + + spin_lock_irqsave(&host->complete_lock, iflags); + + mci_csta = readl(host->base + S3C2410_SDICMDSTAT); + mci_dsta = readl(host->base + S3C2410_SDIDSTA); + mci_dcnt = readl(host->base + S3C2410_SDIDCNT); + mci_fsta = readl(host->base + S3C2410_SDIFSTA); + mci_imsk = readl(host->base + host->sdiimsk); + mci_cclear = 0; + mci_dclear = 0; + + if ((host->complete_what == COMPLETION_NONE) || + (host->complete_what == COMPLETION_FINALIZE)) { + host->status = "nothing to complete"; + clear_imask(host); + goto irq_out; + } + + if (!host->mrq) { + host->status = "no active mrq"; + clear_imask(host); + goto irq_out; + } + + cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd; + + if (!cmd) { + host->status = "no active cmd"; + clear_imask(host); + goto irq_out; + } + + if (!host->dodma) { + if ((host->pio_active == XFER_WRITE) && + (mci_fsta & S3C2410_SDIFSTA_TFDET)) { + + disable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); + tasklet_schedule(&host->pio_tasklet); + host->status = "pio tx"; + } + + if ((host->pio_active == XFER_READ) && + (mci_fsta & S3C2410_SDIFSTA_RFDET)) { + + disable_imask(host, + S3C2410_SDIIMSK_RXFIFOHALF | + S3C2410_SDIIMSK_RXFIFOLAST); + + tasklet_schedule(&host->pio_tasklet); + host->status = "pio rx"; + } + } + + if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) { + cmd->error = -ETIMEDOUT; + host->status = "error: command timeout"; + goto fail_transfer; + } + + if (mci_csta & S3C2410_SDICMDSTAT_CMDSENT) { + if (host->complete_what == COMPLETION_CMDSENT) { + host->status = "ok: command sent"; + goto close_transfer; + } + + mci_cclear |= S3C2410_SDICMDSTAT_CMDSENT; + } + + if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) { + if (cmd->flags & MMC_RSP_CRC) { + cmd->error = -EILSEQ; + host->status = "error: bad command crc"; + goto fail_transfer; + } + + mci_cclear |= S3C2410_SDICMDSTAT_CRCFAIL; + } + + if (mci_csta & S3C2410_SDICMDSTAT_RSPFIN) { + if (host->complete_what == COMPLETION_RSPFIN) { + host->status = "ok: command response received"; + goto close_transfer; + } + + if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN) + host->complete_what = COMPLETION_XFERFINISH; + + mci_cclear |= S3C2410_SDICMDSTAT_RSPFIN; + } + + /* errors handled after this point are only relevant + when a data transfer is in progress */ + + if (!cmd->data) + goto clear_status_bits; + + /* Check for FIFO failure */ + if (host->is2440) { + if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) { + host->mrq->data->error = -EILSEQ; + host->status = "error: 2440 fifo failure"; + goto fail_transfer; + } + } else { + if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) { + cmd->data->error = -EILSEQ; + host->status = "error: fifo failure"; + goto fail_transfer; + } + } + + if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) { + cmd->data->error = -EILSEQ; + host->status = "error: bad data crc (outgoing)"; + goto fail_transfer; + } + + if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) { + cmd->data->error = -EILSEQ; + host->status = "error: bad data crc (incoming)"; + goto fail_transfer; + } + + if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) { + cmd->data->error = -ETIMEDOUT; + host->status = "error: data timeout"; + goto fail_transfer; + } + + if (mci_dsta & S3C2410_SDIDSTA_XFERFINISH) { + if (host->complete_what == COMPLETION_XFERFINISH) { + host->status = "ok: data transfer completed"; + goto close_transfer; + } + + if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN) + host->complete_what = COMPLETION_RSPFIN; + + mci_dclear |= S3C2410_SDIDSTA_XFERFINISH; + } + +clear_status_bits: + writel(mci_cclear, host->base + S3C2410_SDICMDSTAT); + writel(mci_dclear, host->base + S3C2410_SDIDSTA); + + goto irq_out; + +fail_transfer: + host->pio_active = XFER_NONE; + +close_transfer: + host->complete_what = COMPLETION_FINALIZE; + + clear_imask(host); + tasklet_schedule(&host->pio_tasklet); + + goto irq_out; + +irq_out: + dbg(host, dbg_irq, + "csta:0x%08x dsta:0x%08x fsta:0x%08x dcnt:0x%08x status:%s.\n", + mci_csta, mci_dsta, mci_fsta, mci_dcnt, host->status); + + spin_unlock_irqrestore(&host->complete_lock, iflags); + return IRQ_HANDLED; + +} + +/* + * ISR for the CardDetect Pin +*/ + +static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id) +{ + struct s3cmci_host *host = (struct s3cmci_host *)dev_id; + + dbg(host, dbg_irq, "card detect\n"); + + mmc_detect_change(host->mmc, 500); + + return IRQ_HANDLED; +} + +void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch, void *buf_id, + int size, enum s3c2410_dma_buffresult result) +{ + struct s3cmci_host *host = buf_id; + unsigned long iflags; + u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt; + + mci_csta = readl(host->base + S3C2410_SDICMDSTAT); + mci_dsta = readl(host->base + S3C2410_SDIDSTA); + mci_fsta = readl(host->base + S3C2410_SDIFSTA); + mci_dcnt = readl(host->base + S3C2410_SDIDCNT); + + BUG_ON(!host->mrq); + BUG_ON(!host->mrq->data); + BUG_ON(!host->dmatogo); + + spin_lock_irqsave(&host->complete_lock, iflags); + + if (result != S3C2410_RES_OK) { + dbg(host, dbg_fail, "DMA FAILED: csta=0x%08x dsta=0x%08x " + "fsta=0x%08x dcnt:0x%08x result:0x%08x toGo:%u\n", + mci_csta, mci_dsta, mci_fsta, + mci_dcnt, result, host->dmatogo); + + goto fail_request; + } + + host->dmatogo--; + if (host->dmatogo) { + dbg(host, dbg_dma, "DMA DONE Size:%i DSTA:[%08x] " + "DCNT:[%08x] toGo:%u\n", + size, mci_dsta, mci_dcnt, host->dmatogo); + + goto out; + } + + dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n", + size, mci_dsta, mci_dcnt); + + host->complete_what = COMPLETION_FINALIZE; + +out: + tasklet_schedule(&host->pio_tasklet); + spin_unlock_irqrestore(&host->complete_lock, iflags); + return; + + +fail_request: + host->mrq->data->error = -EINVAL; + host->complete_what = COMPLETION_FINALIZE; + writel(0, host->base + host->sdiimsk); + goto out; + +} + +static void finalize_request(struct s3cmci_host *host) +{ + struct mmc_request *mrq = host->mrq; + struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; + int debug_as_failure = 0; + + if (host->complete_what != COMPLETION_FINALIZE) + return; + + if (!mrq) + return; + + if (cmd->data && (cmd->error == 0) && + (cmd->data->error == 0)) { + if (host->dodma && (!host->dma_complete)) { + dbg(host, dbg_dma, "DMA Missing!\n"); + return; + } + } + + /* Read response from controller. */ + cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0); + cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1); + cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2); + cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3); + + writel(host->prescaler, host->base + S3C2410_SDIPRE); + + if (cmd->error) + debug_as_failure = 1; + + if (cmd->data && cmd->data->error) + debug_as_failure = 1; + + dbg_dumpcmd(host, cmd, debug_as_failure); + + /* Cleanup controller */ + writel(0, host->base + S3C2410_SDICMDARG); + writel(0, host->base + S3C2410_SDIDCON); + writel(0, host->base + S3C2410_SDICMDCON); + writel(0, host->base + host->sdiimsk); + + if (cmd->data && cmd->error) + cmd->data->error = cmd->error; + + if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) { + host->cmd_is_stop = 1; + s3cmci_send_request(host->mmc); + return; + } + + /* If we have no data transfer we are finished here */ + if (!mrq->data) + goto request_done; + + /* Calulate the amout of bytes transfer if there was no error */ + if (mrq->data->error == 0) { + mrq->data->bytes_xfered = + (mrq->data->blocks * mrq->data->blksz); + } else { + mrq->data->bytes_xfered = 0; + } + + /* If we had an error while transfering data we flush the + * DMA channel and the fifo to clear out any garbage. */ + if (mrq->data->error != 0) { + if (host->dodma) + s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); + + if (host->is2440) { + /* Clear failure register and reset fifo. */ + writel(S3C2440_SDIFSTA_FIFORESET | + S3C2440_SDIFSTA_FIFOFAIL, + host->base + S3C2410_SDIFSTA); + } else { + u32 mci_con; + + /* reset fifo */ + mci_con = readl(host->base + S3C2410_SDICON); + mci_con |= S3C2410_SDICON_FIFORESET; + + writel(mci_con, host->base + S3C2410_SDICON); + } + } + +request_done: + host->complete_what = COMPLETION_NONE; + host->mrq = NULL; + mmc_request_done(host->mmc, mrq); +} + + +void s3cmci_dma_setup(struct s3cmci_host *host, enum s3c2410_dmasrc source) +{ + static enum s3c2410_dmasrc last_source = -1; + static int setup_ok; + + if (last_source == source) + return; + + last_source = source; + + s3c2410_dma_devconfig(host->dma, source, 3, + host->mem->start + host->sdidata); + + if (!setup_ok) { + s3c2410_dma_config(host->dma, 4, + (S3C2410_DCON_HWTRIG | S3C2410_DCON_CH0_SDI)); + s3c2410_dma_set_buffdone_fn(host->dma, + s3cmci_dma_done_callback); + s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART); + setup_ok = 1; + } +} + +static void s3cmci_send_command(struct s3cmci_host *host, + struct mmc_command *cmd) +{ + u32 ccon, imsk; + + imsk = S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_CMDTIMEOUT | + S3C2410_SDIIMSK_RESPONSEND | S3C2410_SDIIMSK_CMDSENT | + S3C2410_SDIIMSK_RESPONSECRC; + + enable_imask(host, imsk); + + if (cmd->data) + host->complete_what = COMPLETION_XFERFINISH_RSPFIN; + else if (cmd->flags & MMC_RSP_PRESENT) + host->complete_what = COMPLETION_RSPFIN; + else + host->complete_what = COMPLETION_CMDSENT; + + writel(cmd->arg, host->base + S3C2410_SDICMDARG); + + ccon = cmd->opcode & S3C2410_SDICMDCON_INDEX; + ccon |= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART; + + if (cmd->flags & MMC_RSP_PRESENT) + ccon |= S3C2410_SDICMDCON_WAITRSP; + + if (cmd->flags & MMC_RSP_136) + ccon |= S3C2410_SDICMDCON_LONGRSP; + + writel(ccon, host->base + S3C2410_SDICMDCON); +} + +static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data) +{ + u32 dcon, imsk, stoptries = 3; + + /* write DCON register */ + + if (!data) { + writel(0, host->base + S3C2410_SDIDCON); + return 0; + } + + while (readl(host->base + S3C2410_SDIDSTA) & + (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) { + + dbg(host, dbg_err, + "mci_setup_data() transfer stillin progress.\n"); + + writel(0, host->base + S3C2410_SDIDCON); + s3cmci_reset(host); + + if ((stoptries--) == 0) { + dbg_dumpregs(host, "DRF"); + return -EINVAL; + } + } + + dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK; + + if (host->dodma) + dcon |= S3C2410_SDIDCON_DMAEN; + + if (host->bus_width == MMC_BUS_WIDTH_4) + dcon |= S3C2410_SDIDCON_WIDEBUS; + + if (!(data->flags & MMC_DATA_STREAM)) + dcon |= S3C2410_SDIDCON_BLOCKMODE; + + if (data->flags & MMC_DATA_WRITE) { + dcon |= S3C2410_SDIDCON_TXAFTERRESP; + dcon |= S3C2410_SDIDCON_XFER_TXSTART; + } + + if (data->flags & MMC_DATA_READ) { + dcon |= S3C2410_SDIDCON_RXAFTERCMD; + dcon |= S3C2410_SDIDCON_XFER_RXSTART; + } + + if (host->is2440) { + dcon |= S3C2440_SDIDCON_DS_WORD; + dcon |= S3C2440_SDIDCON_DATSTART; + } + + writel(dcon, host->base + S3C2410_SDIDCON); + + /* write BSIZE register */ + + writel(data->blksz, host->base + S3C2410_SDIBSIZE); + + /* add to IMASK register */ + imsk = S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC | + S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH; + + enable_imask(host, imsk); + + /* write TIMER register */ + + if (host->is2440) { + writel(0x007FFFFF, host->base + S3C2410_SDITIMER); + } else { + writel(0x0000FFFF, host->base + S3C2410_SDITIMER); + + /* FIX: set slow clock to prevent timeouts on read */ + if (data->flags & MMC_DATA_READ) + writel(0xFF, host->base + S3C2410_SDIPRE); + } + + return 0; +} + +#define BOTH_DIR (MMC_DATA_WRITE | MMC_DATA_READ) + +static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data) +{ + int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0; + + BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); + + host->pio_sgptr = 0; + host->pio_words = 0; + host->pio_count = 0; + host->pio_active = rw ? XFER_WRITE : XFER_READ; + + if (rw) { + do_pio_write(host); + enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); + } else { + enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF + | S3C2410_SDIIMSK_RXFIFOLAST); + } + + return 0; +} + +static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data) +{ + int dma_len, i; + int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0; + + BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); + + s3cmci_dma_setup(host, rw ? S3C2410_DMASRC_MEM : S3C2410_DMASRC_HW); + s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); + + dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + (rw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + + if (dma_len == 0) + return -ENOMEM; + + host->dma_complete = 0; + host->dmatogo = dma_len; + + for (i = 0; i < dma_len; i++) { + int res; + + dbg(host, dbg_dma, "enqueue %i:%u@%u\n", i, + sg_dma_address(&data->sg[i]), + sg_dma_len(&data->sg[i])); + + res = s3c2410_dma_enqueue(host->dma, (void *) host, + sg_dma_address(&data->sg[i]), + sg_dma_len(&data->sg[i])); + + if (res) { + s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); + return -EBUSY; + } + } + + s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_START); + + return 0; +} + +static void s3cmci_send_request(struct mmc_host *mmc) +{ + struct s3cmci_host *host = mmc_priv(mmc); + struct mmc_request *mrq = host->mrq; + struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; + + host->ccnt++; + prepare_dbgmsg(host, cmd, host->cmd_is_stop); + + /* Clear command, data and fifo status registers + Fifo clear only necessary on 2440, but doesn't hurt on 2410 + */ + writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT); + writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA); + writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA); + + if (cmd->data) { + int res = s3cmci_setup_data(host, cmd->data); + + host->dcnt++; + + if (res) { + cmd->error = -EINVAL; + cmd->data->error = -EINVAL; + + mmc_request_done(mmc, mrq); + return; + } + + if (host->dodma) + res = s3cmci_prepare_dma(host, cmd->data); + else + res = s3cmci_prepare_pio(host, cmd->data); + + if (res) { + cmd->error = res; + cmd->data->error = res; + + mmc_request_done(mmc, mrq); + return; + } + } + + /* Send command */ + s3cmci_send_command(host, cmd); + + /* Enable Interrupt */ + enable_irq(host->irq); +} + +static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct s3cmci_host *host = mmc_priv(mmc); + + host->status = "mmc request"; + host->cmd_is_stop = 0; + host->mrq = mrq; + + s3cmci_send_request(mmc); +} + +static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct s3cmci_host *host = mmc_priv(mmc); + u32 mci_psc, mci_con; + + /* Set the power state */ + + mci_con = readl(host->base + S3C2410_SDICON); + + switch (ios->power_mode) { + case MMC_POWER_ON: + case MMC_POWER_UP: + s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD); + s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0); + s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1); + s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2); + s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3); + + if (!host->is2440) + mci_con |= S3C2410_SDICON_FIFORESET; + + break; + + case MMC_POWER_OFF: + default: + s3c2410_gpio_setpin(S3C2410_GPE5, 0); + s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP); + + if (host->is2440) + mci_con |= S3C2440_SDICON_SDRESET; + + break; + } + + /* Set clock */ + for (mci_psc = 0; mci_psc < 255; mci_psc++) { + host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1)); + + if (host->real_rate <= ios->clock) + break; + } + + if (mci_psc > 255) + mci_psc = 255; + + host->prescaler = mci_psc; + writel(host->prescaler, host->base + S3C2410_SDIPRE); + + /* If requested clock is 0, real_rate will be 0, too */ + if (ios->clock == 0) + host->real_rate = 0; + + /* Set CLOCK_ENABLE */ + if (ios->clock) + mci_con |= S3C2410_SDICON_CLOCKTYPE; + else + mci_con &= ~S3C2410_SDICON_CLOCKTYPE; + + writel(mci_con, host->base + S3C2410_SDICON); + + if ((ios->power_mode == MMC_POWER_ON) || + (ios->power_mode == MMC_POWER_UP)) { + dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n", + host->real_rate/1000, ios->clock/1000); + } else { + dbg(host, dbg_conf, "powered down.\n"); + } + + host->bus_width = ios->bus_width; +} + +static void s3cmci_reset(struct s3cmci_host *host) +{ + u32 con = readl(host->base + S3C2410_SDICON); + + con |= S3C2440_SDICON_SDRESET; + writel(con, host->base + S3C2410_SDICON); +} + +static struct mmc_host_ops s3cmci_ops = { + .request = s3cmci_request, + .set_ios = s3cmci_set_ios, +}; + +static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) +{ + struct s3cmci_host *host; + struct mmc_host *mmc; + int ret; + + mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev); + if (!mmc) { + ret = -ENOMEM; + goto probe_out; + } + + host = mmc_priv(mmc); + host->mmc = mmc; + host->pdev = pdev; + host->is2440 = is2440; + + spin_lock_init(&host->complete_lock); + tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); + + if (is2440) { + host->sdiimsk = S3C2440_SDIIMSK; + host->sdidata = S3C2440_SDIDATA; + host->clk_div = 1; + } else { + host->sdiimsk = S3C2410_SDIIMSK; + host->sdidata = S3C2410_SDIDATA; + host->clk_div = 2; + } + + host->dodma = 0; + host->complete_what = COMPLETION_NONE; + host->pio_active = XFER_NONE; + + host->dma = S3CMCI_DMA; + host->irq_cd = IRQ_EINT2; + + host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!host->mem) { + dev_err(&pdev->dev, + "failed to get io memory region resouce.\n"); + + ret = -ENOENT; + goto probe_free_host; + } + + host->mem = request_mem_region(host->mem->start, + RESSIZE(host->mem), pdev->name); + + if (!host->mem) { + dev_err(&pdev->dev, "failed to request io memory region.\n"); + ret = -ENOENT; + goto probe_free_host; + } + + host->base = ioremap(host->mem->start, RESSIZE(host->mem)); + if (host->base == 0) { + dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); + ret = -EINVAL; + goto probe_free_mem_region; + } + + host->irq = platform_get_irq(pdev, 0); + if (host->irq == 0) { + dev_err(&pdev->dev, "failed to get interrupt resouce.\n"); + ret = -EINVAL; + goto probe_iounmap; + } + + if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) { + dev_err(&pdev->dev, "failed to request mci interrupt.\n"); + ret = -ENOENT; + goto probe_iounmap; + } + + /* We get spurious interrupts even when we have set the IMSK + * register to ignore everything, so use disable_irq() to make + * ensure we don't lock the system with un-serviceable requests. */ + + disable_irq(host->irq); + + s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2); + set_irq_type(host->irq_cd, IRQT_BOTHEDGE); + + if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) { + dev_err(&pdev->dev, + "failed to request card detect interrupt.\n"); + ret = -ENOENT; + goto probe_free_irq; + } + + if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) { + dev_err(&pdev->dev, "unable to get DMA channel.\n"); + ret = -EBUSY; + goto probe_free_irq_cd; + } + + host->clk = clk_get(&pdev->dev, "sdi"); + if (IS_ERR(host->clk)) { + dev_err(&pdev->dev, "failed to find clock source.\n"); + ret = PTR_ERR(host->clk); + host->clk = NULL; + goto probe_free_host; + } + + ret = clk_enable(host->clk); + if (ret) { + dev_err(&pdev->dev, "failed to enable clock source.\n"); + goto clk_free; + } + + host->clk_rate = clk_get_rate(host->clk); + + mmc->ops = &s3cmci_ops; + mmc->ocr_avail = MMC_VDD_32_33; + mmc->caps = MMC_CAP_4_BIT_DATA; + mmc->f_min = host->clk_rate / (host->clk_div * 256); + mmc->f_max = host->clk_rate / host->clk_div; + + mmc->max_blk_count = 4095; + mmc->max_blk_size = 4095; + mmc->max_req_size = 4095 * 512; + mmc->max_seg_size = mmc->max_req_size; + + mmc->max_phys_segs = 128; + mmc->max_hw_segs = 128; + + dbg(host, dbg_debug, + "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%u.\n", + (host->is2440?"2440":""), + host->base, host->irq, host->irq_cd, host->dma); + + ret = mmc_add_host(mmc); + if (ret) { + dev_err(&pdev->dev, "failed to add mmc host.\n"); + goto free_dmabuf; + } + + platform_set_drvdata(pdev, mmc); + dev_info(&pdev->dev, "initialisation done.\n"); + + return 0; + + free_dmabuf: + clk_disable(host->clk); + + clk_free: + clk_put(host->clk); + + probe_free_irq_cd: + free_irq(host->irq_cd, host); + + probe_free_irq: + free_irq(host->irq, host); + + probe_iounmap: + iounmap(host->base); + + probe_free_mem_region: + release_mem_region(host->mem->start, RESSIZE(host->mem)); + + probe_free_host: + mmc_free_host(mmc); + probe_out: + return ret; +} + +static int __devexit s3cmci_remove(struct platform_device *pdev) +{ + struct mmc_host *mmc = platform_get_drvdata(pdev); + struct s3cmci_host *host = mmc_priv(mmc); + + mmc_remove_host(mmc); + + clk_disable(host->clk); + clk_put(host->clk); + + tasklet_disable(&host->pio_tasklet); + + free_irq(host->irq_cd, host); + free_irq(host->irq, host); + + iounmap(host->base); + release_mem_region(host->mem->start, RESSIZE(host->mem)); + + mmc_free_host(mmc); + return 0; +} + +static int __devinit s3cmci_probe_2410(struct platform_device *dev) +{ + return s3cmci_probe(dev, 0); +} + +static int __devinit s3cmci_probe_2412(struct platform_device *dev) +{ + return s3cmci_probe(dev, 1); +} + +static int __devinit s3cmci_probe_2440(struct platform_device *dev) +{ + return s3cmci_probe(dev, 1); +} + +#ifdef CONFIG_PM + +static int s3cmci_suspend(struct platform_device *dev, pm_message_t state) +{ + struct mmc_host *mmc = platform_get_drvdata(dev); + + return mmc_suspend_host(mmc, state); +} + +static int s3cmci_resume(struct platform_device *dev) +{ + struct mmc_host *mmc = platform_get_drvdata(dev); + + return mmc_resume_host(mmc); +} + +#else /* CONFIG_PM */ +#define s3cmci_suspend NULL +#define s3cmci_resume NULL +#endif /* CONFIG_PM */ + + +static struct platform_driver s3cmci_driver_2410 = { + .driver.name = "s3c2410-sdi", + .driver.owner = THIS_MODULE, + .probe = s3cmci_probe_2410, + .remove = __devexit_p(s3cmci_remove), + .suspend = s3cmci_suspend, + .resume = s3cmci_resume, +}; + +static struct platform_driver s3cmci_driver_2412 = { + .driver.name = "s3c2412-sdi", + .driver.owner = THIS_MODULE, + .probe = s3cmci_probe_2412, + .remove = __devexit_p(s3cmci_remove), + .suspend = s3cmci_suspend, + .resume = s3cmci_resume, +}; + +static struct platform_driver s3cmci_driver_2440 = { + .driver.name = "s3c2440-sdi", + .driver.owner = THIS_MODULE, + .probe = s3cmci_probe_2440, + .remove = __devexit_p(s3cmci_remove), + .suspend = s3cmci_suspend, + .resume = s3cmci_resume, +}; + + +static int __init s3cmci_init(void) +{ + platform_driver_register(&s3cmci_driver_2410); + platform_driver_register(&s3cmci_driver_2412); + platform_driver_register(&s3cmci_driver_2440); + return 0; +} + +static void __exit s3cmci_exit(void) +{ + platform_driver_unregister(&s3cmci_driver_2410); + platform_driver_unregister(&s3cmci_driver_2412); + platform_driver_unregister(&s3cmci_driver_2440); +} + +module_init(s3cmci_init); +module_exit(s3cmci_exit); + +MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Thomas Kleffel "); diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h new file mode 100644 index 00000000000..90b8af7d8a4 --- /dev/null +++ b/drivers/mmc/host/s3cmci.h @@ -0,0 +1,69 @@ +/* + * linux/drivers/mmc/s3cmci.h - Samsung S3C MCI driver + * + * Copyright (C) 2004-2006 Thomas Kleffel, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* FIXME: DMA Resource management ?! */ +#define S3CMCI_DMA 0 + +enum s3cmci_waitfor { + COMPLETION_NONE, + COMPLETION_FINALIZE, + COMPLETION_CMDSENT, + COMPLETION_RSPFIN, + COMPLETION_XFERFINISH, + COMPLETION_XFERFINISH_RSPFIN, +}; + +struct s3cmci_host { + struct platform_device *pdev; + struct mmc_host *mmc; + struct resource *mem; + struct clk *clk; + void __iomem *base; + int irq; + int irq_cd; + int dma; + + unsigned long clk_rate; + unsigned long clk_div; + unsigned long real_rate; + u8 prescaler; + + int is2440; + unsigned sdiimsk; + unsigned sdidata; + int dodma; + int dmatogo; + + struct mmc_request *mrq; + int cmd_is_stop; + + spinlock_t complete_lock; + enum s3cmci_waitfor complete_what; + + int dma_complete; + + u32 pio_sgptr; + u32 pio_words; + u32 pio_count; + u32 *pio_ptr; +#define XFER_NONE 0 +#define XFER_READ 1 +#define XFER_WRITE 2 + u32 pio_active; + + int bus_width; + + char dbgmsg_cmd[301]; + char dbgmsg_dat[301]; + char *status; + + unsigned int ccnt, dcnt; + struct tasklet_struct pio_tasklet; +}; diff --git a/include/asm-arm/arch-s3c2410/regs-sdi.h b/include/asm-arm/arch-s3c2410/regs-sdi.h index bb9d30b7295..bfb222fa4ab 100644 --- a/include/asm-arm/arch-s3c2410/regs-sdi.h +++ b/include/asm-arm/arch-s3c2410/regs-sdi.h @@ -28,9 +28,15 @@ #define S3C2410_SDIDCNT (0x30) #define S3C2410_SDIDSTA (0x34) #define S3C2410_SDIFSTA (0x38) + #define S3C2410_SDIDATA (0x3C) #define S3C2410_SDIIMSK (0x40) +#define S3C2440_SDIDATA (0x40) +#define S3C2440_SDIIMSK (0x3C) + +#define S3C2440_SDICON_SDRESET (1<<8) +#define S3C2440_SDICON_MMCCLOCK (1<<5) #define S3C2410_SDICON_BYTEORDER (1<<4) #define S3C2410_SDICON_SDIOIRQ (1<<3) #define S3C2410_SDICON_RWAITEN (1<<2) @@ -42,7 +48,8 @@ #define S3C2410_SDICMDCON_LONGRSP (1<<10) #define S3C2410_SDICMDCON_WAITRSP (1<<9) #define S3C2410_SDICMDCON_CMDSTART (1<<8) -#define S3C2410_SDICMDCON_INDEX (0xff) +#define S3C2410_SDICMDCON_SENDERHOST (1<<6) +#define S3C2410_SDICMDCON_INDEX (0x3f) #define S3C2410_SDICMDSTAT_CRCFAIL (1<<12) #define S3C2410_SDICMDSTAT_CMDSENT (1<<11) @@ -51,6 +58,9 @@ #define S3C2410_SDICMDSTAT_XFERING (1<<8) #define S3C2410_SDICMDSTAT_INDEX (0xff) +#define S3C2440_SDIDCON_DS_BYTE (0<<22) +#define S3C2440_SDIDCON_DS_HALFWORD (1<<22) +#define S3C2440_SDIDCON_DS_WORD (2<<22) #define S3C2410_SDIDCON_IRQPERIOD (1<<21) #define S3C2410_SDIDCON_TXAFTERRESP (1<<20) #define S3C2410_SDIDCON_RXAFTERCMD (1<<19) @@ -59,6 +69,7 @@ #define S3C2410_SDIDCON_WIDEBUS (1<<16) #define S3C2410_SDIDCON_DMAEN (1<<15) #define S3C2410_SDIDCON_STOP (1<<14) +#define S3C2440_SDIDCON_DATSTART (1<<14) #define S3C2410_SDIDCON_DATMODE (3<<12) #define S3C2410_SDIDCON_BLKNUM (0x7ff) @@ -68,6 +79,7 @@ #define S3C2410_SDIDCON_XFER_RXSTART (2<<12) #define S3C2410_SDIDCON_XFER_TXSTART (3<<12) +#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF) #define S3C2410_SDIDCNT_BLKNUM_SHIFT (12) #define S3C2410_SDIDSTA_RDYWAITREQ (1<<10) @@ -82,10 +94,12 @@ #define S3C2410_SDIDSTA_TXDATAON (1<<1) #define S3C2410_SDIDSTA_RXDATAON (1<<0) +#define S3C2440_SDIFSTA_FIFORESET (1<<16) +#define S3C2440_SDIFSTA_FIFOFAIL (3<<14) /* 3 is correct (2 bits) */ #define S3C2410_SDIFSTA_TFDET (1<<13) #define S3C2410_SDIFSTA_RFDET (1<<12) -#define S3C2410_SDIFSTA_TXHALF (1<<11) -#define S3C2410_SDIFSTA_TXEMPTY (1<<10) +#define S3C2410_SDIFSTA_TFHALF (1<<11) +#define S3C2410_SDIFSTA_TFEMPTY (1<<10) #define S3C2410_SDIFSTA_RFLAST (1<<9) #define S3C2410_SDIFSTA_RFFULL (1<<8) #define S3C2410_SDIFSTA_RFHALF (1<<7) -- cgit v1.2.3-70-g09d2 From edb5a98e43682d66c98ddd1dee863d867807546e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:29 +0100 Subject: MMC: S3C24XX: Add platform data for MMC/SD driver This patch adds platform data support to the s3mci driver. This allows flexible board-specific configuration of set_power, card detect and read only pins. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman --- drivers/mmc/host/s3cmci.c | 44 +++++++++++++++++++++++++++++++++++--- drivers/mmc/host/s3cmci.h | 1 + include/asm-arm/plat-s3c24xx/mci.h | 12 +++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 include/asm-arm/plat-s3c24xx/mci.h (limited to 'include/asm-arm') diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 774af3d7218..684a10ca2e8 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -21,6 +21,8 @@ #include #include +#include + #include "s3cmci.h" #define DRIVER_NAME "s3c-mci" @@ -1011,6 +1013,9 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2); s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3); + if (host->pdata->set_power) + host->pdata->set_power(ios->power_mode, ios->vdd); + if (!host->is2440) mci_con |= S3C2410_SDICON_FIFORESET; @@ -1024,6 +1029,9 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->is2440) mci_con |= S3C2440_SDICON_SDRESET; + if (host->pdata->set_power) + host->pdata->set_power(ios->power_mode, ios->vdd); + break; } @@ -1072,9 +1080,25 @@ static void s3cmci_reset(struct s3cmci_host *host) writel(con, host->base + S3C2410_SDICON); } +static int s3cmci_get_ro(struct mmc_host *mmc) +{ + struct s3cmci_host *host = mmc_priv(mmc); + + if (host->pdata->gpio_wprotect == 0) + return 0; + + return s3c2410_gpio_getpin(host->pdata->gpio_wprotect); +} + static struct mmc_host_ops s3cmci_ops = { .request = s3cmci_request, .set_ios = s3cmci_set_ios, + .get_ro = s3cmci_get_ro, +}; + +static struct s3c24xx_mci_pdata s3cmci_def_pdata = { + /* This is currently here to avoid a number of if (host->pdata) + * checks. Any zero fields to ensure reaonable defaults are picked. */ }; static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) @@ -1094,6 +1118,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) host->pdev = pdev; host->is2440 = is2440; + host->pdata = pdev->dev.platform_data; + if (!host->pdata) { + pdev->dev.platform_data = &s3cmci_def_pdata; + host->pdata = &s3cmci_def_pdata; + } + spin_lock_init(&host->complete_lock); tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); @@ -1112,7 +1142,8 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) host->pio_active = XFER_NONE; host->dma = S3CMCI_DMA; - host->irq_cd = IRQ_EINT2; + host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); + s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!host->mem) { @@ -1158,7 +1189,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) disable_irq(host->irq); - s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2); + s3c2410_gpio_cfgpin(host->pdata->gpio_detect, S3C2410_GPIO_IRQ); set_irq_type(host->irq_cd, IRQT_BOTHEDGE); if (request_irq(host->irq_cd, s3cmci_irq_cd, 0, DRIVER_NAME, host)) { @@ -1168,6 +1199,10 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) goto probe_free_irq; } + if (host->pdata->gpio_wprotect) + s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect, + S3C2410_GPIO_INPUT); + if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) { dev_err(&pdev->dev, "unable to get DMA channel.\n"); ret = -EBUSY; @@ -1191,11 +1226,14 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) host->clk_rate = clk_get_rate(host->clk); mmc->ops = &s3cmci_ops; - mmc->ocr_avail = MMC_VDD_32_33; + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->caps = MMC_CAP_4_BIT_DATA; mmc->f_min = host->clk_rate / (host->clk_div * 256); mmc->f_max = host->clk_rate / host->clk_div; + if (host->pdata->ocr_avail) + mmc->ocr_avail = host->pdata->ocr_avail; + mmc->max_blk_count = 4095; mmc->max_blk_size = 4095; mmc->max_req_size = 4095 * 512; diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h index 90b8af7d8a4..37d9c60010c 100644 --- a/drivers/mmc/host/s3cmci.h +++ b/drivers/mmc/host/s3cmci.h @@ -22,6 +22,7 @@ enum s3cmci_waitfor { struct s3cmci_host { struct platform_device *pdev; + struct s3c24xx_mci_pdata *pdata; struct mmc_host *mmc; struct resource *mem; struct clk *clk; diff --git a/include/asm-arm/plat-s3c24xx/mci.h b/include/asm-arm/plat-s3c24xx/mci.h new file mode 100644 index 00000000000..5be2c1449c6 --- /dev/null +++ b/include/asm-arm/plat-s3c24xx/mci.h @@ -0,0 +1,12 @@ +#ifndef _ARCH_MCI_H +#define _ARCH_MCI_H + +struct s3c24xx_mci_pdata { + unsigned int gpio_detect; + unsigned int gpio_wprotect; + unsigned long ocr_avail; + void (*set_power)(unsigned char power_mode, + unsigned short vdd); +}; + +#endif /* _ARCH_NCI_H */ -- cgit v1.2.3-70-g09d2 From cf0984c8edf63017fcc2ead212ca057877e345df Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:30 +0100 Subject: MMC: S3C24XX: Add support to invert write protect line Support for inverting the sense of the MMC driver's write protect detection line. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman --- drivers/mmc/host/s3cmci.c | 11 +++++++++-- include/asm-arm/plat-s3c24xx/mci.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'include/asm-arm') diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 684a10ca2e8..4fd11d8864e 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1083,11 +1083,18 @@ static void s3cmci_reset(struct s3cmci_host *host) static int s3cmci_get_ro(struct mmc_host *mmc) { struct s3cmci_host *host = mmc_priv(mmc); + struct s3c24xx_mci_pdata *pdata = host->pdata; + int ret; - if (host->pdata->gpio_wprotect == 0) + if (pdata->gpio_wprotect == 0) return 0; - return s3c2410_gpio_getpin(host->pdata->gpio_wprotect); + ret = s3c2410_gpio_getpin(pdata->gpio_wprotect); + + if (pdata->wprotect_invert) + ret = !ret; + + return ret; } static struct mmc_host_ops s3cmci_ops = { diff --git a/include/asm-arm/plat-s3c24xx/mci.h b/include/asm-arm/plat-s3c24xx/mci.h index 5be2c1449c6..4f4ccd18f0c 100644 --- a/include/asm-arm/plat-s3c24xx/mci.h +++ b/include/asm-arm/plat-s3c24xx/mci.h @@ -2,6 +2,8 @@ #define _ARCH_MCI_H struct s3c24xx_mci_pdata { + unsigned int wprotect_invert : 1; + unsigned int gpio_detect; unsigned int gpio_wprotect; unsigned long ocr_avail; -- cgit v1.2.3-70-g09d2 From 50a845700b3b55f825b0eb901b03d6091f66d9f4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Jun 2008 22:40:36 +0100 Subject: MMC: S3C24XX: Add media presence test to request handling. Ensure that we have physical media present before attempting to send a request to a card. This ensures that we do not get flooded by errors from commands that can never be completed timing out. Signed-off-by: Ben Dooks Signed-off-by: Pierre Ossman --- drivers/mmc/host/s3cmci.c | 19 ++++++++++++++++++- include/asm-arm/plat-s3c24xx/mci.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 6f1b474e33b..62d73d3497f 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -984,6 +984,18 @@ static void s3cmci_send_request(struct mmc_host *mmc) enable_irq(host->irq); } +static int s3cmci_card_present(struct s3cmci_host *host) +{ + struct s3c24xx_mci_pdata *pdata = host->pdata; + int ret; + + if (pdata->gpio_detect == 0) + return -ENOSYS; + + ret = s3c2410_gpio_getpin(pdata->gpio_detect) ? 0 : 1; + return ret ^ pdata->detect_invert; +} + static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct s3cmci_host *host = mmc_priv(mmc); @@ -992,7 +1004,12 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->cmd_is_stop = 0; host->mrq = mrq; - s3cmci_send_request(mmc); + if (s3cmci_card_present(host) == 0) { + dbg(host, dbg_err, "%s: no medium present\n", __func__); + host->mrq->cmd->error = -ENOMEDIUM; + mmc_request_done(mmc, mrq); + } else + s3cmci_send_request(mmc); } static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) diff --git a/include/asm-arm/plat-s3c24xx/mci.h b/include/asm-arm/plat-s3c24xx/mci.h index 4f4ccd18f0c..2d0852ac3b2 100644 --- a/include/asm-arm/plat-s3c24xx/mci.h +++ b/include/asm-arm/plat-s3c24xx/mci.h @@ -3,6 +3,7 @@ struct s3c24xx_mci_pdata { unsigned int wprotect_invert : 1; + unsigned int detect_invert : 1; /* set => detect active high. */ unsigned int gpio_detect; unsigned int gpio_wprotect; -- cgit v1.2.3-70-g09d2 From 2a46fa13d788364c093c4296fe01cae837aa8919 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 17 Jul 2008 17:59:56 -0700 Subject: iop_adma: cleanup iop_chan_xor_slot_count - use a table for iop13xx, trade text for data - shrink the iop3xx to a cache line Signed-off-by: Dan Williams --- include/asm-arm/arch-iop13xx/adma.h | 18 +++++++----------- include/asm-arm/hardware/iop3xx-adma.h | 4 ++-- 2 files changed, 9 insertions(+), 13 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-iop13xx/adma.h b/include/asm-arm/arch-iop13xx/adma.h index 90d14ee564f..ef4f5da2029 100644 --- a/include/asm-arm/arch-iop13xx/adma.h +++ b/include/asm-arm/arch-iop13xx/adma.h @@ -198,17 +198,13 @@ iop_chan_memset_slot_count(size_t len, int *slots_per_op) static inline int iop_chan_xor_slot_count(size_t len, int src_cnt, int *slots_per_op) { - int num_slots; - /* slots_to_find = 1 for basic descriptor + 1 per 4 sources above 1 - * (1 source => 8 bytes) (1 slot => 32 bytes) - */ - num_slots = 1 + (((src_cnt - 1) << 3) >> 5); - if (((src_cnt - 1) << 3) & 0x1f) - num_slots++; - - *slots_per_op = num_slots; - - return num_slots; + static const char slot_count_table[] = { 1, 2, 2, 2, + 2, 3, 3, 3, + 3, 4, 4, 4, + 4, 5, 5, 5, + }; + *slots_per_op = slot_count_table[src_cnt - 1]; + return *slots_per_op; } #define ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024) diff --git a/include/asm-arm/hardware/iop3xx-adma.h b/include/asm-arm/hardware/iop3xx-adma.h index a32b86ac62a..af64676650a 100644 --- a/include/asm-arm/hardware/iop3xx-adma.h +++ b/include/asm-arm/hardware/iop3xx-adma.h @@ -260,7 +260,7 @@ static inline int iop_chan_memset_slot_count(size_t len, int *slots_per_op) static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt, int *slots_per_op) { - static const int slot_count_table[] = { 0, + static const char slot_count_table[] = { 1, 1, 1, 1, /* 01 - 04 */ 2, 2, 2, 2, /* 05 - 08 */ 4, 4, 4, 4, /* 09 - 12 */ @@ -270,7 +270,7 @@ static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt, 8, 8, 8, 8, /* 25 - 28 */ 8, 8, 8, 8, /* 29 - 32 */ }; - *slots_per_op = slot_count_table[src_cnt]; + *slots_per_op = slot_count_table[src_cnt - 1]; return *slots_per_op; } -- cgit v1.2.3-70-g09d2 From 1fe532685a1984dc9f2603ed20bd5e630ba79709 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 18 Jul 2008 13:30:14 +0400 Subject: ARM: support generic per-device coherent dma mem Signed-off-by: Dmitry Baryshkov Cc: Jesse Barnes Cc: Russell King Signed-off-by: Ingo Molnar --- arch/arm/Kconfig | 1 + arch/arm/mm/consistent.c | 8 ++++++++ include/asm-arm/dma-mapping.h | 2 ++ 3 files changed, 11 insertions(+) (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c7ad324ddf2..ea8b9be02b6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -16,6 +16,7 @@ config ARM select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_FTRACE if (!XIP_KERNEL) select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE) + select HAVE_GENERIC_DMA_COHERENT help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 333a82a3717..db7b3e38ef1 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -274,6 +274,11 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) { + void *memory; + + if (dma_alloc_from_coherent(dev, size, handle, &memory)) + return memory; + if (arch_is_coherent()) { void *virt; @@ -362,6 +367,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr WARN_ON(irqs_disabled()); + if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) + return; + if (arch_is_coherent()) { kfree(cpu_addr); return; diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h index e99406a7bec..943f23bc99a 100644 --- a/include/asm-arm/dma-mapping.h +++ b/include/asm-arm/dma-mapping.h @@ -7,6 +7,8 @@ #include +#include + /* * DMA-consistent mapping functions. These allocate/free a region of * uncached, unwrite-buffered mapped memory space for use with DMA -- cgit v1.2.3-70-g09d2 From 5cbad0ebf45c5417104b383dc0e34f64fa7f2473 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Wed, 20 Feb 2008 13:33:40 -0600 Subject: kgdb: support for ARCH=arm This patch adds the ARCH=arm specific a kgdb backend, originally written by Deepak Saxena and George Davis . Geoff Levand , Nicolas Pitre, Manish Lachwani, and Jason Wessel have contributed various fixups here as well. The KGDB patch makes one change to the core ARM architecture such that the traps are initialized early for use with the debugger or other subsystems. [ mingo@elte.hu: small cleanups. ] [ ben-linux@fluff.org: fixed early_trap_init ] Signed-off-by: Jason Wessel Acked-by: Deepak Saxena --- arch/arm/Kconfig | 1 + arch/arm/kernel/Makefile | 1 + arch/arm/kernel/kgdb.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/setup.c | 2 + arch/arm/kernel/traps.c | 5 ++ include/asm-arm/kgdb.h | 104 ++++++++++++++++++++++++ include/asm-arm/traps.h | 2 + 7 files changed, 316 insertions(+) create mode 100644 arch/arm/kernel/kgdb.c create mode 100644 include/asm-arm/kgdb.h (limited to 'include/asm-arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c7ad324ddf2..d048f6887d0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -12,6 +12,7 @@ config ARM select RTC_LIB select SYS_SUPPORTS_APM_EMULATION select HAVE_OPROFILE + select HAVE_ARCH_KGDB select HAVE_KPROBES if (!XIP_KERNEL) select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_FTRACE if (!XIP_KERNEL) diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index eb9092ca800..1d296fc8494 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o obj-$(CONFIG_ATAGS_PROC) += atags.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o +obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c new file mode 100644 index 00000000000..aaffaecffcd --- /dev/null +++ b/arch/arm/kernel/kgdb.c @@ -0,0 +1,201 @@ +/* + * arch/arm/kernel/kgdb.c + * + * ARM KGDB support + * + * Copyright (c) 2002-2004 MontaVista Software, Inc + * Copyright (c) 2008 Wind River Systems, Inc. + * + * Authors: George Davis + * Deepak Saxena + */ +#include +#include + +/* Make a local copy of the registers passed into the handler (bletch) */ +void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs) +{ + int regno; + + /* Initialize all to zero. */ + for (regno = 0; regno < GDB_MAX_REGS; regno++) + gdb_regs[regno] = 0; + + gdb_regs[_R0] = kernel_regs->ARM_r0; + gdb_regs[_R1] = kernel_regs->ARM_r1; + gdb_regs[_R2] = kernel_regs->ARM_r2; + gdb_regs[_R3] = kernel_regs->ARM_r3; + gdb_regs[_R4] = kernel_regs->ARM_r4; + gdb_regs[_R5] = kernel_regs->ARM_r5; + gdb_regs[_R6] = kernel_regs->ARM_r6; + gdb_regs[_R7] = kernel_regs->ARM_r7; + gdb_regs[_R8] = kernel_regs->ARM_r8; + gdb_regs[_R9] = kernel_regs->ARM_r9; + gdb_regs[_R10] = kernel_regs->ARM_r10; + gdb_regs[_FP] = kernel_regs->ARM_fp; + gdb_regs[_IP] = kernel_regs->ARM_ip; + gdb_regs[_SPT] = kernel_regs->ARM_sp; + gdb_regs[_LR] = kernel_regs->ARM_lr; + gdb_regs[_PC] = kernel_regs->ARM_pc; + gdb_regs[_CPSR] = kernel_regs->ARM_cpsr; +} + +/* Copy local gdb registers back to kgdb regs, for later copy to kernel */ +void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs) +{ + kernel_regs->ARM_r0 = gdb_regs[_R0]; + kernel_regs->ARM_r1 = gdb_regs[_R1]; + kernel_regs->ARM_r2 = gdb_regs[_R2]; + kernel_regs->ARM_r3 = gdb_regs[_R3]; + kernel_regs->ARM_r4 = gdb_regs[_R4]; + kernel_regs->ARM_r5 = gdb_regs[_R5]; + kernel_regs->ARM_r6 = gdb_regs[_R6]; + kernel_regs->ARM_r7 = gdb_regs[_R7]; + kernel_regs->ARM_r8 = gdb_regs[_R8]; + kernel_regs->ARM_r9 = gdb_regs[_R9]; + kernel_regs->ARM_r10 = gdb_regs[_R10]; + kernel_regs->ARM_fp = gdb_regs[_FP]; + kernel_regs->ARM_ip = gdb_regs[_IP]; + kernel_regs->ARM_sp = gdb_regs[_SPT]; + kernel_regs->ARM_lr = gdb_regs[_LR]; + kernel_regs->ARM_pc = gdb_regs[_PC]; + kernel_regs->ARM_cpsr = gdb_regs[_CPSR]; +} + +void +sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) +{ + struct pt_regs *thread_regs; + int regno; + + /* Just making sure... */ + if (task == NULL) + return; + + /* Initialize to zero */ + for (regno = 0; regno < GDB_MAX_REGS; regno++) + gdb_regs[regno] = 0; + + /* Otherwise, we have only some registers from switch_to() */ + thread_regs = task_pt_regs(task); + gdb_regs[_R0] = thread_regs->ARM_r0; + gdb_regs[_R1] = thread_regs->ARM_r1; + gdb_regs[_R2] = thread_regs->ARM_r2; + gdb_regs[_R3] = thread_regs->ARM_r3; + gdb_regs[_R4] = thread_regs->ARM_r4; + gdb_regs[_R5] = thread_regs->ARM_r5; + gdb_regs[_R6] = thread_regs->ARM_r6; + gdb_regs[_R7] = thread_regs->ARM_r7; + gdb_regs[_R8] = thread_regs->ARM_r8; + gdb_regs[_R9] = thread_regs->ARM_r9; + gdb_regs[_R10] = thread_regs->ARM_r10; + gdb_regs[_FP] = thread_regs->ARM_fp; + gdb_regs[_IP] = thread_regs->ARM_ip; + gdb_regs[_SPT] = thread_regs->ARM_sp; + gdb_regs[_LR] = thread_regs->ARM_lr; + gdb_regs[_PC] = thread_regs->ARM_pc; + gdb_regs[_CPSR] = thread_regs->ARM_cpsr; +} + +static int compiled_break; + +int kgdb_arch_handle_exception(int exception_vector, int signo, + int err_code, char *remcom_in_buffer, + char *remcom_out_buffer, + struct pt_regs *linux_regs) +{ + unsigned long addr; + char *ptr; + + switch (remcom_in_buffer[0]) { + case 'D': + case 'k': + case 'c': + kgdb_contthread = NULL; + + /* + * Try to read optional parameter, pc unchanged if no parm. + * If this was a compiled breakpoint, we need to move + * to the next instruction or we will just breakpoint + * over and over again. + */ + ptr = &remcom_in_buffer[1]; + if (kgdb_hex2long(&ptr, &addr)) + linux_regs->ARM_pc = addr; + else if (compiled_break == 1) + linux_regs->ARM_pc += 4; + + compiled_break = 0; + + return 0; + } + + return -1; +} + +static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr) +{ + kgdb_handle_exception(1, SIGTRAP, 0, regs); + + return 0; +} + +static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr) +{ + compiled_break = 1; + kgdb_handle_exception(1, SIGTRAP, 0, regs); + + return 0; +} + +static struct undef_hook kgdb_brkpt_hook = { + .instr_mask = 0xffffffff, + .instr_val = KGDB_BREAKINST, + .fn = kgdb_brk_fn +}; + +static struct undef_hook kgdb_compiled_brkpt_hook = { + .instr_mask = 0xffffffff, + .instr_val = KGDB_COMPILED_BREAK, + .fn = kgdb_compiled_brk_fn +}; + +/** + * kgdb_arch_init - Perform any architecture specific initalization. + * + * This function will handle the initalization of any architecture + * specific callbacks. + */ +int kgdb_arch_init(void) +{ + register_undef_hook(&kgdb_brkpt_hook); + register_undef_hook(&kgdb_compiled_brkpt_hook); + + return 0; +} + +/** + * kgdb_arch_exit - Perform any architecture specific uninitalization. + * + * This function will handle the uninitalization of any architecture + * specific callbacks, for dynamic registration and unregistration. + */ +void kgdb_arch_exit(void) +{ + unregister_undef_hook(&kgdb_brkpt_hook); + unregister_undef_hook(&kgdb_compiled_brkpt_hook); +} + +/* + * Register our undef instruction hooks with ARM undef core. + * We regsiter a hook specifically looking for the KGB break inst + * and we handle the normal undef case within the do_undefinstr + * handler. + */ +struct kgdb_arch arch_kgdb_ops = { +#ifndef __ARMEB__ + .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7} +#else /* ! __ARMEB__ */ + .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe} +#endif +}; diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b7b0720bc1b..38f0e7940a1 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "compat.h" #include "atags.h" @@ -853,6 +854,7 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif #endif + early_trap_init(); } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 5595fdd75e8..7277aef8309 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -707,6 +707,11 @@ void abort(void) EXPORT_SYMBOL(abort); void __init trap_init(void) +{ + return; +} + +void __init early_trap_init(void) { unsigned long vectors = CONFIG_VECTORS_BASE; extern char __stubs_start[], __stubs_end[]; diff --git a/include/asm-arm/kgdb.h b/include/asm-arm/kgdb.h new file mode 100644 index 00000000000..67af4b84198 --- /dev/null +++ b/include/asm-arm/kgdb.h @@ -0,0 +1,104 @@ +/* + * ARM KGDB support + * + * Author: Deepak Saxena + * + * Copyright (C) 2002 MontaVista Software Inc. + * + */ + +#ifndef __ARM_KGDB_H__ +#define __ARM_KGDB_H__ + +#include + +/* + * GDB assumes that we're a user process being debugged, so + * it will send us an SWI command to write into memory as the + * debug trap. When an SWI occurs, the next instruction addr is + * placed into R14_svc before jumping to the vector trap. + * This doesn't work for kernel debugging as we are already in SVC + * we would loose the kernel's LR, which is a bad thing. This + * is bad thing. + * + * By doing this as an undefined instruction trap, we force a mode + * switch from SVC to UND mode, allowing us to save full kernel state. + * + * We also define a KGDB_COMPILED_BREAK which can be used to compile + * in breakpoints. This is important for things like sysrq-G and for + * the initial breakpoint from trap_init(). + * + * Note to ARM HW designers: Add real trap support like SH && PPC to + * make our lives much much simpler. :) + */ +#define BREAK_INSTR_SIZE 4 +#define GDB_BREAKINST 0xef9f0001 +#define KGDB_BREAKINST 0xe7ffdefe +#define KGDB_COMPILED_BREAK 0xe7ffdeff +#define CACHE_FLUSH_IS_SAFE 1 + +#ifndef __ASSEMBLY__ + +static inline void arch_kgdb_breakpoint(void) +{ + asm(".word 0xe7ffdeff"); +} + +extern void kgdb_handle_bus_error(void); +extern int kgdb_fault_expected; + +#endif /* !__ASSEMBLY__ */ + +/* + * From Kevin Hilman: + * + * gdb is expecting the following registers layout. + * + * r0-r15: 1 long word each + * f0-f7: unused, 3 long words each !! + * fps: unused, 1 long word + * cpsr: 1 long word + * + * Even though f0-f7 and fps are not used, they need to be + * present in the registers sent for correct processing in + * the host-side gdb. + * + * In particular, it is crucial that CPSR is in the right place, + * otherwise gdb will not be able to correctly interpret stepping over + * conditional branches. + */ +#define _GP_REGS 16 +#define _FP_REGS 8 +#define _EXTRA_REGS 2 +#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) + +#define KGDB_MAX_NO_CPUS 1 +#define BUFMAX 400 +#define NUMREGBYTES (GDB_MAX_REGS << 2) +#define NUMCRITREGBYTES (32 << 2) + +#define _R0 0 +#define _R1 1 +#define _R2 2 +#define _R3 3 +#define _R4 4 +#define _R5 5 +#define _R6 6 +#define _R7 7 +#define _R8 8 +#define _R9 9 +#define _R10 10 +#define _FP 11 +#define _IP 12 +#define _SPT 13 +#define _LR 14 +#define _PC 15 +#define _CPSR (GDB_MAX_REGS - 1) + +/* + * So that we can denote the end of a frame for tracing, + * in the simple case: + */ +#define CFI_END_FRAME(func) __CFI_END_FRAME(_PC, _SPT, func) + +#endif /* __ASM_KGDB_H__ */ diff --git a/include/asm-arm/traps.h b/include/asm-arm/traps.h index f1541afcf85..aa399aec568 100644 --- a/include/asm-arm/traps.h +++ b/include/asm-arm/traps.h @@ -24,4 +24,6 @@ static inline int in_exception_text(unsigned long ptr) ptr < (unsigned long)&__exception_text_end; } +extern void __init early_trap_init(void); + #endif -- cgit v1.2.3-70-g09d2 From 2351ec533ed0dd56052ab96988d2161d5ecc8ed9 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 24 Jul 2008 08:09:32 -0400 Subject: Remove asm/semaphore.h All users have now been converted to linux/semaphore.h and we don't need to keep these files around any longer. Signed-off-by: Matthew Wilcox --- Documentation/feature-removal-schedule.txt | 8 -------- include/asm-alpha/semaphore.h | 1 - include/asm-arm/semaphore.h | 1 - include/asm-avr32/semaphore.h | 1 - include/asm-blackfin/semaphore.h | 1 - include/asm-cris/semaphore.h | 1 - include/asm-frv/semaphore.h | 1 - include/asm-h8300/semaphore.h | 1 - include/asm-ia64/semaphore.h | 1 - include/asm-m32r/semaphore.h | 1 - include/asm-m68k/semaphore.h | 1 - include/asm-m68knommu/semaphore.h | 1 - include/asm-mips/semaphore.h | 1 - include/asm-mn10300/semaphore.h | 1 - include/asm-parisc/semaphore.h | 1 - include/asm-powerpc/semaphore.h | 1 - include/asm-s390/semaphore.h | 1 - include/asm-sh/semaphore.h | 1 - include/asm-sparc/semaphore.h | 1 - include/asm-sparc64/semaphore.h | 1 - include/asm-um/semaphore.h | 1 - include/asm-v850/semaphore.h | 1 - include/asm-x86/semaphore.h | 1 - include/asm-xtensa/semaphore.h | 1 - 24 files changed, 31 deletions(-) delete mode 100644 include/asm-alpha/semaphore.h delete mode 100644 include/asm-arm/semaphore.h delete mode 100644 include/asm-avr32/semaphore.h delete mode 100644 include/asm-blackfin/semaphore.h delete mode 100644 include/asm-cris/semaphore.h delete mode 100644 include/asm-frv/semaphore.h delete mode 100644 include/asm-h8300/semaphore.h delete mode 100644 include/asm-ia64/semaphore.h delete mode 100644 include/asm-m32r/semaphore.h delete mode 100644 include/asm-m68k/semaphore.h delete mode 100644 include/asm-m68knommu/semaphore.h delete mode 100644 include/asm-mips/semaphore.h delete mode 100644 include/asm-mn10300/semaphore.h delete mode 100644 include/asm-parisc/semaphore.h delete mode 100644 include/asm-powerpc/semaphore.h delete mode 100644 include/asm-s390/semaphore.h delete mode 100644 include/asm-sh/semaphore.h delete mode 100644 include/asm-sparc/semaphore.h delete mode 100644 include/asm-sparc64/semaphore.h delete mode 100644 include/asm-um/semaphore.h delete mode 100644 include/asm-v850/semaphore.h delete mode 100644 include/asm-x86/semaphore.h delete mode 100644 include/asm-xtensa/semaphore.h (limited to 'include/asm-arm') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 9f73587219e..09c4a1efb8e 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -300,14 +300,6 @@ Who: ocfs2-devel@oss.oracle.com --------------------------- -What: asm/semaphore.h -When: 2.6.26 -Why: Implementation became generic; users should now include - linux/semaphore.h instead. -Who: Matthew Wilcox - ---------------------------- - What: SCTP_GET_PEER_ADDRS_NUM_OLD, SCTP_GET_PEER_ADDRS_OLD, SCTP_GET_LOCAL_ADDRS_NUM_OLD, SCTP_GET_LOCAL_ADDRS_OLD When: June 2009 diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-alpha/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-arm/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-avr32/semaphore.h b/include/asm-avr32/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-avr32/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-blackfin/semaphore.h b/include/asm-blackfin/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-blackfin/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-cris/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-frv/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-h8300/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-ia64/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-m32r/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-m68k/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-m68knommu/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-mips/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-mn10300/semaphore.h b/include/asm-mn10300/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-mn10300/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-parisc/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-powerpc/semaphore.h b/include/asm-powerpc/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-powerpc/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-s390/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-sh/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-sparc/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h deleted file mode 100644 index 39362afde5f..00000000000 --- a/include/asm-sparc64/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-um/semaphore.h b/include/asm-um/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-um/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-v850/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-x86/semaphore.h b/include/asm-x86/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-x86/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h deleted file mode 100644 index d9b2034ed1d..00000000000 --- a/include/asm-xtensa/semaphore.h +++ /dev/null @@ -1 +0,0 @@ -#include -- cgit v1.2.3-70-g09d2 From 27ac792ca0b0a1e7e65f20342260650516c95864 Mon Sep 17 00:00:00 2001 From: Andrea Righi Date: Wed, 23 Jul 2008 21:28:13 -0700 Subject: PAGE_ALIGN(): correctly handle 64-bit values on 32-bit architectures On 32-bit architectures PAGE_ALIGN() truncates 64-bit values to the 32-bit boundary. For example: u64 val = PAGE_ALIGN(size); always returns a value < 4GB even if size is greater than 4GB. The problem resides in PAGE_MASK definition (from include/asm-x86/page.h for example): #define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) ... #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) The "~" is performed on a 32-bit value, so everything in "and" with PAGE_MASK greater than 4GB will be truncated to the 32-bit boundary. Using the ALIGN() macro seems to be the right way, because it uses typeof(addr) for the mask. Also move the PAGE_ALIGN() definitions out of include/asm-*/page.h in include/linux/mm.h. See also lkml discussion: http://lkml.org/lkml/2008/6/11/237 [akpm@linux-foundation.org: fix drivers/media/video/uvc/uvc_queue.c] [akpm@linux-foundation.org: fix v850] [akpm@linux-foundation.org: fix powerpc] [akpm@linux-foundation.org: fix arm] [akpm@linux-foundation.org: fix mips] [akpm@linux-foundation.org: fix drivers/media/video/pvrusb2/pvrusb2-dvb.c] [akpm@linux-foundation.org: fix drivers/mtd/maps/uclinux.c] [akpm@linux-foundation.org: fix powerpc] Signed-off-by: Andrea Righi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/kernel/module.c | 1 + arch/arm/plat-omap/fb.c | 1 + arch/avr32/mm/ioremap.c | 1 + arch/h8300/kernel/setup.c | 1 + arch/m68k/amiga/chipram.c | 1 + arch/m68knommu/kernel/setup.c | 1 + arch/mips/kernel/module.c | 1 + arch/mips/sgi-ip27/ip27-klnuma.c | 1 + arch/powerpc/kernel/suspend.c | 1 + arch/powerpc/lib/code-patching.c | 1 + arch/sparc64/kernel/iommu_common.h | 2 +- arch/x86/kernel/module_64.c | 1 + arch/xtensa/kernel/setup.c | 1 + drivers/char/random.c | 1 + drivers/ieee1394/iso.c | 1 + drivers/media/video/pvrusb2/pvrusb2-dvb.c | 1 + drivers/media/video/pvrusb2/pvrusb2-ioread.c | 1 + drivers/media/video/uvc/uvc_queue.c | 1 + drivers/media/video/videobuf-core.c | 1 + drivers/mtd/maps/uclinux.c | 1 + drivers/net/mlx4/eq.c | 1 + drivers/pcmcia/electra_cf.c | 1 + drivers/scsi/sun_esp.c | 1 + drivers/video/acornfb.c | 1 + drivers/video/imxfb.c | 1 + drivers/video/omap/dispc.c | 1 + drivers/video/omap/omapfb_main.c | 1 + drivers/video/pxafb.c | 1 + drivers/video/sa1100fb.c | 1 + include/asm-alpha/page.h | 3 --- include/asm-arm/page-nommu.h | 4 +--- include/asm-arm/page.h | 3 --- include/asm-avr32/page.h | 3 --- include/asm-blackfin/page.h | 3 --- include/asm-cris/page.h | 3 --- include/asm-frv/page.h | 3 --- include/asm-h8300/page.h | 3 --- include/asm-ia64/page.h | 1 - include/asm-m32r/page.h | 3 --- include/asm-m68k/dvma.h | 2 +- include/asm-m68k/page.h | 3 --- include/asm-m68knommu/page.h | 3 --- include/asm-mips/page.h | 3 --- include/asm-mips/processor.h | 2 +- include/asm-mn10300/page.h | 3 --- include/asm-parisc/page.h | 4 ---- include/asm-powerpc/page.h | 3 --- include/asm-s390/page.h | 3 --- include/asm-sh/page.h | 3 --- include/asm-sparc/page_32.h | 3 --- include/asm-sparc/page_64.h | 3 --- include/asm-um/page.h | 3 --- include/asm-v850/page.h | 4 ---- include/asm-x86/page.h | 3 --- include/asm-xtensa/page.h | 2 -- include/linux/mm.h | 3 +++ sound/core/info.c | 1 + 57 files changed, 36 insertions(+), 74 deletions(-) (limited to 'include/asm-arm') diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 79b7e5cf541..a68259a0ccc 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c index 96d6f061973..5d107520e6b 100644 --- a/arch/arm/plat-omap/fb.c +++ b/arch/arm/plat-omap/fb.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c index 3437c82434a..f03b79f0e0a 100644 --- a/arch/avr32/mm/ioremap.c +++ b/arch/avr32/mm/ioremap.c @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ #include +#include #include #include diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index b1f25c20a5d..7fda657110e 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index cbe36538af4..61df1d33c05 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index 03f4fe6a2fc..5985f198902 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index e7ed0ac4853..1f60e27523d 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c index 48932ce1d73..d9c79d8be81 100644 --- a/arch/mips/sgi-ip27/ip27-klnuma.c +++ b/arch/mips/sgi-ip27/ip27-klnuma.c @@ -4,6 +4,7 @@ * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com) */ #include +#include #include #include #include diff --git a/arch/powerpc/kernel/suspend.c b/arch/powerpc/kernel/suspend.c index 8cee5710754..6fc6328dc62 100644 --- a/arch/powerpc/kernel/suspend.c +++ b/arch/powerpc/kernel/suspend.c @@ -7,6 +7,7 @@ * Copyright (c) 2001 Patrick Mochel */ +#include #include /* References to section boundaries */ diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 0559fe086eb..7c975d43e3f 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h index f3575a614fa..53b19c8231a 100644 --- a/arch/sparc64/kernel/iommu_common.h +++ b/arch/sparc64/kernel/iommu_common.h @@ -23,7 +23,7 @@ #define IO_PAGE_SHIFT 13 #define IO_PAGE_SIZE (1UL << IO_PAGE_SHIFT) #define IO_PAGE_MASK (~(IO_PAGE_SIZE-1)) -#define IO_PAGE_ALIGN(addr) (((addr)+IO_PAGE_SIZE-1)&IO_PAGE_MASK) +#define IO_PAGE_ALIGN(addr) ALIGN(addr, IO_PAGE_SIZE) #define IO_TSB_ENTRIES (128*1024) #define IO_TSB_SIZE (IO_TSB_ENTRIES * 8) diff --git a/arch/x86/kernel/module_64.c b/arch/x86/kernel/module_64.c index 0e867676b5a..6ba87830d4b 100644 --- a/arch/x86/kernel/module_64.c +++ b/arch/x86/kernel/module_64.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 5e6d75c9f92..a00359e8f7a 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/char/random.c b/drivers/char/random.c index 0cf98bd4f2d..e0d0e371909 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -236,6 +236,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c index 07ca35c98f9..1cf6487b65b 100644 --- a/drivers/ieee1394/iso.c +++ b/drivers/ieee1394/iso.c @@ -11,6 +11,7 @@ #include #include +#include #include #include "hosts.h" diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c index 6ec4bf81fc7..77b3c338506 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c +++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c @@ -20,6 +20,7 @@ #include #include +#include #include "dvbdev.h" #include "pvrusb2-debug.h" #include "pvrusb2-hdw-internal.h" diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c index 05a1376405e..b4824782d85 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c @@ -22,6 +22,7 @@ #include "pvrusb2-debug.h" #include #include +#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 7388d0cee3d..5646a6a3293 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 0a88c44ace0..b7b05842cf2 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index c42f4b83f68..3fcf92130aa 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index e141a1513f0..ea3a09aaa84 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -33,6 +33,7 @@ #include #include +#include #include #include diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index c21f9a9c3e3..a34284b1482 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 2c87db98cdf..f9cf7015136 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index eedb8285e32..017233d0c48 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 94e4d3ac1a0..0c5a475c1ca 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index ab32ceb0617..ab77c51fe9d 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 14d0f7a1114..f85af5c4fa6 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -25,6 +25,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index bb251436950..5e8a140399f 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index ab2b2110478..4a9f7e12180 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -167,6 +167,7 @@ #include #include #include +#include #include #include #include diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h index 22ff9762d17..0995f9d1341 100644 --- a/include/asm-alpha/page.h +++ b/include/asm-alpha/page.h @@ -80,9 +80,6 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) #ifndef CONFIG_DISCONTIGMEM diff --git a/include/asm-arm/page-nommu.h b/include/asm-arm/page-nommu.h index a1bcad06048..ea1cde84f50 100644 --- a/include/asm-arm/page-nommu.h +++ b/include/asm-arm/page-nommu.h @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + #ifndef _ASMARM_PAGE_NOMMU_H #define _ASMARM_PAGE_NOMMU_H @@ -42,9 +43,6 @@ typedef unsigned long pgprot_t; #define __pmd(x) (x) #define __pgprot(x) (x) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h index 8e05bdb5f12..7c5fc5582e5 100644 --- a/include/asm-arm/page.h +++ b/include/asm-arm/page.h @@ -15,9 +15,6 @@ #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #ifndef __ASSEMBLY__ #ifndef CONFIG_MMU diff --git a/include/asm-avr32/page.h b/include/asm-avr32/page.h index cbbc5ca9728..f805d1cb11b 100644 --- a/include/asm-avr32/page.h +++ b/include/asm-avr32/page.h @@ -57,9 +57,6 @@ static inline int get_order(unsigned long size) #endif /* !__ASSEMBLY__ */ -/* Align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - /* * The hardware maps the virtual addresses 0x80000000 -> 0x9fffffff * permanently to the physical addresses 0x00000000 -> 0x1fffffff when diff --git a/include/asm-blackfin/page.h b/include/asm-blackfin/page.h index c7db0220fbd..344f6a8c1f2 100644 --- a/include/asm-blackfin/page.h +++ b/include/asm-blackfin/page.h @@ -51,9 +51,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h index c45bb1ef397..d19272ba6b6 100644 --- a/include/asm-cris/page.h +++ b/include/asm-cris/page.h @@ -60,9 +60,6 @@ typedef struct page *pgtable_t; #define page_to_phys(page) __pa((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #ifndef __ASSEMBLY__ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-frv/page.h b/include/asm-frv/page.h index c2c1e89e747..bd9c220094c 100644 --- a/include/asm-frv/page.h +++ b/include/asm-frv/page.h @@ -40,9 +40,6 @@ typedef struct page *pgtable_t; #define __pgprot(x) ((pgprot_t) { (x) } ) #define PTE_MASK PAGE_MASK -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - #define devmem_is_allowed(pfn) 1 #define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr)) diff --git a/include/asm-h8300/page.h b/include/asm-h8300/page.h index d6a3eaf3b27..0b6acf0b03a 100644 --- a/include/asm-h8300/page.h +++ b/include/asm-h8300/page.h @@ -43,9 +43,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h index 36f39321b76..5f271bc712e 100644 --- a/include/asm-ia64/page.h +++ b/include/asm-ia64/page.h @@ -40,7 +40,6 @@ #define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE - 1)) -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) #define PERCPU_PAGE_SHIFT 16 /* log2() of max. size of per-CPU area */ #define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT) diff --git a/include/asm-m32r/page.h b/include/asm-m32r/page.h index 8a677f3fca6..c9333089fe1 100644 --- a/include/asm-m32r/page.h +++ b/include/asm-m32r/page.h @@ -41,9 +41,6 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - /* * This handles the memory map.. We could make this a config * option, but too many people screw it up, and too few need diff --git a/include/asm-m68k/dvma.h b/include/asm-m68k/dvma.h index 4fff408d015..890bbf7e775 100644 --- a/include/asm-m68k/dvma.h +++ b/include/asm-m68k/dvma.h @@ -13,7 +13,7 @@ #define DVMA_PAGE_SHIFT 13 #define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT) #define DVMA_PAGE_MASK (~(DVMA_PAGE_SIZE-1)) -#define DVMA_PAGE_ALIGN(addr) (((addr)+DVMA_PAGE_SIZE-1)&DVMA_PAGE_MASK) +#define DVMA_PAGE_ALIGN(addr) ALIGN(addr, DVMA_PAGE_SIZE) extern void dvma_init(void); extern int dvma_map_iommu(unsigned long kaddr, unsigned long baddr, diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h index 880c2cbff8a..a34b8bad784 100644 --- a/include/asm-m68k/page.h +++ b/include/asm-m68k/page.h @@ -103,9 +103,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #endif /* !__ASSEMBLY__ */ #include diff --git a/include/asm-m68knommu/page.h b/include/asm-m68knommu/page.h index 1e82ebb7d64..3a1ede4544c 100644 --- a/include/asm-m68knommu/page.h +++ b/include/asm-m68knommu/page.h @@ -43,9 +43,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 494f00ba954..fe7a88ea066 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -137,9 +137,6 @@ typedef struct { unsigned long pgprot; } pgprot_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - /* * __pa()/__va() should be used only during mem init. */ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 58cbac5a64e..a1e4453469f 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -45,7 +45,7 @@ extern unsigned int vced_count, vcei_count; * This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) +#define TASK_UNMAPPED_BASE ((TASK_SIZE / 3) & ~(PAGE_SIZE)) #endif #ifdef CONFIG_64BIT diff --git a/include/asm-mn10300/page.h b/include/asm-mn10300/page.h index 124971b9fb9..8288e124165 100644 --- a/include/asm-mn10300/page.h +++ b/include/asm-mn10300/page.h @@ -61,9 +61,6 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - /* * This handles the memory map.. We could make this a config * option, but too many people screw it up, and too few need diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h index 27d50b85954..c3941f09a87 100644 --- a/include/asm-parisc/page.h +++ b/include/asm-parisc/page.h @@ -119,10 +119,6 @@ extern int npmem_ranges; #define PMD_ENTRY_SIZE (1UL << BITS_PER_PMD_ENTRY) #define PTE_ENTRY_SIZE (1UL << BITS_PER_PTE_ENTRY) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - - #define LINUX_GATEWAY_SPACE 0 /* This governs the relationship between virtual and physical addresses. diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h index cffdf0eb0df..e088545cb3f 100644 --- a/include/asm-powerpc/page.h +++ b/include/asm-powerpc/page.h @@ -119,9 +119,6 @@ extern phys_addr_t kernstart_addr; /* align addr on a size boundary - adjust address up if needed */ #define _ALIGN(addr,size) _ALIGN_UP(addr,size) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) - /* * Don't compare things with KERNELBASE or PAGE_OFFSET to test for * "kernelness", use is_kernel_addr() - it should do what you want. diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index 12fd9c4f0f1..991ba939408 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h @@ -138,9 +138,6 @@ void arch_alloc_page(struct page *page, int order); #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #define __PAGE_OFFSET 0x0UL #define PAGE_OFFSET 0x0UL #define __pa(x) (unsigned long)(x) diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 304c30b5d94..5dc01d2fcc4 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -22,9 +22,6 @@ #define PAGE_MASK (~(PAGE_SIZE-1)) #define PTE_MASK PAGE_MASK -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) #define HPAGE_SHIFT 16 #elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) diff --git a/include/asm-sparc/page_32.h b/include/asm-sparc/page_32.h index 14de518cc38..cf5fb70ca1c 100644 --- a/include/asm-sparc/page_32.h +++ b/include/asm-sparc/page_32.h @@ -134,9 +134,6 @@ BTFIXUPDEF_SETHI(sparc_unmapped_base) #endif /* !(__ASSEMBLY__) */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #define PAGE_OFFSET 0xf0000000 #ifndef __ASSEMBLY__ extern unsigned long phys_base; diff --git a/include/asm-sparc/page_64.h b/include/asm-sparc/page_64.h index a8a2bba032c..b579b910ef5 100644 --- a/include/asm-sparc/page_64.h +++ b/include/asm-sparc/page_64.h @@ -106,9 +106,6 @@ typedef struct page *pgtable_t; #endif /* !(__ASSEMBLY__) */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - /* We used to stick this into a hard-coded global register (%g4) * but that does not make sense anymore. */ diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 916e1a61999..335c57383c0 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h @@ -92,9 +92,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long uml_physmem; #define PAGE_OFFSET (uml_physmem) diff --git a/include/asm-v850/page.h b/include/asm-v850/page.h index 74a539a9bd5..f9de35d873f 100644 --- a/include/asm-v850/page.h +++ b/include/asm-v850/page.h @@ -94,10 +94,6 @@ typedef unsigned long pgprot_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - - /* No current v850 processor has virtual memory. */ #define __virt_to_phys(addr) (addr) #define __phys_to_virt(addr) (addr) diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 6e02098b160..49982110e4d 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -34,9 +34,6 @@ #define HUGE_MAX_HSTATE 2 -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #ifndef __ASSEMBLY__ #include #endif diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h index 80a6ae0dd25..11f7dc2dbec 100644 --- a/include/asm-xtensa/page.h +++ b/include/asm-xtensa/page.h @@ -26,13 +26,11 @@ /* * PAGE_SHIFT determines the page size - * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary */ #define PAGE_SHIFT 12 #define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE - 1) & PAGE_MASK) #define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR #define MAX_MEM_PFN XCHAL_KSEG_SIZE diff --git a/include/linux/mm.h b/include/linux/mm.h index df322fb4df3..d87a5a5fe87 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -41,6 +41,9 @@ extern unsigned long mmap_min_addr; #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) + /* * Linux kernel virtual memory manager primitives. * The idea being to have a "virtual" mm in the same way diff --git a/sound/core/info.c b/sound/core/info.c index cb5ead3e202..c67773ad929 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From e7ecb331e11d1f7aa66aeef9170fc20781c9bb55 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 23 Jul 2008 21:28:35 -0700 Subject: pm: remove remaining obsolete definitions from pm.h Remove the remaining obsolete definitions from include/linux/pm.h and move the definitions of PM_SUSPEND and PM_RESUME to the header of h3600 which is the only user of them. Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-arm/arch-sa1100/h3600.h | 5 ++++ include/linux/pm.h | 46 ------------------------------------- 2 files changed, 5 insertions(+), 46 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-sa1100/h3600.h b/include/asm-arm/arch-sa1100/h3600.h index 1b635597157..3ca0ecf095e 100644 --- a/include/asm-arm/arch-sa1100/h3600.h +++ b/include/asm-arm/arch-sa1100/h3600.h @@ -23,6 +23,11 @@ #ifndef _INCLUDE_H3600_H_ #define _INCLUDE_H3600_H_ +typedef int __bitwise pm_request_t; + +#define PM_SUSPEND ((__force pm_request_t) 1) /* enter D1-D3 */ +#define PM_RESUME ((__force pm_request_t) 2) /* enter D0 */ + /* generalized support for H3xxx series Compaq Pocket PC's */ #define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600() || machine_is_h3800()) diff --git a/include/linux/pm.h b/include/linux/pm.h index 5bf1ce89cfb..390dd95a375 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -25,52 +25,6 @@ #include #include -/* - * Power management requests... these are passed to pm_send_all() and friends. - * - * these functions are old and deprecated, see below. - */ -typedef int __bitwise pm_request_t; - -#define PM_SUSPEND ((__force pm_request_t) 1) /* enter D1-D3 */ -#define PM_RESUME ((__force pm_request_t) 2) /* enter D0 */ - - -/* - * Device types... these are passed to pm_register - */ -typedef int __bitwise pm_dev_t; - -#define PM_UNKNOWN_DEV ((__force pm_dev_t) 0) /* generic */ -#define PM_SYS_DEV ((__force pm_dev_t) 1) /* system device (fan, KB controller, ...) */ -#define PM_PCI_DEV ((__force pm_dev_t) 2) /* PCI device */ -#define PM_USB_DEV ((__force pm_dev_t) 3) /* USB device */ -#define PM_SCSI_DEV ((__force pm_dev_t) 4) /* SCSI device */ -#define PM_ISA_DEV ((__force pm_dev_t) 5) /* ISA device */ -#define PM_MTD_DEV ((__force pm_dev_t) 6) /* Memory Technology Device */ - -/* - * System device hardware ID (PnP) values - */ -enum -{ - PM_SYS_UNKNOWN = 0x00000000, /* generic */ - PM_SYS_KBC = 0x41d00303, /* keyboard controller */ - PM_SYS_COM = 0x41d00500, /* serial port */ - PM_SYS_IRDA = 0x41d00510, /* IRDA controller */ - PM_SYS_FDC = 0x41d00700, /* floppy controller */ - PM_SYS_VGA = 0x41d00900, /* VGA controller */ - PM_SYS_PCMCIA = 0x41d00e00, /* PCMCIA controller */ -}; - -/* - * Device identifier - */ -#define PM_PCI_ID(dev) ((dev)->bus->number << 16 | (dev)->devfn) - -/* Functions above this comment are list-based old-style power - * management. Please avoid using them. */ - /* * Callbacks for platform drivers to implement. */ -- cgit v1.2.3-70-g09d2 From d83b8b85cd56a083d30df73f3fd5e4714591b910 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 24 Jul 2008 22:53:30 +0200 Subject: ide: define MAX_HWIFS in * Now that ide_hwif_t instances are allocated dynamically the difference between MAX_HWIFS == 2 and MAX_HWIFS == 10 is ~100 bytes (x86-32) so use MAX_HWIFS == 10 on all archs except these ones that use MAX_HWIFS == 1. * Define MAX_HWIFS in instead of . [ Please note that avr32/cris/v850 have no and alpha/ia64/sh always define CONFIG_IDE_MAX_HWIFS. ] Signed-off-by: Bartlomiej Zolnierkiewicz --- include/asm-arm/ide.h | 4 ---- include/asm-blackfin/ide.h | 2 -- include/asm-frv/ide.h | 4 ---- include/asm-h8300/ide.h | 2 -- include/asm-m32r/ide.h | 8 -------- include/asm-m68k/ide.h | 4 ---- include/asm-mips/mach-generic/ide.h | 8 -------- include/asm-mn10300/ide.h | 4 ---- include/asm-parisc/ide.h | 4 ---- include/asm-powerpc/ide.h | 8 -------- include/asm-sparc/ide.h | 3 --- include/asm-x86/ide.h | 9 --------- include/asm-xtensa/ide.h | 5 ----- include/linux/ide.h | 8 ++++++++ 14 files changed, 8 insertions(+), 65 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/ide.h b/include/asm-arm/ide.h index 88f4d231ce4..a48019f99d0 100644 --- a/include/asm-arm/ide.h +++ b/include/asm-arm/ide.h @@ -13,10 +13,6 @@ #ifdef __KERNEL__ -#ifndef MAX_HWIFS -#define MAX_HWIFS 4 -#endif - #define __ide_mm_insw(port,addr,len) readsw(port,addr,len) #define __ide_mm_insl(port,addr,len) readsl(port,addr,len) #define __ide_mm_outsw(port,addr,len) writesw(port,addr,len) diff --git a/include/asm-blackfin/ide.h b/include/asm-blackfin/ide.h index 5b88de115bf..90bc50bd22e 100644 --- a/include/asm-blackfin/ide.h +++ b/include/asm-blackfin/ide.h @@ -17,8 +17,6 @@ #ifdef __KERNEL__ /****************************************************************************/ -#define MAX_HWIFS 1 - #include /****************************************************************************/ diff --git a/include/asm-frv/ide.h b/include/asm-frv/ide.h index 8c9a540d434..7ebcc56a222 100644 --- a/include/asm-frv/ide.h +++ b/include/asm-frv/ide.h @@ -18,10 +18,6 @@ #include #include -#ifndef MAX_HWIFS -#define MAX_HWIFS 8 -#endif - /****************************************************************************/ /* * some bits needed for parts of the IDE subsystem to compile diff --git a/include/asm-h8300/ide.h b/include/asm-h8300/ide.h index f8535ce7476..8f79ba2ff92 100644 --- a/include/asm-h8300/ide.h +++ b/include/asm-h8300/ide.h @@ -16,8 +16,6 @@ #ifdef __KERNEL__ /****************************************************************************/ -#define MAX_HWIFS 1 - #include /****************************************************************************/ diff --git a/include/asm-m32r/ide.h b/include/asm-m32r/ide.h index 72798d62422..d755d41b993 100644 --- a/include/asm-m32r/ide.h +++ b/include/asm-m32r/ide.h @@ -15,14 +15,6 @@ #include -#ifndef MAX_HWIFS -# ifdef CONFIG_BLK_DEV_IDEPCI -#define MAX_HWIFS 10 -# else -#define MAX_HWIFS 2 -# endif -#endif - static __inline__ int ide_default_irq(unsigned long base) { switch (base) { diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h index 909c6dfd385..1daf6cbdd9f 100644 --- a/include/asm-m68k/ide.h +++ b/include/asm-m68k/ide.h @@ -45,10 +45,6 @@ #include #endif -#ifndef MAX_HWIFS -#define MAX_HWIFS 4 /* same as the other archs */ -#endif - /* * Get rid of defs from io.h - ide has its private and conflicting versions * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h index f34740ee677..8ee6bff030d 100644 --- a/include/asm-mips/mach-generic/ide.h +++ b/include/asm-mips/mach-generic/ide.h @@ -19,14 +19,6 @@ #include #include -#ifndef MAX_HWIFS -# ifdef CONFIG_BLK_DEV_IDEPCI -#define MAX_HWIFS 10 -# else -#define MAX_HWIFS 6 -# endif -#endif - static __inline__ int ide_probe_legacy(void) { #ifdef CONFIG_PCI diff --git a/include/asm-mn10300/ide.h b/include/asm-mn10300/ide.h index dc235121ec4..6adcdd92e83 100644 --- a/include/asm-mn10300/ide.h +++ b/include/asm-mn10300/ide.h @@ -23,10 +23,6 @@ #undef SUPPORT_VLB_SYNC #define SUPPORT_VLB_SYNC 0 -#ifndef MAX_HWIFS -#define MAX_HWIFS 8 -#endif - /* * some bits needed for parts of the IDE subsystem to compile */ diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h index db0c9441009..c246ef75017 100644 --- a/include/asm-parisc/ide.h +++ b/include/asm-parisc/ide.h @@ -13,10 +13,6 @@ #ifdef __KERNEL__ -#ifndef MAX_HWIFS -#define MAX_HWIFS 2 -#endif - #define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) #define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) #define ide_request_region(from,extent,name) request_region((from), (extent), (name)) diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h index 3d90bf7d3d7..262def6a9f0 100644 --- a/include/asm-powerpc/ide.h +++ b/include/asm-powerpc/ide.h @@ -14,14 +14,6 @@ #endif #include -#ifndef MAX_HWIFS -#ifdef __powerpc64__ -#define MAX_HWIFS 10 -#else -#define MAX_HWIFS 8 -#endif -#endif - #define __ide_mm_insw(p, a, c) readsw((void __iomem *)(p), (a), (c)) #define __ide_mm_insl(p, a, c) readsl((void __iomem *)(p), (a), (c)) #define __ide_mm_outsw(p, a, c) writesw((void __iomem *)(p), (a), (c)) diff --git a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h index 879fcec72dc..b7af3d65823 100644 --- a/include/asm-sparc/ide.h +++ b/include/asm-sparc/ide.h @@ -21,9 +21,6 @@ #include #endif -#undef MAX_HWIFS -#define MAX_HWIFS 2 - #define __ide_insl(data_reg, buffer, wcount) \ __ide_insw(data_reg, buffer, (wcount)<<1) #define __ide_outsl(data_reg, buffer, wcount) \ diff --git a/include/asm-x86/ide.h b/include/asm-x86/ide.h index 34050747f38..bc54879daed 100644 --- a/include/asm-x86/ide.h +++ b/include/asm-x86/ide.h @@ -11,15 +11,6 @@ #ifdef __KERNEL__ - -#ifndef MAX_HWIFS -# ifdef CONFIG_BLK_DEV_IDEPCI -#define MAX_HWIFS 10 -# else -#define MAX_HWIFS 6 -# endif -#endif - static __inline__ int ide_default_irq(unsigned long base) { switch (base) { diff --git a/include/asm-xtensa/ide.h b/include/asm-xtensa/ide.h index cb995701c42..18342a2cc77 100644 --- a/include/asm-xtensa/ide.h +++ b/include/asm-xtensa/ide.h @@ -14,11 +14,6 @@ #ifdef __KERNEL__ - -#ifndef MAX_HWIFS -# define MAX_HWIFS 1 -#endif - #include #endif /* __KERNEL__ */ diff --git a/include/linux/ide.h b/include/linux/ide.h index dbd0aeb3a56..76fe00b24b5 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -213,6 +213,14 @@ static inline int __ide_default_irq(unsigned long base) #include +#ifndef MAX_HWIFS +#if defined(CONFIG_BLACKFIN) || defined(CONFIG_H8300) || defined(CONFIG_XTENSA) +# define MAX_HWIFS 1 +#else +# define MAX_HWIFS 10 +#endif +#endif + #if !defined(MAX_HWIFS) || defined(CONFIG_EMBEDDED) #undef MAX_HWIFS #define MAX_HWIFS CONFIG_IDE_MAX_HWIFS -- cgit v1.2.3-70-g09d2 From b69c49b78457f681ecfb3147bd968434ee6559c1 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 25 Jul 2008 01:45:40 -0700 Subject: clean up duplicated alloc/free_thread_info We duplicate alloc/free_thread_info defines on many platforms (the majority uses __get_free_pages/free_pages). This patch defines common defines and removes these duplicated defines. __HAVE_ARCH_THREAD_INFO_ALLOCATOR is introduced for platforms that do something different. Signed-off-by: FUJITA Tomonori Acked-by: Russell King Cc: Pekka Enberg Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-alpha/thread_info.h | 4 +--- include/asm-arm/thread_info.h | 13 ------------- include/asm-avr32/thread_info.h | 4 ---- include/asm-blackfin/thread_info.h | 5 +---- include/asm-cris/thread_info.h | 2 ++ include/asm-frv/thread_info.h | 2 ++ include/asm-h8300/thread_info.h | 5 +---- include/asm-ia64/thread_info.h | 2 ++ include/asm-m32r/thread_info.h | 2 ++ include/asm-m68k/thread_info.h | 8 +------- include/asm-m68knommu/thread_info.h | 4 ---- include/asm-mips/thread_info.h | 2 ++ include/asm-mn10300/thread_info.h | 2 ++ include/asm-parisc/thread_info.h | 10 +++------- include/asm-powerpc/thread_info.h | 14 +++----------- include/asm-s390/thread_info.h | 5 +---- include/asm-sh/thread_info.h | 2 ++ include/asm-sparc/thread_info_32.h | 2 ++ include/asm-sparc/thread_info_64.h | 2 ++ include/asm-um/thread_info.h | 16 +--------------- include/asm-x86/thread_info.h | 2 ++ include/asm-xtensa/thread_info.h | 5 +---- kernel/fork.c | 17 +++++++++++++++++ 23 files changed, 50 insertions(+), 80 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-alpha/thread_info.h b/include/asm-alpha/thread_info.h index fb318519629..15fda434442 100644 --- a/include/asm-alpha/thread_info.h +++ b/include/asm-alpha/thread_info.h @@ -50,10 +50,8 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define current_thread_info() __current_thread_info /* Thread information allocation. */ +#define THREAD_SIZE_ORDER 1 #define THREAD_SIZE (2*PAGE_SIZE) -#define alloc_thread_info(tsk) \ - ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) #endif /* __ASSEMBLY__ */ diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h index f5a66478631..d4be2d64616 100644 --- a/include/asm-arm/thread_info.h +++ b/include/asm-arm/thread_info.h @@ -97,19 +97,6 @@ static inline struct thread_info *current_thread_info(void) return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); } -/* thread information allocation */ -#ifdef CONFIG_DEBUG_STACK_USAGE -#define alloc_thread_info(tsk) \ - ((struct thread_info *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, \ - THREAD_SIZE_ORDER)) -#else -#define alloc_thread_info(tsk) \ - ((struct thread_info *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER)) -#endif - -#define free_thread_info(info) \ - free_pages((unsigned long)info, THREAD_SIZE_ORDER); - #define thread_saved_pc(tsk) \ ((unsigned long)(pc_pointer(task_thread_info(tsk)->cpu_context.pc))) #define thread_saved_fp(tsk) \ diff --git a/include/asm-avr32/thread_info.h b/include/asm-avr32/thread_info.h index df68631b7b2..294b25f9323 100644 --- a/include/asm-avr32/thread_info.h +++ b/include/asm-avr32/thread_info.h @@ -61,10 +61,6 @@ static inline struct thread_info *current_thread_info(void) return (struct thread_info *)addr; } -/* thread information allocation */ -#define alloc_thread_info(ti) \ - ((struct thread_info *) __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER)) -#define free_thread_info(ti) free_pages((unsigned long)(ti), 1) #define get_thread_info(ti) get_task_struct((ti)->task) #define put_thread_info(ti) put_task_struct((ti)->task) diff --git a/include/asm-blackfin/thread_info.h b/include/asm-blackfin/thread_info.h index bc2fe5accf2..642769329d1 100644 --- a/include/asm-blackfin/thread_info.h +++ b/include/asm-blackfin/thread_info.h @@ -42,6 +42,7 @@ /* * Size of kernel stack for each process. This must be a power of 2... */ +#define THREAD_SIZE_ORDER 1 #define THREAD_SIZE 8192 /* 2 pages */ #ifndef __ASSEMBLY__ @@ -94,10 +95,6 @@ static inline struct thread_info *current_thread_info(void) return (struct thread_info *)((long)ti & ~((long)THREAD_SIZE-1)); } -/* thread information allocation */ -#define alloc_thread_info(tsk) ((struct thread_info *) \ - __get_free_pages(GFP_KERNEL, 1)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) #endif /* __ASSEMBLY__ */ /* diff --git a/include/asm-cris/thread_info.h b/include/asm-cris/thread_info.h index 784668ab0fa..7efe1000f99 100644 --- a/include/asm-cris/thread_info.h +++ b/include/asm-cris/thread_info.h @@ -11,6 +11,8 @@ #ifdef __KERNEL__ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #ifndef __ASSEMBLY__ #include #include diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h index 348b8f1df17..b7ac6bf2844 100644 --- a/include/asm-frv/thread_info.h +++ b/include/asm-frv/thread_info.h @@ -82,6 +82,8 @@ register struct thread_info *__current_thread_info asm("gr15"); #define current_thread_info() ({ __current_thread_info; }) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + /* thread information allocation */ #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info(tsk) \ diff --git a/include/asm-h8300/thread_info.h b/include/asm-h8300/thread_info.h index 27bb95e2944..aafd4d322ec 100644 --- a/include/asm-h8300/thread_info.h +++ b/include/asm-h8300/thread_info.h @@ -49,6 +49,7 @@ struct thread_info { /* * Size of kernel stack for each process. This must be a power of 2... */ +#define THREAD_SIZE_ORDER 1 #define THREAD_SIZE 8192 /* 2 pages */ @@ -65,10 +66,6 @@ static inline struct thread_info *current_thread_info(void) return ti; } -/* thread information allocation */ -#define alloc_thread_info(tsk) ((struct thread_info *) \ - __get_free_pages(GFP_KERNEL, 1)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) #endif /* __ASSEMBLY__ */ /* diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h index 2422ac61658..7c60fcdd2ef 100644 --- a/include/asm-ia64/thread_info.h +++ b/include/asm-ia64/thread_info.h @@ -54,6 +54,8 @@ struct thread_info { }, \ } +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #ifndef ASM_OFFSETS_C /* how to get the thread information struct from C */ #define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE)) diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h index 1effcd0f5e6..8589d462df2 100644 --- a/include/asm-m32r/thread_info.h +++ b/include/asm-m32r/thread_info.h @@ -94,6 +94,8 @@ static inline struct thread_info *current_thread_info(void) return ti; } +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + /* thread information allocation */ #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info(tsk) \ diff --git a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h index d635a375248..abc002798a2 100644 --- a/include/asm-m68k/thread_info.h +++ b/include/asm-m68k/thread_info.h @@ -25,13 +25,7 @@ struct thread_info { } /* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */ -#if PAGE_SHIFT == 13 /* 8k machines */ -#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,0)) -#define free_thread_info(ti) free_pages((unsigned long)(ti),0) -#else /* otherwise assume 4k pages */ -#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,1)) -#define free_thread_info(ti) free_pages((unsigned long)(ti),1) -#endif /* PAGE_SHIFT == 13 */ +#define THREAD_SIZE_ORDER (13 - PAGE_SHIFT) #define init_thread_info (init_task.thread.info) #define init_stack (init_thread_union.stack) diff --git a/include/asm-m68knommu/thread_info.h b/include/asm-m68knommu/thread_info.h index 95996d978be..0c9bc095f3f 100644 --- a/include/asm-m68knommu/thread_info.h +++ b/include/asm-m68knommu/thread_info.h @@ -71,10 +71,6 @@ static inline struct thread_info *current_thread_info(void) return ti; } -/* thread information allocation */ -#define alloc_thread_info(tsk) ((struct thread_info *) \ - __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_SIZE_ORDER) #endif /* __ASSEMBLY__ */ #define PREEMPT_ACTIVE 0x4000000 diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index b2772df1a1b..bb3060699df 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h @@ -82,6 +82,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) #define THREAD_MASK (THREAD_SIZE - 1UL) +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info(tsk) \ ({ \ diff --git a/include/asm-mn10300/thread_info.h b/include/asm-mn10300/thread_info.h index e397e719278..78a3881f3c1 100644 --- a/include/asm-mn10300/thread_info.h +++ b/include/asm-mn10300/thread_info.h @@ -112,6 +112,8 @@ static inline unsigned long current_stack_pointer(void) return sp; } +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + /* thread information allocation */ #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL) diff --git a/include/asm-parisc/thread_info.h b/include/asm-parisc/thread_info.h index 2d9c7500867..9f812741c35 100644 --- a/include/asm-parisc/thread_info.h +++ b/include/asm-parisc/thread_info.h @@ -34,15 +34,11 @@ struct thread_info { /* thread information allocation */ -#define THREAD_ORDER 2 +#define THREAD_SIZE_ORDER 2 /* Be sure to hunt all references to this down when you change the size of * the kernel stack */ -#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) -#define THREAD_SHIFT (PAGE_SHIFT + THREAD_ORDER) - -#define alloc_thread_info(tsk) ((struct thread_info *) \ - __get_free_pages(GFP_KERNEL, THREAD_ORDER)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER) +#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER) /* how to get the thread information struct from C */ #define current_thread_info() ((struct thread_info *)mfctl(30)) diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index b705c2a7651..a9db562df69 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -66,20 +66,12 @@ struct thread_info { #if THREAD_SHIFT >= PAGE_SHIFT -#define THREAD_ORDER (THREAD_SHIFT - PAGE_SHIFT) - -#ifdef CONFIG_DEBUG_STACK_USAGE -#define alloc_thread_info(tsk) \ - ((struct thread_info *)__get_free_pages(GFP_KERNEL | \ - __GFP_ZERO, THREAD_ORDER)) -#else -#define alloc_thread_info(tsk) \ - ((struct thread_info *)__get_free_pages(GFP_KERNEL, THREAD_ORDER)) -#endif -#define free_thread_info(ti) free_pages((unsigned long)ti, THREAD_ORDER) +#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) #else /* THREAD_SHIFT < PAGE_SHIFT */ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + extern struct thread_info *alloc_thread_info(struct task_struct *tsk); extern void free_thread_info(struct thread_info *ti); diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h index 99bbed99a3b..91a8f93ad35 100644 --- a/include/asm-s390/thread_info.h +++ b/include/asm-s390/thread_info.h @@ -78,10 +78,7 @@ static inline struct thread_info *current_thread_info(void) return (struct thread_info *)((*(unsigned long *) __LC_KERNEL_STACK)-THREAD_SIZE); } -/* thread information allocation */ -#define alloc_thread_info(tsk) ((struct thread_info *) \ - __get_free_pages(GFP_KERNEL,THREAD_ORDER)) -#define free_thread_info(ti) free_pages((unsigned long) (ti),THREAD_ORDER) +#define THREAD_SIZE_ORDER THREAD_ORDER #endif diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h index c50e5d35fe8..5131e390752 100644 --- a/include/asm-sh/thread_info.h +++ b/include/asm-sh/thread_info.h @@ -92,6 +92,8 @@ static inline struct thread_info *current_thread_info(void) return ti; } +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + /* thread information allocation */ #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info(ti) kzalloc(THREAD_SIZE, GFP_KERNEL) diff --git a/include/asm-sparc/thread_info_32.h b/include/asm-sparc/thread_info_32.h index 91b9f5888c8..2cf9db04405 100644 --- a/include/asm-sparc/thread_info_32.h +++ b/include/asm-sparc/thread_info_32.h @@ -86,6 +86,8 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define THREAD_INFO_ORDER 1 #endif +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info, void) #define alloc_thread_info(tsk) BTFIXUP_CALL(alloc_thread_info)() diff --git a/include/asm-sparc/thread_info_64.h b/include/asm-sparc/thread_info_64.h index c6d2e6c7f84..960969d5ad0 100644 --- a/include/asm-sparc/thread_info_64.h +++ b/include/asm-sparc/thread_info_64.h @@ -155,6 +155,8 @@ register struct thread_info *current_thread_info_reg asm("g6"); #define __THREAD_INFO_ORDER 0 #endif /* PAGE_SHIFT == 13 */ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info(tsk) \ ({ \ diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h index 356b83e2c22..e07e72846c7 100644 --- a/include/asm-um/thread_info.h +++ b/include/asm-um/thread_info.h @@ -53,21 +53,7 @@ static inline struct thread_info *current_thread_info(void) return ti; } -#ifdef CONFIG_DEBUG_STACK_USAGE - -#define alloc_thread_info(tsk) \ - ((struct thread_info *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, \ - CONFIG_KERNEL_STACK_ORDER)) -#else - -/* thread information allocation */ -#define alloc_thread_info(tsk) \ - ((struct thread_info *) __get_free_pages(GFP_KERNEL, \ - CONFIG_KERNEL_STACK_ORDER)) -#endif - -#define free_thread_info(ti) \ - free_pages((unsigned long)(ti),CONFIG_KERNEL_STACK_ORDER) +#define THREAD_SIZE_ORDER CONFIG_KERNEL_STACK_ORDER #endif diff --git a/include/asm-x86/thread_info.h b/include/asm-x86/thread_info.h index 3f2de105098..da0a675adf9 100644 --- a/include/asm-x86/thread_info.h +++ b/include/asm-x86/thread_info.h @@ -152,6 +152,8 @@ struct thread_info { #define THREAD_FLAGS GFP_KERNEL #endif +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #define alloc_thread_info(tsk) \ ((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER)) diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h index a2c640682ed..7e4131dd546 100644 --- a/include/asm-xtensa/thread_info.h +++ b/include/asm-xtensa/thread_info.h @@ -111,10 +111,6 @@ static inline struct thread_info *current_thread_info(void) return ti; } -/* thread information allocation */ -#define alloc_thread_info(tsk) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) -#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) - #else /* !__ASSEMBLY__ */ /* how to get the thread information struct from ASM */ @@ -160,6 +156,7 @@ static inline struct thread_info *current_thread_info(void) #define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */ #define THREAD_SIZE 8192 //(2*PAGE_SIZE) +#define THREAD_SIZE_ORDER 1 #endif /* __KERNEL__ */ #endif /* _XTENSA_THREAD_INFO */ diff --git a/kernel/fork.c b/kernel/fork.c index 552c8d8e77a..5a5d6fef341 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -93,6 +93,23 @@ int nr_processes(void) static struct kmem_cache *task_struct_cachep; #endif +#ifndef __HAVE_ARCH_THREAD_INFO_ALLOCATOR +static inline struct thread_info *alloc_thread_info(struct task_struct *tsk) +{ +#ifdef CONFIG_DEBUG_STACK_USAGE + gfp_t mask = GFP_KERNEL | __GFP_ZERO; +#else + gfp_t mask = GFP_KERNEL; +#endif + return (struct thread_info *)__get_free_pages(mask, THREAD_SIZE_ORDER); +} + +static inline void free_thread_info(struct thread_info *ti) +{ + free_pages((unsigned long)ti, THREAD_SIZE_ORDER); +} +#endif + /* SLAB cache for signal_struct structures (tsk->signal) */ static struct kmem_cache *signal_cachep; -- cgit v1.2.3-70-g09d2 From f22ab814a24e654b1de24db0c5f8b57b5ab2026a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 01:47:34 -0700 Subject: include/asm/ptrace.h userspace headers cleanup This patch contains the following cleanups for the asm/ptrace.h userspace headers: - include/asm-generic/Kbuild.asm already lists ptrace.h, remove the superfluous listings in the Kbuild files of the following architectures: - cris - frv - powerpc - x86 - don't expose function prototypes and macros to userspace: - arm - blackfin - cris - mn10300 - parisc - remove #ifdef CONFIG_'s around #define's: - blackfin - m68knommu - sh: AFAIK __SH5__ should work in both kernel and userspace, no need to leak CONFIG_SUPERH64 to userspace - xtensa: cosmetical change to remove empty #ifndef __ASSEMBLY__ #else #endif from the userspace headers Not changed by this patch is the fact that the following architectures have a different struct pt_regs depending on CONFIG_ variables: - h8300 - m68knommu - mips This does not work in userspace. Signed-off-by: Adrian Bunk Cc: Cc: Roland McGrath Cc: Oleg Nesterov Acked-by: Greg Ungerer Acked-by: Paul Mundt Acked-by: Grant Grundler Acked-by: Jesper Nilsson Acked-by: Chris Zankel Acked-by: David Howells Acked-by: Paul Mackerras Acked-by: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-arm/ptrace.h | 6 ++---- include/asm-blackfin/ptrace.h | 6 ++++-- include/asm-cris/arch-v10/Kbuild | 1 - include/asm-cris/arch-v10/ptrace.h | 4 ++++ include/asm-cris/arch-v32/Kbuild | 1 - include/asm-cris/arch-v32/ptrace.h | 4 ++++ include/asm-cris/ptrace.h | 4 +++- include/asm-frv/Kbuild | 1 - include/asm-m68knommu/ptrace.h | 2 -- include/asm-mn10300/ptrace.h | 8 ++++++-- include/asm-parisc/ptrace.h | 4 +++- include/asm-powerpc/Kbuild | 1 - include/asm-sh/ptrace.h | 2 +- include/asm-x86/Kbuild | 1 - include/asm-xtensa/ptrace.h | 10 +++++----- 15 files changed, 32 insertions(+), 23 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h index 7aaa206cb54..8382b7510f9 100644 --- a/include/asm-arm/ptrace.h +++ b/include/asm-arm/ptrace.h @@ -139,8 +139,6 @@ static inline int valid_user_regs(struct pt_regs *regs) return 0; } -#endif /* __KERNEL__ */ - #define pc_pointer(v) \ ((v) & ~PCMASK) @@ -153,10 +151,10 @@ extern unsigned long profile_pc(struct pt_regs *regs); #define profile_pc(regs) instruction_pointer(regs) #endif -#ifdef __KERNEL__ #define predicate(x) ((x) & 0xf0000000) #define PREDICATE_ALWAYS 0xe0000000 -#endif + +#endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-blackfin/ptrace.h b/include/asm-blackfin/ptrace.h index b8346cd3a6f..a45a80e54ad 100644 --- a/include/asm-blackfin/ptrace.h +++ b/include/asm-blackfin/ptrace.h @@ -83,14 +83,14 @@ struct pt_regs { #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 /* ptrace signal */ -#ifdef CONFIG_BINFMT_ELF_FDPIC #define PTRACE_GETFDPIC 31 #define PTRACE_GETFDPIC_EXEC 0 #define PTRACE_GETFDPIC_INTERP 1 -#endif #define PS_S (0x0002) +#ifdef __KERNEL__ + /* user_mode returns true if only one bit is set in IPEND, other than the master interrupt enable. */ #define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1))) @@ -98,6 +98,8 @@ struct pt_regs { #define profile_pc(regs) instruction_pointer(regs) extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ + #endif /* __ASSEMBLY__ */ /* diff --git a/include/asm-cris/arch-v10/Kbuild b/include/asm-cris/arch-v10/Kbuild index 60e7e1b73ce..7a192e1290b 100644 --- a/include/asm-cris/arch-v10/Kbuild +++ b/include/asm-cris/arch-v10/Kbuild @@ -1,4 +1,3 @@ -header-y += ptrace.h header-y += user.h header-y += svinto.h header-y += sv_addr_ag.h diff --git a/include/asm-cris/arch-v10/ptrace.h b/include/asm-cris/arch-v10/ptrace.h index fb14c5ee37f..2f464eab3a5 100644 --- a/include/asm-cris/arch-v10/ptrace.h +++ b/include/asm-cris/arch-v10/ptrace.h @@ -106,10 +106,14 @@ struct switch_stack { unsigned long return_ip; /* ip that _resume will return to */ }; +#ifdef __KERNEL__ + /* bit 8 is user-mode flag */ #define user_mode(regs) (((regs)->dccr & 0x100) != 0) #define instruction_pointer(regs) ((regs)->irp) #define profile_pc(regs) instruction_pointer(regs) extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-cris/arch-v32/Kbuild b/include/asm-cris/arch-v32/Kbuild index a0ec545e242..35f2fc4f993 100644 --- a/include/asm-cris/arch-v32/Kbuild +++ b/include/asm-cris/arch-v32/Kbuild @@ -1,3 +1,2 @@ -header-y += ptrace.h header-y += user.h header-y += cryptocop.h diff --git a/include/asm-cris/arch-v32/ptrace.h b/include/asm-cris/arch-v32/ptrace.h index 516cc7062d9..41f4e8662bc 100644 --- a/include/asm-cris/arch-v32/ptrace.h +++ b/include/asm-cris/arch-v32/ptrace.h @@ -106,9 +106,13 @@ struct switch_stack { unsigned long return_ip; /* ip that _resume will return to */ }; +#ifdef __KERNEL__ + #define user_mode(regs) (((regs)->ccs & (1 << (U_CCS_BITNR + CCS_SHIFT))) != 0) #define instruction_pointer(regs) ((regs)->erp) extern void show_regs(struct pt_regs *); #define profile_pc(regs) instruction_pointer(regs) +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-cris/ptrace.h b/include/asm-cris/ptrace.h index 1ec69a7ea83..d910925e317 100644 --- a/include/asm-cris/ptrace.h +++ b/include/asm-cris/ptrace.h @@ -4,11 +4,13 @@ #include #ifdef __KERNEL__ + /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 -#endif #define profile_pc(regs) instruction_pointer(regs) +#endif /* __KERNEL__ */ + #endif /* _CRIS_PTRACE_H */ diff --git a/include/asm-frv/Kbuild b/include/asm-frv/Kbuild index bc3f12c5b7e..0f8956def73 100644 --- a/include/asm-frv/Kbuild +++ b/include/asm-frv/Kbuild @@ -3,4 +3,3 @@ include include/asm-generic/Kbuild.asm header-y += registers.h unifdef-y += termios.h -unifdef-y += ptrace.h diff --git a/include/asm-m68knommu/ptrace.h b/include/asm-m68knommu/ptrace.h index 47258e86e8c..8c9194b9854 100644 --- a/include/asm-m68knommu/ptrace.h +++ b/include/asm-m68knommu/ptrace.h @@ -68,10 +68,8 @@ struct switch_stack { /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 -#ifdef CONFIG_FPU #define PTRACE_GETFPREGS 14 #define PTRACE_SETFPREGS 15 -#endif #ifdef __KERNEL__ diff --git a/include/asm-mn10300/ptrace.h b/include/asm-mn10300/ptrace.h index b3684689fcc..7b06cc623d8 100644 --- a/include/asm-mn10300/ptrace.h +++ b/include/asm-mn10300/ptrace.h @@ -88,12 +88,16 @@ extern struct pt_regs *__frame; /* current frame pointer */ /* options set using PTRACE_SETOPTIONS */ #define PTRACE_O_TRACESYSGOOD 0x00000001 -#if defined(__KERNEL__) && !defined(__ASSEMBLY__) +#if defined(__KERNEL__) + +#if !defined(__ASSEMBLY__) #define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) #define instruction_pointer(regs) ((regs)->pc) extern void show_regs(struct pt_regs *); -#endif +#endif /* !__ASSEMBLY */ #define profile_pc(regs) ((regs)->pc) +#endif /* __KERNEL__ */ + #endif /* _ASM_PTRACE_H */ diff --git a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h index 93f990e418f..3e94c5d85ff 100644 --- a/include/asm-parisc/ptrace.h +++ b/include/asm-parisc/ptrace.h @@ -33,7 +33,6 @@ struct pt_regs { unsigned long ipsw; /* CR22 */ }; -#define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS)) /* * The numbers chosen here are somewhat arbitrary but absolutely MUST * not overlap with any of the number assigned in . @@ -43,8 +42,11 @@ struct pt_regs { * since we have taken branch traps too) */ #define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */ + #ifdef __KERNEL__ +#define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS)) + /* XXX should we use iaoq[1] or iaoq[0] ? */ #define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0) #define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0) diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild index 04ce8f8a2ee..5ab7d7fe198 100644 --- a/include/asm-powerpc/Kbuild +++ b/include/asm-powerpc/Kbuild @@ -29,7 +29,6 @@ unifdef-y += elf.h unifdef-y += nvram.h unifdef-y += param.h unifdef-y += posix_types.h -unifdef-y += ptrace.h unifdef-y += seccomp.h unifdef-y += signal.h unifdef-y += spu_info.h diff --git a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h index 8d6c92b3e77..7d36dc3bee6 100644 --- a/include/asm-sh/ptrace.h +++ b/include/asm-sh/ptrace.h @@ -5,7 +5,7 @@ * Copyright (C) 1999, 2000 Niibe Yutaka * */ -#if defined(__SH5__) || defined(CONFIG_SUPERH64) +#if defined(__SH5__) struct pt_regs { unsigned long long pc; unsigned long long sr; diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild index 1e3554596f7..00473f7dd81 100644 --- a/include/asm-x86/Kbuild +++ b/include/asm-x86/Kbuild @@ -19,7 +19,6 @@ unifdef-y += msr.h unifdef-y += mtrr.h unifdef-y += posix_types_32.h unifdef-y += posix_types_64.h -unifdef-y += ptrace.h unifdef-y += unistd_32.h unifdef-y += unistd_64.h unifdef-y += vm86.h diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h index 422c73e2693..089b0db4481 100644 --- a/include/asm-xtensa/ptrace.h +++ b/include/asm-xtensa/ptrace.h @@ -73,10 +73,10 @@ #define PTRACE_GETXTREGS 18 #define PTRACE_SETXTREGS 19 -#ifndef __ASSEMBLY__ - #ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + /* * This struct defines the way the registers are stored on the * kernel stack during a system call or other kernel entry. @@ -122,14 +122,14 @@ extern void show_regs(struct pt_regs *); # ifndef CONFIG_SMP # define profile_pc(regs) instruction_pointer(regs) # endif -#endif /* __KERNEL__ */ #else /* __ASSEMBLY__ */ -#ifdef __KERNEL__ # include #define PT_REGS_OFFSET (KERNEL_STACK_SIZE - PT_USER_SIZE) -#endif #endif /* !__ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + #endif /* _XTENSA_PTRACE_H */ -- cgit v1.2.3-70-g09d2 From 7dcf2a9fced59e58e4694cdcf15850c01fdba89b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 1 Jul 2008 19:27:16 +0300 Subject: remove dummy asm/kvm.h files This patch removes the dummy asm/kvm.h files on architectures not (yet) supporting KVM and uses the same conditional headers installation as already used for a.out.h . Also removed are superfluous install rules in the s390 and x86 Kbuild files (they are already in Kbuild.asm). Signed-off-by: Adrian Bunk Acked-by: Sam Ravnborg Signed-off-by: David Woodhouse --- include/asm-alpha/kvm.h | 6 ------ include/asm-arm/kvm.h | 6 ------ include/asm-avr32/kvm.h | 6 ------ include/asm-blackfin/kvm.h | 6 ------ include/asm-cris/kvm.h | 6 ------ include/asm-frv/kvm.h | 6 ------ include/asm-generic/Kbuild.asm | 2 ++ include/asm-h8300/kvm.h | 6 ------ include/asm-m32r/kvm.h | 6 ------ include/asm-m68k/kvm.h | 6 ------ include/asm-m68knommu/kvm.h | 6 ------ include/asm-mips/kvm.h | 6 ------ include/asm-mn10300/kvm.h | 6 ------ include/asm-parisc/kvm.h | 6 ------ include/asm-s390/Kbuild | 1 - include/asm-sh/kvm.h | 6 ------ include/asm-sparc/kvm.h | 6 ------ include/asm-sparc64/kvm.h | 1 - include/asm-um/kvm.h | 6 ------ include/asm-x86/Kbuild | 1 - include/asm-xtensa/kvm.h | 6 ------ include/linux/Kbuild | 2 ++ 22 files changed, 4 insertions(+), 105 deletions(-) delete mode 100644 include/asm-alpha/kvm.h delete mode 100644 include/asm-arm/kvm.h delete mode 100644 include/asm-avr32/kvm.h delete mode 100644 include/asm-blackfin/kvm.h delete mode 100644 include/asm-cris/kvm.h delete mode 100644 include/asm-frv/kvm.h delete mode 100644 include/asm-h8300/kvm.h delete mode 100644 include/asm-m32r/kvm.h delete mode 100644 include/asm-m68k/kvm.h delete mode 100644 include/asm-m68knommu/kvm.h delete mode 100644 include/asm-mips/kvm.h delete mode 100644 include/asm-mn10300/kvm.h delete mode 100644 include/asm-parisc/kvm.h delete mode 100644 include/asm-sh/kvm.h delete mode 100644 include/asm-sparc/kvm.h delete mode 100644 include/asm-sparc64/kvm.h delete mode 100644 include/asm-um/kvm.h delete mode 100644 include/asm-xtensa/kvm.h (limited to 'include/asm-arm') diff --git a/include/asm-alpha/kvm.h b/include/asm-alpha/kvm.h deleted file mode 100644 index b9daec42968..00000000000 --- a/include/asm-alpha/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_ALPHA_H -#define __LINUX_KVM_ALPHA_H - -/* alpha does not support KVM */ - -#endif diff --git a/include/asm-arm/kvm.h b/include/asm-arm/kvm.h deleted file mode 100644 index cb3c08cbcb9..00000000000 --- a/include/asm-arm/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_ARM_H -#define __LINUX_KVM_ARM_H - -/* arm does not support KVM */ - -#endif diff --git a/include/asm-avr32/kvm.h b/include/asm-avr32/kvm.h deleted file mode 100644 index 8c5777020e2..00000000000 --- a/include/asm-avr32/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_AVR32_H -#define __LINUX_KVM_AVR32_H - -/* avr32 does not support KVM */ - -#endif diff --git a/include/asm-blackfin/kvm.h b/include/asm-blackfin/kvm.h deleted file mode 100644 index e3477d77c01..00000000000 --- a/include/asm-blackfin/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_BLACKFIN_H -#define __LINUX_KVM_BLACKFIN_H - -/* blackfin does not support KVM */ - -#endif diff --git a/include/asm-cris/kvm.h b/include/asm-cris/kvm.h deleted file mode 100644 index c860f51149f..00000000000 --- a/include/asm-cris/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_CRIS_H -#define __LINUX_KVM_CRIS_H - -/* cris does not support KVM */ - -#endif diff --git a/include/asm-frv/kvm.h b/include/asm-frv/kvm.h deleted file mode 100644 index 9c8a4f08d0a..00000000000 --- a/include/asm-frv/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_FRV_H -#define __LINUX_KVM_FRV_H - -/* frv does not support KVM */ - -#endif diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm index 7cd25b8e7c9..1170dc60e63 100644 --- a/include/asm-generic/Kbuild.asm +++ b/include/asm-generic/Kbuild.asm @@ -1,4 +1,6 @@ +ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/kvm.h),) header-y += kvm.h +endif ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),) unifdef-y += a.out.h diff --git a/include/asm-h8300/kvm.h b/include/asm-h8300/kvm.h deleted file mode 100644 index bdbed7b987e..00000000000 --- a/include/asm-h8300/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_H8300_H -#define __LINUX_KVM_H8300_H - -/* h8300 does not support KVM */ - -#endif diff --git a/include/asm-m32r/kvm.h b/include/asm-m32r/kvm.h deleted file mode 100644 index 99a40515b77..00000000000 --- a/include/asm-m32r/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_M32R_H -#define __LINUX_KVM_M32R_H - -/* m32r does not support KVM */ - -#endif diff --git a/include/asm-m68k/kvm.h b/include/asm-m68k/kvm.h deleted file mode 100644 index 7ed27fce524..00000000000 --- a/include/asm-m68k/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_M68K_H -#define __LINUX_KVM_M68K_H - -/* m68k does not support KVM */ - -#endif diff --git a/include/asm-m68knommu/kvm.h b/include/asm-m68knommu/kvm.h deleted file mode 100644 index b49d4258dab..00000000000 --- a/include/asm-m68knommu/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_M68KNOMMU_H -#define __LINUX_KVM_M68KNOMMU_H - -/* m68knommu does not support KVM */ - -#endif diff --git a/include/asm-mips/kvm.h b/include/asm-mips/kvm.h deleted file mode 100644 index 093a5b7f796..00000000000 --- a/include/asm-mips/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_MIPS_H -#define __LINUX_KVM_MIPS_H - -/* mips does not support KVM */ - -#endif diff --git a/include/asm-mn10300/kvm.h b/include/asm-mn10300/kvm.h deleted file mode 100644 index f6b609ff4a5..00000000000 --- a/include/asm-mn10300/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_MN10300_H -#define __LINUX_KVM_MN10300_H - -/* mn10300 does not support KVM */ - -#endif diff --git a/include/asm-parisc/kvm.h b/include/asm-parisc/kvm.h deleted file mode 100644 index 00cc4581254..00000000000 --- a/include/asm-parisc/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_PARISC_H -#define __LINUX_KVM_PARISC_H - -/* parisc does not support KVM */ - -#endif diff --git a/include/asm-s390/Kbuild b/include/asm-s390/Kbuild index bb5e9edb982..63a23415fba 100644 --- a/include/asm-s390/Kbuild +++ b/include/asm-s390/Kbuild @@ -7,7 +7,6 @@ header-y += tape390.h header-y += ucontext.h header-y += vtoc.h header-y += zcrypt.h -header-y += kvm.h header-y += chsc.h unifdef-y += cmb.h diff --git a/include/asm-sh/kvm.h b/include/asm-sh/kvm.h deleted file mode 100644 index 6af51dbab2d..00000000000 --- a/include/asm-sh/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_SH_H -#define __LINUX_KVM_SH_H - -/* sh does not support KVM */ - -#endif diff --git a/include/asm-sparc/kvm.h b/include/asm-sparc/kvm.h deleted file mode 100644 index 2e5478da381..00000000000 --- a/include/asm-sparc/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_SPARC_H -#define __LINUX_KVM_SPARC_H - -/* sparc does not support KVM */ - -#endif diff --git a/include/asm-sparc64/kvm.h b/include/asm-sparc64/kvm.h deleted file mode 100644 index 53564ad86b1..00000000000 --- a/include/asm-sparc64/kvm.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-um/kvm.h b/include/asm-um/kvm.h deleted file mode 100644 index 66aa7709455..00000000000 --- a/include/asm-um/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_UM_H -#define __LINUX_KVM_UM_H - -/* um does not support KVM */ - -#endif diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild index 1e3554596f7..811e9828ccb 100644 --- a/include/asm-x86/Kbuild +++ b/include/asm-x86/Kbuild @@ -3,7 +3,6 @@ include include/asm-generic/Kbuild.asm header-y += boot.h header-y += bootparam.h header-y += debugreg.h -header-y += kvm.h header-y += ldt.h header-y += msr-index.h header-y += prctl.h diff --git a/include/asm-xtensa/kvm.h b/include/asm-xtensa/kvm.h deleted file mode 100644 index bda4e331e98..00000000000 --- a/include/asm-xtensa/kvm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_KVM_XTENSA_H -#define __LINUX_KVM_XTENSA_H - -/* xtensa does not support KVM */ - -#endif diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 71d70d1fbce..402c8f55d71 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -256,7 +256,9 @@ unifdef-y += kd.h unifdef-y += kernelcapi.h unifdef-y += kernel.h unifdef-y += keyboard.h +ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/kvm.h),) unifdef-y += kvm.h +endif unifdef-y += llc.h unifdef-y += loop.h unifdef-y += lp.h -- cgit v1.2.3-70-g09d2 From 0c65f459ce6c8bd873a61b3ae1e57858ab1debf3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jul 2008 15:35:22 -0700 Subject: [ARM] fix fls() for 64-bit arguments arm's fls() is implemented as a macro, causing it to misbehave when passed 64-bit arguments. Fix. Cc: Nickolay Vinogradov Tested-by: Krzysztof Halasa Cc: Signed-off-by: Andrew Morton Signed-off-by: Russell King --- include/asm-arm/bitops.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h index 5c60bfc1a84..9a1db20e032 100644 --- a/include/asm-arm/bitops.h +++ b/include/asm-arm/bitops.h @@ -277,9 +277,16 @@ static inline int constant_fls(int x) * the clz instruction for much better code efficiency. */ -#define fls(x) \ +#define __fls(x) \ ( __builtin_constant_p(x) ? constant_fls(x) : \ ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) + +/* Implement fls() in C so that 64-bit args are suitably truncated */ +static inline int fls(int x) +{ + return __fls(x); +} + #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) #define __ffs(x) (ffs(x) - 1) #define ffz(x) __ffs( ~(x) ) -- cgit v1.2.3-70-g09d2 From dd438e77f01d024919a8ae81d0cf2e4c6cda79cc Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 25 Jul 2008 20:55:52 +0100 Subject: [ARM] pci: provide dummy pci_get_legacy_ide_irq() This fixes footbridge_defconfig: drivers/pnp/resource.c: In function 'pci_dev_uses_irq': drivers/pnp/resource.c:317: error: implicit declaration of function 'pci_get_legacy_ide_irq' Signed-off-by: Russell King --- include/asm-arm/pci.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/asm-arm') diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h index 75feb1574a6..2d84792f2e1 100644 --- a/include/asm-arm/pci.h +++ b/include/asm-arm/pci.h @@ -78,6 +78,14 @@ pcibios_select_root(struct pci_dev *pdev, struct resource *res) return root; } +/* + * Dummy implementation; always return 0. + */ +static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) +{ + return 0; +} + #endif /* __KERNEL__ */ #endif -- cgit v1.2.3-70-g09d2 From 8d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 25 Jul 2008 19:44:49 -0700 Subject: dma-mapping: add the device argument to dma_mapping_error() Add per-device dma_mapping_ops support for CONFIG_X86_64 as POWER architecture does: This enables us to cleanly fix the Calgary IOMMU issue that some devices are not behind the IOMMU (http://lkml.org/lkml/2008/5/8/423). I think that per-device dma_mapping_ops support would be also helpful for KVM people to support PCI passthrough but Andi thinks that this makes it difficult to support the PCI passthrough (see the above thread). So I CC'ed this to KVM camp. Comments are appreciated. A pointer to dma_mapping_ops to struct dev_archdata is added. If the pointer is non NULL, DMA operations in asm/dma-mapping.h use it. If it's NULL, the system-wide dma_ops pointer is used as before. If it's useful for KVM people, I plan to implement a mechanism to register a hook called when a new pci (or dma capable) device is created (it works with hot plugging). It enables IOMMUs to set up an appropriate dma_mapping_ops per device. The major obstacle is that dma_mapping_error doesn't take a pointer to the device unlike other DMA operations. So x86 can't have dma_mapping_ops per device. Note all the POWER IOMMUs use the same dma_mapping_error function so this is not a problem for POWER but x86 IOMMUs use different dma_mapping_error functions. The first patch adds the device argument to dma_mapping_error. The patch is trivial but large since it touches lots of drivers and dma-mapping.h in all the architecture. This patch: dma_mapping_error() doesn't take a pointer to the device unlike other DMA operations. So we can't have dma_mapping_ops per device. Note that POWER already has dma_mapping_ops per device but all the POWER IOMMUs use the same dma_mapping_error function. x86 IOMMUs use device argument. [akpm@linux-foundation.org: fix sge] [akpm@linux-foundation.org: fix svc_rdma] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix bnx2x] [akpm@linux-foundation.org: fix s2io] [akpm@linux-foundation.org: fix pasemi_mac] [akpm@linux-foundation.org: fix sdhci] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix sparc] [akpm@linux-foundation.org: fix ibmvscsi] Signed-off-by: FUJITA Tomonori Cc: Muli Ben-Yehuda Cc: Andi Kleen Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/DMA-API.txt | 4 +- arch/arm/common/dmabounce.c | 2 +- arch/ia64/hp/common/hwsw_iommu.c | 5 +- arch/ia64/hp/common/sba_iommu.c | 2 +- arch/ia64/sn/pci/pci_dma.c | 2 +- arch/mips/mm/dma-default.c | 2 +- arch/powerpc/platforms/cell/celleb_scc_pciex.c | 2 +- arch/powerpc/platforms/cell/spider-pci.c | 2 +- arch/powerpc/platforms/iseries/mf.c | 2 +- arch/x86/kernel/pci-calgary_64.c | 2 +- arch/x86/kernel/pci-dma.c | 27 ++++--- arch/x86/kernel/pci-gart_64.c | 3 +- arch/x86/kernel/pci-nommu.c | 14 +--- arch/x86/kernel/pci-swiotlb_64.c | 2 +- drivers/firewire/fw-iso.c | 2 +- drivers/firewire/fw-ohci.c | 2 +- drivers/firewire/fw-sbp2.c | 8 +-- drivers/infiniband/hw/ipath/ipath_sdma.c | 2 +- drivers/infiniband/hw/ipath/ipath_user_sdma.c | 6 +- drivers/infiniband/hw/mthca/mthca_eq.c | 2 +- drivers/media/dvb/pluto2/pluto2.c | 2 +- drivers/mmc/host/sdhci.c | 4 +- drivers/net/arm/ep93xx_eth.c | 4 +- drivers/net/bnx2x_main.c | 4 +- drivers/net/cxgb3/sge.c | 2 +- drivers/net/e100.c | 2 +- drivers/net/e1000e/ethtool.c | 4 +- drivers/net/e1000e/netdev.c | 11 +-- drivers/net/ibmveth.c | 38 +++++----- drivers/net/iseries_veth.c | 4 +- drivers/net/mlx4/eq.c | 2 +- drivers/net/pasemi_mac.c | 6 +- drivers/net/qla3xxx.c | 12 ++-- drivers/net/s2io.c | 48 +++++++------ drivers/net/sfc/rx.c | 4 +- drivers/net/sfc/tx.c | 7 +- drivers/net/spider_net.c | 4 +- drivers/net/tc35815.c | 4 +- drivers/net/wireless/ath5k/base.c | 4 +- drivers/scsi/ibmvscsi/ibmvfc.c | 4 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 4 +- drivers/scsi/ibmvscsi/ibmvstgt.c | 2 +- drivers/scsi/ibmvscsi/rpa_vscsi.c | 2 +- drivers/spi/atmel_spi.c | 4 +- drivers/spi/au1550_spi.c | 6 +- drivers/spi/omap2_mcspi.c | 4 +- drivers/spi/pxa2xx_spi.c | 4 +- drivers/spi/spi_imx.c | 6 +- include/asm-alpha/dma-mapping.h | 6 +- include/asm-alpha/pci.h | 2 +- include/asm-arm/dma-mapping.h | 2 +- include/asm-avr32/dma-mapping.h | 2 +- include/asm-cris/dma-mapping.h | 2 +- include/asm-frv/dma-mapping.h | 2 +- include/asm-generic/dma-mapping-broken.h | 2 +- include/asm-generic/dma-mapping.h | 4 +- include/asm-generic/pci-dma-compat.h | 4 +- include/asm-ia64/machvec.h | 2 +- include/asm-m68k/dma-mapping.h | 2 +- include/asm-mips/dma-mapping.h | 2 +- include/asm-mn10300/dma-mapping.h | 2 +- include/asm-parisc/dma-mapping.h | 2 +- include/asm-powerpc/dma-mapping.h | 2 +- include/asm-sh/dma-mapping.h | 2 +- include/asm-sparc/dma-mapping_64.h | 2 +- include/asm-sparc/pci_32.h | 3 +- include/asm-sparc/pci_64.h | 5 +- include/asm-x86/device.h | 3 + include/asm-x86/dma-mapping.h | 99 ++++++++++++++++++-------- include/asm-x86/swiotlb.h | 2 +- include/asm-xtensa/dma-mapping.h | 2 +- include/linux/i2o.h | 2 +- include/linux/ssb/ssb.h | 4 +- include/rdma/ib_verbs.h | 2 +- lib/swiotlb.c | 4 +- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 3 +- 76 files changed, 256 insertions(+), 210 deletions(-) (limited to 'include/asm-arm') diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 80d150458c8..d8b63d164e4 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -298,10 +298,10 @@ recommended that you never use these unless you really know what the cache width is. int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr) In some circumstances dma_map_single and dma_map_page will fail to create a mapping. A driver can check for these errors by testing the returned diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index dd294734260..69130f36590 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -280,7 +280,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, /* * Trying to unmap an invalid mapping */ - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Trying to unmap invalid mapping\n"); return; } diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 1c44ec2a1d5..88b6e6f3fd8 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -186,9 +186,10 @@ hwsw_dma_supported (struct device *dev, u64 mask) } int -hwsw_dma_mapping_error (dma_addr_t dma_addr) +hwsw_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return hwiommu_dma_mapping_error (dma_addr) || swiotlb_dma_mapping_error(dma_addr); + return hwiommu_dma_mapping_error(dev, dma_addr) || + swiotlb_dma_mapping_error(dev, dma_addr); } EXPORT_SYMBOL(hwsw_dma_mapping_error); diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 34421aed1e2..4956be40d7b 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -2147,7 +2147,7 @@ sba_dma_supported (struct device *dev, u64 mask) } int -sba_dma_mapping_error (dma_addr_t dma_addr) +sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 52175af299a..53ebb648449 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -350,7 +350,7 @@ void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } EXPORT_SYMBOL(sn_dma_sync_sg_for_device); -int sn_dma_mapping_error(dma_addr_t dma_addr) +int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index ae39dd88b9a..891312f8e5a 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -348,7 +348,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele EXPORT_SYMBOL(dma_sync_sg_for_device); -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 0e04f8fb152..3e7e0f1568e 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -281,7 +281,7 @@ static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data) dummy_page_da = dma_map_single(bus->phb->parent, dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(dummy_page_da)) { + if (dma_mapping_error(bus->phb->parent, dummy_page_da)) { pr_err("PCIEX:Map dummy page failed.\n"); kfree(dummy_page_va); return -1; diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c index 418b605ac35..5122ec14527 100644 --- a/arch/powerpc/platforms/cell/spider-pci.c +++ b/arch/powerpc/platforms/cell/spider-pci.c @@ -111,7 +111,7 @@ static int __init spiderpci_pci_setup_chip(struct pci_controller *phb, dummy_page_da = dma_map_single(phb->parent, dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(dummy_page_da)) { + if (dma_mapping_error(phb->parent, dummy_page_da)) { pr_err("SPIDER-IOWA:Map dummy page filed.\n"); kfree(dummy_page_va); return -1; diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 1dc7295746d..731d7b15774 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -871,7 +871,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off, count = 256 - off; dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_addr)) + if (dma_mapping_error(NULL, dma_addr)) return -ENOMEM; memset(page, 0, off + count); memset(&vsp_cmd, 0, sizeof(vsp_cmd)); diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 19e7fc7c2c4..1eb86be93d7 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -544,7 +544,7 @@ error: return ret; } -static const struct dma_mapping_ops calgary_dma_ops = { +static struct dma_mapping_ops calgary_dma_ops = { .alloc_coherent = calgary_alloc_coherent, .map_single = calgary_map_single, .unmap_single = calgary_unmap_single, diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index cbecb05551b..37544123896 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -11,7 +11,7 @@ static int forbid_dac __read_mostly; -const struct dma_mapping_ops *dma_ops; +struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); static int iommu_sac_force __read_mostly; @@ -312,6 +312,8 @@ static int dma_release_coherent(struct device *dev, int order, void *vaddr) int dma_supported(struct device *dev, u64 mask) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + #ifdef CONFIG_PCI if (mask > 0xffffffff && forbid_dac > 0) { dev_info(dev, "PCI: Disallowing DAC for device\n"); @@ -319,8 +321,8 @@ int dma_supported(struct device *dev, u64 mask) } #endif - if (dma_ops->dma_supported) - return dma_ops->dma_supported(dev, mask); + if (ops->dma_supported) + return ops->dma_supported(dev, mask); /* Copied from i386. Doesn't make much sense, because it will only work for pci_alloc_coherent. @@ -367,6 +369,7 @@ void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) { + struct dma_mapping_ops *ops = get_dma_ops(dev); void *memory = NULL; struct page *page; unsigned long dma_mask = 0; @@ -435,8 +438,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, /* Let low level make its own zone decisions */ gfp &= ~(GFP_DMA32|GFP_DMA); - if (dma_ops->alloc_coherent) - return dma_ops->alloc_coherent(dev, size, + if (ops->alloc_coherent) + return ops->alloc_coherent(dev, size, dma_handle, gfp); return NULL; } @@ -448,14 +451,14 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, } } - if (dma_ops->alloc_coherent) { + if (ops->alloc_coherent) { free_pages((unsigned long)memory, get_order(size)); gfp &= ~(GFP_DMA|GFP_DMA32); - return dma_ops->alloc_coherent(dev, size, dma_handle, gfp); + return ops->alloc_coherent(dev, size, dma_handle, gfp); } - if (dma_ops->map_simple) { - *dma_handle = dma_ops->map_simple(dev, virt_to_phys(memory), + if (ops->map_simple) { + *dma_handle = ops->map_simple(dev, virt_to_phys(memory), size, PCI_DMA_BIDIRECTIONAL); if (*dma_handle != bad_dma_address) @@ -477,12 +480,14 @@ EXPORT_SYMBOL(dma_alloc_coherent); void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t bus) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + int order = get_order(size); WARN_ON(irqs_disabled()); /* for portability */ if (dma_release_coherent(dev, order, vaddr)) return; - if (dma_ops->unmap_single) - dma_ops->unmap_single(dev, bus, size, 0); + if (ops->unmap_single) + ops->unmap_single(dev, bus, size, 0); free_pages((unsigned long)vaddr, order); } EXPORT_SYMBOL(dma_free_coherent); diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index df5f142657d..744126e6495 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -692,8 +692,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) extern int agp_amd64_init(void); -static const struct dma_mapping_ops gart_dma_ops = { - .mapping_error = NULL, +static struct dma_mapping_ops gart_dma_ops = { .map_single = gart_map_single, .map_simple = gart_map_simple, .unmap_single = gart_unmap_single, diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 792b9179eff..3f91f71cdc3 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -72,21 +72,9 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, return nents; } -/* Make sure we keep the same behaviour */ -static int nommu_mapping_error(dma_addr_t dma_addr) -{ -#ifdef CONFIG_X86_32 - return 0; -#else - return (dma_addr == bad_dma_address); -#endif -} - - -const struct dma_mapping_ops nommu_dma_ops = { +struct dma_mapping_ops nommu_dma_ops = { .map_single = nommu_map_single, .map_sg = nommu_map_sg, - .mapping_error = nommu_mapping_error, .is_phys = 1, }; diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c index 20df839b9c2..c4ce0332759 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -18,7 +18,7 @@ swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); } -const struct dma_mapping_ops swiotlb_dma_ops = { +struct dma_mapping_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, .alloc_coherent = swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, diff --git a/drivers/firewire/fw-iso.c b/drivers/firewire/fw-iso.c index bcbe794a3ea..e14c03dc006 100644 --- a/drivers/firewire/fw-iso.c +++ b/drivers/firewire/fw-iso.c @@ -50,7 +50,7 @@ fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card, address = dma_map_page(card->device, buffer->pages[i], 0, PAGE_SIZE, direction); - if (dma_mapping_error(address)) { + if (dma_mapping_error(card->device, address)) { __free_page(buffer->pages[i]); goto out_pages; } diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 333b12544dd..566672e0bcf 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -953,7 +953,7 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet) payload_bus = dma_map_single(ohci->card.device, packet->payload, packet->payload_length, DMA_TO_DEVICE); - if (dma_mapping_error(payload_bus)) { + if (dma_mapping_error(ohci->card.device, payload_bus)) { packet->ack = RCODE_SEND_ERROR; return -1; } diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 53fc5a641e6..aaff50ebba1 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -543,7 +543,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, orb->response_bus = dma_map_single(device->card->device, &orb->response, sizeof(orb->response), DMA_FROM_DEVICE); - if (dma_mapping_error(orb->response_bus)) + if (dma_mapping_error(device->card->device, orb->response_bus)) goto fail_mapping_response; orb->request.response.high = 0; @@ -577,7 +577,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) + if (dma_mapping_error(device->card->device, orb->base.request_bus)) goto fail_mapping_request; sbp2_send_orb(&orb->base, lu, node_id, generation, @@ -1424,7 +1424,7 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, orb->page_table_bus = dma_map_single(device->card->device, orb->page_table, sizeof(orb->page_table), DMA_TO_DEVICE); - if (dma_mapping_error(orb->page_table_bus)) + if (dma_mapping_error(device->card->device, orb->page_table_bus)) goto fail_page_table; /* @@ -1509,7 +1509,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) + if (dma_mapping_error(device->card->device, orb->base.request_bus)) goto out; sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation, diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c index eaba03273e4..284c9bca517 100644 --- a/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -698,7 +698,7 @@ retry: addr = dma_map_single(&dd->pcidev->dev, tx->txreq.map_addr, tx->map_len, DMA_TO_DEVICE); - if (dma_mapping_error(addr)) { + if (dma_mapping_error(&dd->pcidev->dev, addr)) { ret = -EIO; goto unlock; } diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/drivers/infiniband/hw/ipath/ipath_user_sdma.c index 86e016916cd..82d9a0b5ca2 100644 --- a/drivers/infiniband/hw/ipath/ipath_user_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.c @@ -206,7 +206,7 @@ static int ipath_user_sdma_coalesce(const struct ipath_devdata *dd, dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto free_unmap; } @@ -301,7 +301,7 @@ static int ipath_user_sdma_pin_pages(const struct ipath_devdata *dd, pages[j], 0, flen, DMA_TO_DEVICE); unsigned long fofs = addr & ~PAGE_MASK; - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto done; } @@ -508,7 +508,7 @@ static int ipath_user_sdma_queue_pkts(const struct ipath_devdata *dd, if (page) { dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto free_pbc; } diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 4e36aa7cb3d..cc6858f0b65 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -780,7 +780,7 @@ int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt) return -ENOMEM; dev->eq_table.icm_dma = pci_map_page(dev->pdev, dev->eq_table.icm_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->eq_table.icm_dma)) { + if (pci_dma_mapping_error(dev->pdev, dev->eq_table.icm_dma)) { __free_page(dev->eq_table.icm_page); return -ENOMEM; } diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 1360403b88b..a9653c63f4d 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -242,7 +242,7 @@ static int __devinit pluto_dma_map(struct pluto *pluto) pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf, TS_DMA_BYTES, PCI_DMA_FROMDEVICE); - return pci_dma_mapping_error(pluto->dma_addr); + return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr); } static void pluto_dma_unmap(struct pluto *pluto) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index c3a5db72ddd..5f95e10229b 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -337,7 +337,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, host->align_addr = dma_map_single(mmc_dev(host->mmc), host->align_buffer, 128 * 4, direction); - if (dma_mapping_error(host->align_addr)) + if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) goto fail; BUG_ON(host->align_addr & 0x3); @@ -439,7 +439,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, host->adma_addr = dma_map_single(mmc_dev(host->mmc), host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); - if (dma_mapping_error(host->align_addr)) + if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) goto unmap_entries; BUG_ON(host->adma_addr & 0x3); diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 7a14980f347..18d3eeb7eab 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -482,7 +482,7 @@ static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) goto err; d = dma_map_single(NULL, page, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(d)) { + if (dma_mapping_error(NULL, d)) { free_page((unsigned long)page); goto err; } @@ -505,7 +505,7 @@ static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) goto err; d = dma_map_single(NULL, page, PAGE_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(d)) { + if (dma_mapping_error(NULL, d)) { free_page((unsigned long)page); goto err; } diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 0263bef9cc6..c7cc760a177 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1020,7 +1020,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, mapping = pci_map_page(bp->pdev, page, 0, BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(mapping))) { + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { __free_pages(page, PAGES_PER_SGE_SHIFT); return -ENOMEM; } @@ -1048,7 +1048,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(mapping))) { + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { dev_kfree_skb(skb); return -ENOMEM; } diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index a96331c875e..1b0861d73ab 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -386,7 +386,7 @@ static inline int add_one_rx_buf(void *va, unsigned int len, dma_addr_t mapping; mapping = pci_map_single(pdev, va, len, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(mapping))) + if (unlikely(pci_dma_mapping_error(pdev, mapping))) return -ENOMEM; pci_unmap_addr_set(sd, dma_addr, mapping); diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 1037b133231..19d32a227be 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1790,7 +1790,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(rx->dma_addr)) { + if (pci_dma_mapping_error(nic->pdev, rx->dma_addr)) { dev_kfree_skb_any(rx->skb); rx->skb = NULL; rx->dma_addr = 0; diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index a14561f40db..9350564065e 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1090,7 +1090,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) tx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(tx_ring->buffer_info[i].dma)) { + if (pci_dma_mapping_error(pdev, tx_ring->buffer_info[i].dma)) { ret_val = 4; goto err_nomem; } @@ -1153,7 +1153,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, 2048, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rx_ring->buffer_info[i].dma)) { + if (pci_dma_mapping_error(pdev, rx_ring->buffer_info[i].dma)) { ret_val = 8; goto err_nomem; } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 9c0f56b3c51..d1367789976 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -195,7 +195,7 @@ map_skb: buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(pdev, buffer_info->dma)) { dev_err(&pdev->dev, "RX DMA map failed\n"); adapter->rx_dma_failed++; break; @@ -265,7 +265,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, ps_page->page, 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(ps_page->dma)) { + if (pci_dma_mapping_error(pdev, ps_page->dma)) { dev_err(&adapter->pdev->dev, "RX DMA page map failed\n"); adapter->rx_dma_failed++; @@ -300,7 +300,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_ps_bsize0, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(pdev, buffer_info->dma)) { dev_err(&pdev->dev, "RX DMA map failed\n"); adapter->rx_dma_failed++; /* cleanup skb */ @@ -3344,7 +3344,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, skb->data + offset, size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) { dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); adapter->tx_dma_failed++; return -1; @@ -3382,7 +3382,8 @@ static int e1000_tx_map(struct e1000_adapter *adapter, offset, size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(adapter->pdev, + buffer_info->dma)) { dev_err(&adapter->pdev->dev, "TX DMA page map failed\n"); adapter->tx_dma_failed++; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index e5a6e2e8454..91ec9fdc718 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -260,7 +260,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, pool->buff_size, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_addr)) + if (dma_mapping_error((&adapter->vdev->dev, dma_addr)) goto failure; pool->free_map[free_index] = IBM_VETH_INVALID_MAP; @@ -294,7 +294,7 @@ failure: pool->consumer_index = pool->size - 1; else pool->consumer_index--; - if (!dma_mapping_error(dma_addr)) + if (!dma_mapping_error((&adapter->vdev->dev, dma_addr)) dma_unmap_single(&adapter->vdev->dev, pool->dma_addr[index], pool->buff_size, DMA_FROM_DEVICE); @@ -448,11 +448,11 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) static void ibmveth_cleanup(struct ibmveth_adapter *adapter) { int i; + struct device *dev = &adapter->vdev->dev; if(adapter->buffer_list_addr != NULL) { - if(!dma_mapping_error(adapter->buffer_list_dma)) { - dma_unmap_single(&adapter->vdev->dev, - adapter->buffer_list_dma, 4096, + if (!dma_mapping_error(dev, adapter->buffer_list_dma)) { + dma_unmap_single(dev, adapter->buffer_list_dma, 4096, DMA_BIDIRECTIONAL); adapter->buffer_list_dma = DMA_ERROR_CODE; } @@ -461,9 +461,8 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) } if(adapter->filter_list_addr != NULL) { - if(!dma_mapping_error(adapter->filter_list_dma)) { - dma_unmap_single(&adapter->vdev->dev, - adapter->filter_list_dma, 4096, + if (!dma_mapping_error(dev, adapter->filter_list_dma)) { + dma_unmap_single(dev, adapter->filter_list_dma, 4096, DMA_BIDIRECTIONAL); adapter->filter_list_dma = DMA_ERROR_CODE; } @@ -472,8 +471,8 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) } if(adapter->rx_queue.queue_addr != NULL) { - if(!dma_mapping_error(adapter->rx_queue.queue_dma)) { - dma_unmap_single(&adapter->vdev->dev, + if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { + dma_unmap_single(dev, adapter->rx_queue.queue_dma, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); @@ -535,6 +534,7 @@ static int ibmveth_open(struct net_device *netdev) int rc; union ibmveth_buf_desc rxq_desc; int i; + struct device *dev; ibmveth_debug_printk("open starting\n"); @@ -563,17 +563,19 @@ static int ibmveth_open(struct net_device *netdev) return -ENOMEM; } - adapter->buffer_list_dma = dma_map_single(&adapter->vdev->dev, + dev = &adapter->vdev->dev; + + adapter->buffer_list_dma = dma_map_single(dev, adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); - adapter->filter_list_dma = dma_map_single(&adapter->vdev->dev, + adapter->filter_list_dma = dma_map_single(dev, adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); - adapter->rx_queue.queue_dma = dma_map_single(&adapter->vdev->dev, + adapter->rx_queue.queue_dma = dma_map_single(dev, adapter->rx_queue.queue_addr, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); - if((dma_mapping_error(adapter->buffer_list_dma) ) || - (dma_mapping_error(adapter->filter_list_dma)) || - (dma_mapping_error(adapter->rx_queue.queue_dma))) { + if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || + (dma_mapping_error(dev, adapter->filter_list_dma)) || + (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { ibmveth_error_printk("unable to map filter or buffer list pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -645,7 +647,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->bounce_buffer_dma = dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); - if (dma_mapping_error(adapter->bounce_buffer_dma)) { + if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { ibmveth_error_printk("unable to map bounce buffer\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -922,7 +924,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) buf[1] = 0; } - if (dma_mapping_error(data_dma_addr)) { + if (dma_mapping_error((&adapter->vdev->dev, data_dma_addr)) { if (!firmware_has_feature(FW_FEATURE_CMO)) ibmveth_error_printk("tx: unable to map xmit buffer\n"); skb_copy_from_linear_data(skb, adapter->bounce_buffer, diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index b8d0639c1cd..c46864d626b 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1128,7 +1128,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, msg->data.addr[0] = dma_map_single(port->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(msg->data.addr[0])) + if (dma_mapping_error(port->dev, msg->data.addr[0])) goto recycle_and_drop; msg->dev = port->dev; @@ -1226,7 +1226,7 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx, dma_address = msg->data.addr[0]; dma_length = msg->data.len[0]; - if (!dma_mapping_error(dma_address)) + if (!dma_mapping_error(msg->dev, dma_address)) dma_unmap_single(msg->dev, dma_address, dma_length, DMA_TO_DEVICE); diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index ea3a09aaa84..7df928d3a3d 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -526,7 +526,7 @@ int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt) return -ENOMEM; priv->eq_table.icm_dma = pci_map_page(dev->pdev, priv->eq_table.icm_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(priv->eq_table.icm_dma)) { + if (pci_dma_mapping_error(dev->pdev, priv->eq_table.icm_dma)) { __free_page(priv->eq_table.icm_page); return -ENOMEM; } diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 993d87c9296..edc0fd58898 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -650,7 +650,7 @@ static void pasemi_mac_replenish_rx_ring(const struct net_device *dev, mac->bufsz - LOCAL_SKB_ALIGN, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(dma))) { + if (unlikely(pci_dma_mapping_error(mac->dma_pdev, dma))) { dev_kfree_skb_irq(info->skb); break; } @@ -1519,7 +1519,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) map[0] = pci_map_single(mac->dma_pdev, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE); map_size[0] = skb_headlen(skb); - if (dma_mapping_error(map[0])) + if (pci_dma_mapping_error(mac->dma_pdev, map[0])) goto out_err_nolock; for (i = 0; i < nfrags; i++) { @@ -1529,7 +1529,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) frag->page_offset, frag->size, PCI_DMA_TODEVICE); map_size[i+1] = frag->size; - if (dma_mapping_error(map[i+1])) { + if (pci_dma_mapping_error(mac->dma_pdev, map[i+1])) { nfrags = i; goto out_err_nolock; } diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index e7d48a352be..e82b37bbd6c 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -328,7 +328,7 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, qdev->lrg_buffer_len - QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -1919,7 +1919,7 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -2454,7 +2454,7 @@ static int ql_send_map(struct ql3_adapter *qdev, */ map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -2487,7 +2487,7 @@ static int ql_send_map(struct ql3_adapter *qdev, sizeof(struct oal), PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n", @@ -2514,7 +2514,7 @@ static int ql_send_map(struct ql3_adapter *qdev, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n", qdev->ndev->name, err); @@ -2916,7 +2916,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 9dae40ccf04..86d77d05190 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2512,8 +2512,8 @@ static void stop_nic(struct s2io_nic *nic) * Return Value: * SUCCESS on success or an appropriate -ve value on failure. */ - -static int fill_rx_buffers(struct ring_info *ring, int from_card_up) +static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, + int from_card_up) { struct sk_buff *skb; struct RxD_t *rxdp; @@ -2602,7 +2602,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) rxdp1->Buffer0_ptr = pci_map_single (ring->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp1->Buffer0_ptr)) goto pci_map_failed; rxdp->Control_2 = @@ -2636,7 +2637,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) rxdp3->Buffer0_ptr = pci_map_single(ring->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer0_ptr)) goto pci_map_failed; } else pci_dma_sync_single_for_device(ring->pdev, @@ -2655,7 +2657,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) (ring->pdev, skb->data, ring->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer2_ptr)) goto pci_map_failed; if (from_card_up) { @@ -2664,8 +2667,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error - (rxdp3->Buffer1_ptr)) { + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer1_ptr)) { pci_unmap_single (ring->pdev, (dma_addr_t)(unsigned long) @@ -2806,9 +2809,9 @@ static void free_rx_buffers(struct s2io_nic *sp) } } -static int s2io_chk_rx_buffers(struct ring_info *ring) +static int s2io_chk_rx_buffers(struct s2io_nic *nic, struct ring_info *ring) { - if (fill_rx_buffers(ring, 0) == -ENOMEM) { + if (fill_rx_buffers(nic, ring, 0) == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); } @@ -2848,7 +2851,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) return 0; pkts_processed = rx_intr_handler(ring, budget); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(nic, ring); if (pkts_processed < budget_org) { netif_rx_complete(dev, napi); @@ -2882,7 +2885,7 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget) for (i = 0; i < config->rx_ring_num; i++) { ring = &mac_control->rings[i]; ring_pkts_processed = rx_intr_handler(ring, budget); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(nic, ring); pkts_processed += ring_pkts_processed; budget -= ring_pkts_processed; if (budget <= 0) @@ -2939,7 +2942,8 @@ static void s2io_netpoll(struct net_device *dev) rx_intr_handler(&mac_control->rings[i], 0); for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(&mac_control->rings[i], 0) == -ENOMEM) { + if (fill_rx_buffers(nic, &mac_control->rings[i], 0) == + -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n"); break; @@ -4235,14 +4239,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = pci_map_single(sp->pdev, fifo->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(txdp->Buffer_Pointer)) + if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer)) goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(txdp->Buffer_Pointer)) + if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer)) goto pci_map_failed; txdp->Host_Control = (unsigned long) skb; @@ -4345,7 +4349,7 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) netif_rx_schedule(dev, &ring->napi); } else { rx_intr_handler(ring, 0); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(sp, ring); } return IRQ_HANDLED; @@ -4826,7 +4830,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) */ if (!config->napi) { for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(&mac_control->rings[i]); + s2io_chk_rx_buffers(sp, &mac_control->rings[i]); } writeq(sp->general_int_mask, &bar0->general_int_mask); readl(&bar0->general_int_status); @@ -6859,7 +6863,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) + if (pci_dma_mapping_error(sp->pdev, rxdp1->Buffer0_ptr)) goto memalloc_failed; rxdp->Host_Control = (unsigned long) (*skb); } @@ -6886,12 +6890,13 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) + if (pci_dma_mapping_error(sp->pdev, rxdp3->Buffer2_ptr)) goto memalloc_failed; rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { + if (pci_dma_mapping_error(sp->pdev, + rxdp3->Buffer0_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); @@ -6903,7 +6908,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { + if (pci_dma_mapping_error(sp->pdev, + rxdp3->Buffer1_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); @@ -7187,7 +7193,7 @@ static int s2io_card_up(struct s2io_nic * sp) for (i = 0; i < config->rx_ring_num; i++) { mac_control->rings[i].mtu = dev->mtu; - ret = fill_rx_buffers(&mac_control->rings[i], 1); + ret = fill_rx_buffers(sp, &mac_control->rings[i], 1); if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", dev->name); diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 601b001437c..0d27dd39bc0 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -233,7 +233,7 @@ static inline int efx_init_rx_buffer_skb(struct efx_rx_queue *rx_queue, rx_buf->data, rx_buf->len, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(rx_buf->dma_addr))) { + if (unlikely(pci_dma_mapping_error(efx->pci_dev, rx_buf->dma_addr))) { dev_kfree_skb_any(rx_buf->skb); rx_buf->skb = NULL; return -EIO; @@ -275,7 +275,7 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, 0, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(dma_addr))) { + if (unlikely(pci_dma_mapping_error(efx->pci_dev, dma_addr))) { __free_pages(rx_buf->page, efx->rx_buffer_order); rx_buf->page = NULL; return -EIO; diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 5cdd082ab8f..5e8374ab28e 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -172,7 +172,7 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue, /* Process all fragments */ while (1) { - if (unlikely(pci_dma_mapping_error(dma_addr))) + if (unlikely(pci_dma_mapping_error(pci_dev, dma_addr))) goto pci_err; /* Store fields for marking in the per-fragment final @@ -661,7 +661,8 @@ efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len) tsoh->dma_addr = pci_map_single(tx_queue->efx->pci_dev, TSOH_BUFFER(tsoh), header_len, PCI_DMA_TODEVICE); - if (unlikely(pci_dma_mapping_error(tsoh->dma_addr))) { + if (unlikely(pci_dma_mapping_error(tx_queue->efx->pci_dev, + tsoh->dma_addr))) { kfree(tsoh); return NULL; } @@ -863,7 +864,7 @@ static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off, len, PCI_DMA_TODEVICE); - if (likely(!pci_dma_mapping_error(st->ifc.unmap_addr))) { + if (likely(!pci_dma_mapping_error(efx->pci_dev, st->ifc.unmap_addr))) { st->ifc.unmap_len = len; st->ifc.len = len; st->ifc.dma_addr = st->ifc.unmap_addr; diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 00aa0b108cb..b6435d0d71f 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -452,7 +452,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, /* iommu-map the skb */ buf = pci_map_single(card->pdev, descr->skb->data, SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buf)) { + if (pci_dma_mapping_error(card->pdev, buf)) { dev_kfree_skb_any(descr->skb); descr->skb = NULL; if (netif_msg_rx_err(card) && net_ratelimit()) @@ -691,7 +691,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, unsigned long flags; buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buf)) { + if (pci_dma_mapping_error(card->pdev, buf)) { if (netif_msg_tx_err(card) && net_ratelimit()) dev_err(&card->netdev->dev, "could not iommu-map packet (%p, %i). " "Dropping packet\n", skb->data, skb->len); diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index a645e5028c1..8487ace9d2e 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -506,7 +506,7 @@ static void *alloc_rxbuf_page(struct pci_dev *hwdev, dma_addr_t *dma_handle) return NULL; *dma_handle = pci_map_single(hwdev, buf, PAGE_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(*dma_handle)) { + if (pci_dma_mapping_error(hwdev, *dma_handle)) { free_page((unsigned long)buf); return NULL; } @@ -536,7 +536,7 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev, return NULL; *dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(*dma_handle)) { + if (pci_dma_mapping_error(hwdev, *dma_handle)) { dev_kfree_skb_any(skb); return NULL; } diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 217d506527a..d9769c52734 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -1166,7 +1166,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) bf->skb = skb; bf->skbaddr = pci_map_single(sc->pdev, skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(bf->skbaddr))) { + if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) { ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); dev_kfree_skb(skb); bf->skb = NULL; @@ -1918,7 +1918,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " "skbaddr %llx\n", skb, skb->data, skb->len, (unsigned long long)bf->skbaddr); - if (pci_dma_mapping_error(bf->skbaddr)) { + if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) { ATH5K_ERR(sc, "beacon DMA mapping failed\n"); return -EIO; } diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index c4a7c06793c..61f8fdea2d9 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3525,7 +3525,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost) crq->msg_token = dma_map_single(dev, crq->msgs, PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(crq->msg_token)) + if (dma_mapping_error(dev, crq->msg_token)) goto map_failed; retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, @@ -3618,7 +3618,7 @@ static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost) async_q->size * sizeof(*async_q->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(async_q->msg_token)) { + if (dma_mapping_error(dev, async_q->msg_token)) { dev_err(dev, "Failed to map async queue\n"); goto free_async_crq; } diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 20000ec79b0..6b24b9cdb04 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -859,7 +859,7 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) sizeof(hostdata->madapter_info), DMA_BIDIRECTIONAL); - if (dma_mapping_error(req->buffer)) { + if (dma_mapping_error(hostdata->dev, req->buffer)) { if (!firmware_has_feature(FW_FEATURE_CMO)) dev_err(hostdata->dev, "Unable to map request_buffer for " @@ -1407,7 +1407,7 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, length, DMA_BIDIRECTIONAL); - if (dma_mapping_error(host_config->buffer)) { + if (dma_mapping_error(hostdata->dev, host_config->buffer)) { if (!firmware_has_feature(FW_FEATURE_CMO)) dev_err(hostdata->dev, "dma_mapping error getting host config\n"); diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 3b9514c8f1f..2e13ec00172 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -564,7 +564,7 @@ static int crq_queue_create(struct crq_queue *queue, struct srp_target *target) queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(queue->msg_token)) + if (dma_mapping_error(target->dev, queue->msg_token)) goto map_failed; err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 182146100dc..462a8574dad 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -253,7 +253,7 @@ static int rpavscsi_init_crq_queue(struct crq_queue *queue, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(queue->msg_token)) + if (dma_mapping_error(hostdata->dev, queue->msg_token)) goto map_failed; gather_partition_info(); diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index e81d59d7891..0c716566085 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -313,14 +313,14 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) xfer->tx_dma = dma_map_single(dev, (void *) xfer->tx_buf, xfer->len, DMA_TO_DEVICE); - if (dma_mapping_error(xfer->tx_dma)) + if (dma_mapping_error(dev, xfer->tx_dma)) return -ENOMEM; } if (xfer->rx_buf) { xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, xfer->len, DMA_FROM_DEVICE); - if (dma_mapping_error(xfer->rx_dma)) { + if (dma_mapping_error(dev, xfer->rx_dma)) { if (xfer->tx_buf) dma_unmap_single(dev, xfer->tx_dma, xfer->len, diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index 9149689c79d..87b73e0169c 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c @@ -334,7 +334,7 @@ static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size) hw->dma_rx_tmpbuf_size = size; hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf, size, DMA_FROM_DEVICE); - if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) { + if (dma_mapping_error(hw->dev, hw->dma_rx_tmpbuf_addr)) { kfree(hw->dma_rx_tmpbuf); hw->dma_rx_tmpbuf = 0; hw->dma_rx_tmpbuf_size = 0; @@ -378,7 +378,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) dma_rx_addr = dma_map_single(hw->dev, (void *)t->rx_buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_rx_addr)) + if (dma_mapping_error(hw->dev, dma_rx_addr)) dev_err(hw->dev, "rx dma map error\n"); } } else { @@ -401,7 +401,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) dma_tx_addr = dma_map_single(hw->dev, (void *)t->tx_buf, t->len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_tx_addr)) + if (dma_mapping_error(hw->dev, dma_tx_addr)) dev_err(hw->dev, "tx dma map error\n"); } } else { diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index b1cc148036c..f6f987bb71c 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -836,7 +836,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) if (tx_buf != NULL) { t->tx_dma = dma_map_single(&spi->dev, (void *) tx_buf, len, DMA_TO_DEVICE); - if (dma_mapping_error(t->tx_dma)) { + if (dma_mapping_error(&spi->dev, t->tx_dma)) { dev_dbg(&spi->dev, "dma %cX %d bytes error\n", 'T', len); return -EINVAL; @@ -845,7 +845,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) if (rx_buf != NULL) { t->rx_dma = dma_map_single(&spi->dev, rx_buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(t->rx_dma)) { + if (dma_mapping_error(&spi->dev, t->rx_dma)) { dev_dbg(&spi->dev, "dma %cX %d bytes error\n", 'R', len); if (tx_buf != NULL) diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 0c452c46ab0..067299d6d19 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -353,7 +353,7 @@ static int map_dma_buffers(struct driver_data *drv_data) drv_data->rx_dma = dma_map_single(dev, drv_data->rx, drv_data->rx_map_len, DMA_FROM_DEVICE); - if (dma_mapping_error(drv_data->rx_dma)) + if (dma_mapping_error(dev, drv_data->rx_dma)) return 0; /* Stream map the tx buffer */ @@ -361,7 +361,7 @@ static int map_dma_buffers(struct driver_data *drv_data) drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) { + if (dma_mapping_error(dev, drv_data->tx_dma)) { dma_unmap_single(dev, drv_data->rx_dma, drv_data->rx_map_len, DMA_FROM_DEVICE); return 0; diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 54ac7bea5f8..6fb77fcc497 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -491,7 +491,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) + if (dma_mapping_error(dev, drv_data->tx_dma)) return -1; drv_data->tx_dma_needs_unmap = 1; @@ -516,7 +516,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->len, DMA_FROM_DEVICE); - if (dma_mapping_error(drv_data->rx_dma)) + if (dma_mapping_error(dev, drv_data->rx_dma)) return -1; drv_data->rx_dma_needs_unmap = 1; } @@ -534,7 +534,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) { + if (dma_mapping_error(dev, drv_data->tx_dma)) { if (drv_data->rx_dma) { dma_unmap_single(dev, drv_data->rx_dma, diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h index db351d1296f..a5801ae02e4 100644 --- a/include/asm-alpha/dma-mapping.h +++ b/include/asm-alpha/dma-mapping.h @@ -24,8 +24,8 @@ pci_unmap_sg(alpha_gendev_to_pci(dev), sg, nents, dir) #define dma_supported(dev, mask) \ pci_dma_supported(alpha_gendev_to_pci(dev), mask) -#define dma_mapping_error(addr) \ - pci_dma_mapping_error(addr) +#define dma_mapping_error(dev, addr) \ + pci_dma_mapping_error(alpha_gendev_to_pci(dev), addr) #else /* no PCI - no IOMMU. */ @@ -45,7 +45,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, #define dma_unmap_page(dev, addr, size, dir) ((void)0) #define dma_unmap_sg(dev, sg, nents, dir) ((void)0) -#define dma_mapping_error(addr) (0) +#define dma_mapping_error(dev, addr) (0) #endif /* !CONFIG_PCI */ diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index d31fd49ff79..2a14302c17a 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -106,7 +106,7 @@ extern dma_addr_t pci_map_page(struct pci_dev *, struct page *, /* Test for pci_map_single or pci_map_page having generated an error. */ static inline int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) { return dma_addr == 0; } diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h index e99406a7bec..f41335ba633 100644 --- a/include/asm-arm/dma-mapping.h +++ b/include/asm-arm/dma-mapping.h @@ -56,7 +56,7 @@ static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) /* * DMA errors are defined by all-bits-set in the DMA address. */ -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return dma_addr == ~0; } diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h index 57dc672bab8..0399359ab5d 100644 --- a/include/asm-avr32/dma-mapping.h +++ b/include/asm-avr32/dma-mapping.h @@ -35,7 +35,7 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) /* * dma_map_single can't fail as it is implemented now. */ -static inline int dma_mapping_error(dma_addr_t addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t addr) { return 0; } diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h index edc8d1bfaae..cb2fb25ff8d 100644 --- a/include/asm-cris/dma-mapping.h +++ b/include/asm-cris/dma-mapping.h @@ -120,7 +120,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h index 2e8966ca030..b2898877c07 100644 --- a/include/asm-frv/dma-mapping.h +++ b/include/asm-frv/dma-mapping.h @@ -126,7 +126,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele } static inline -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h index e2468f894d2..82cd0cb1c3f 100644 --- a/include/asm-generic/dma-mapping-broken.h +++ b/include/asm-generic/dma-mapping-broken.h @@ -61,7 +61,7 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, #define dma_sync_sg_for_device dma_sync_sg_for_cpu extern int -dma_mapping_error(dma_addr_t dma_addr); +dma_mapping_error(struct device *dev, dma_addr_t dma_addr); extern int dma_supported(struct device *dev, u64 mask); diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h index 783ab9944d7..189486c3f92 100644 --- a/include/asm-generic/dma-mapping.h +++ b/include/asm-generic/dma-mapping.h @@ -144,9 +144,9 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return pci_dma_mapping_error(dma_addr); + return pci_dma_mapping_error(to_pci_dev(dev), dma_addr); } diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h index 25c10e96b2b..37b3706226e 100644 --- a/include/asm-generic/pci-dma-compat.h +++ b/include/asm-generic/pci-dma-compat.h @@ -99,9 +99,9 @@ pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, } static inline int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) { - return dma_mapping_error(dma_addr); + return dma_mapping_error(&pdev->dev, dma_addr); } #endif diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index 0721a5e8271..a6d50c77b6b 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -54,7 +54,7 @@ typedef void ia64_mv_dma_sync_single_for_cpu (struct device *, dma_addr_t, size_ typedef void ia64_mv_dma_sync_sg_for_cpu (struct device *, struct scatterlist *, int, int); typedef void ia64_mv_dma_sync_single_for_device (struct device *, dma_addr_t, size_t, int); typedef void ia64_mv_dma_sync_sg_for_device (struct device *, struct scatterlist *, int, int); -typedef int ia64_mv_dma_mapping_error (dma_addr_t dma_addr); +typedef int ia64_mv_dma_mapping_error(struct device *, dma_addr_t dma_addr); typedef int ia64_mv_dma_supported (struct device *, u64); typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t, int, struct dma_attrs *); diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h index a26cdeb46a5..91f7944333d 100644 --- a/include/asm-m68k/dma-mapping.h +++ b/include/asm-m68k/dma-mapping.h @@ -84,7 +84,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *s { } -static inline int dma_mapping_error(dma_addr_t handle) +static inline int dma_mapping_error(struct device *dev, dma_addr_t handle) { return 0; } diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index 230b3f1b69b..c64afb40cd0 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h @@ -42,7 +42,7 @@ extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); -extern int dma_mapping_error(dma_addr_t dma_addr); +extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr); extern int dma_supported(struct device *dev, u64 mask); static inline int diff --git a/include/asm-mn10300/dma-mapping.h b/include/asm-mn10300/dma-mapping.h index 7c882fca9ec..ccae8f6c632 100644 --- a/include/asm-mn10300/dma-mapping.h +++ b/include/asm-mn10300/dma-mapping.h @@ -182,7 +182,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } static inline -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h index c6c0e9ff6bd..53af696f23d 100644 --- a/include/asm-parisc/dma-mapping.h +++ b/include/asm-parisc/dma-mapping.h @@ -248,6 +248,6 @@ void * sba_get_iommu(struct parisc_device *dev); #endif /* At the moment, we panic on error for IOMMU resource exaustion */ -#define dma_mapping_error(x) 0 +#define dma_mapping_error(dev, x) 0 #endif diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index 74c54978098..c7ca45f97dd 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -415,7 +415,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { #ifdef CONFIG_PPC64 return (dma_addr == DMA_ERROR_CODE); diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h index 22cc419389f..6c0b8a2de14 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h @@ -171,7 +171,7 @@ static inline int dma_get_cache_alignment(void) return L1_CACHE_BYTES; } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return dma_addr == 0; } diff --git a/include/asm-sparc/dma-mapping_64.h b/include/asm-sparc/dma-mapping_64.h index 38cbec76a33..bfa64f9702d 100644 --- a/include/asm-sparc/dma-mapping_64.h +++ b/include/asm-sparc/dma-mapping_64.h @@ -135,7 +135,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, /* No flushing needed to sync cpu writes to the device. */ } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return (dma_addr == DMA_ERROR_CODE); } diff --git a/include/asm-sparc/pci_32.h b/include/asm-sparc/pci_32.h index b93b6c79e08..0ee949d220c 100644 --- a/include/asm-sparc/pci_32.h +++ b/include/asm-sparc/pci_32.h @@ -154,7 +154,8 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, #define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0) -static inline int pci_dma_mapping_error(dma_addr_t dma_addr) +static inline int pci_dma_mapping_error(struct pci_dev *pdev, + dma_addr_t dma_addr) { return (dma_addr == PCI_DMA_ERROR_CODE); } diff --git a/include/asm-sparc/pci_64.h b/include/asm-sparc/pci_64.h index f59f2571295..4f79a54948f 100644 --- a/include/asm-sparc/pci_64.h +++ b/include/asm-sparc/pci_64.h @@ -140,9 +140,10 @@ extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask); #define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) #define PCI64_ADDR_BASE 0xfffc000000000000UL -static inline int pci_dma_mapping_error(dma_addr_t dma_addr) +static inline int pci_dma_mapping_error(struct pci_dev *pdev, + dma_addr_t dma_addr) { - return dma_mapping_error(dma_addr); + return dma_mapping_error(&pdev->dev, dma_addr); } #ifdef CONFIG_PCI diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h index 87a715367a1..3c034f48fdb 100644 --- a/include/asm-x86/device.h +++ b/include/asm-x86/device.h @@ -5,6 +5,9 @@ struct dev_archdata { #ifdef CONFIG_ACPI void *acpi_handle; #endif +#ifdef CONFIG_X86_64 +struct dma_mapping_ops *dma_ops; +#endif #ifdef CONFIG_DMAR void *iommu; /* hook for IOMMU specific extension */ #endif diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h index c2ddd3d1b88..0eaa9bf6011 100644 --- a/include/asm-x86/dma-mapping.h +++ b/include/asm-x86/dma-mapping.h @@ -17,7 +17,8 @@ extern int panic_on_overflow; extern int force_iommu; struct dma_mapping_ops { - int (*mapping_error)(dma_addr_t dma_addr); + int (*mapping_error)(struct device *dev, + dma_addr_t dma_addr); void* (*alloc_coherent)(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp); void (*free_coherent)(struct device *dev, size_t size, @@ -56,14 +57,32 @@ struct dma_mapping_ops { int is_phys; }; -extern const struct dma_mapping_ops *dma_ops; +extern struct dma_mapping_ops *dma_ops; -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) { - if (dma_ops->mapping_error) - return dma_ops->mapping_error(dma_addr); +#ifdef CONFIG_X86_32 + return dma_ops; +#else + if (unlikely(!dev) || !dev->archdata.dma_ops) + return dma_ops; + else + return dev->archdata.dma_ops; +#endif +} + +/* Make sure we keep the same behaviour */ +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ +#ifdef CONFIG_X86_32 + return 0; +#else + struct dma_mapping_ops *ops = get_dma_ops(dev); + if (ops->mapping_error) + return ops->mapping_error(dev, dma_addr); return (dma_addr == bad_dma_address); +#endif } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) @@ -83,44 +102,53 @@ static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_single(hwdev, virt_to_phys(ptr), size, direction); + return ops->map_single(hwdev, virt_to_phys(ptr), size, direction); } static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->unmap_single) - dma_ops->unmap_single(dev, addr, size, direction); + if (ops->unmap_single) + ops->unmap_single(dev, addr, size, direction); } static inline int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_sg(hwdev, sg, nents, direction); + return ops->map_sg(hwdev, sg, nents, direction); } static inline void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->unmap_sg) - dma_ops->unmap_sg(hwdev, sg, nents, direction); + if (ops->unmap_sg) + ops->unmap_sg(hwdev, sg, nents, direction); } static inline void dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_for_cpu) - dma_ops->sync_single_for_cpu(hwdev, dma_handle, size, - direction); + if (ops->sync_single_for_cpu) + ops->sync_single_for_cpu(hwdev, dma_handle, size, direction); flush_write_buffers(); } @@ -128,10 +156,11 @@ static inline void dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_for_device) - dma_ops->sync_single_for_device(hwdev, dma_handle, size, - direction); + if (ops->sync_single_for_device) + ops->sync_single_for_device(hwdev, dma_handle, size, direction); flush_write_buffers(); } @@ -139,11 +168,12 @@ static inline void dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, int direction) { - BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_range_for_cpu) - dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, - size, direction); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); + if (ops->sync_single_range_for_cpu) + ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, + size, direction); flush_write_buffers(); } @@ -152,11 +182,12 @@ dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, int direction) { - BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_range_for_device) - dma_ops->sync_single_range_for_device(hwdev, dma_handle, - offset, size, direction); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); + if (ops->sync_single_range_for_device) + ops->sync_single_range_for_device(hwdev, dma_handle, + offset, size, direction); flush_write_buffers(); } @@ -164,9 +195,11 @@ static inline void dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_sg_for_cpu) - dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); + if (ops->sync_sg_for_cpu) + ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); flush_write_buffers(); } @@ -174,9 +207,11 @@ static inline void dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_sg_for_device) - dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction); + if (ops->sync_sg_for_device) + ops->sync_sg_for_device(hwdev, sg, nelems, direction); flush_write_buffers(); } @@ -185,9 +220,11 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, size_t offset, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_single(dev, page_to_phys(page)+offset, - size, direction); + return ops->map_single(dev, page_to_phys(page) + offset, + size, direction); } static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, diff --git a/include/asm-x86/swiotlb.h b/include/asm-x86/swiotlb.h index c706a744263..2730b351afc 100644 --- a/include/asm-x86/swiotlb.h +++ b/include/asm-x86/swiotlb.h @@ -35,7 +35,7 @@ extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction); -extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr); +extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); extern void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); extern int swiotlb_dma_supported(struct device *hwdev, u64 mask); diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h index 3c7d537dd15..51882ae3db4 100644 --- a/include/asm-xtensa/dma-mapping.h +++ b/include/asm-xtensa/dma-mapping.h @@ -139,7 +139,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, consistent_sync(sg_virt(sg), sg->length, dir); } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 7d51cbca49a..75ae6d8aba4 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -758,7 +758,7 @@ static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, } dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction); - if (!dma_mapping_error(dma_addr)) { + if (!dma_mapping_error(&c->pdev->dev, dma_addr)) { #ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 if ((sizeof(dma_addr_t) > 4) && c->pae_support) { *mptr++ = cpu_to_le32(0x7C020002); diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 4bf8cade9db..e530026eedf 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -427,9 +427,9 @@ static inline int ssb_dma_mapping_error(struct ssb_device *dev, dma_addr_t addr) { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: - return pci_dma_mapping_error(addr); + return pci_dma_mapping_error(dev->bus->host_pci, addr); case SSB_BUSTYPE_SSB: - return dma_mapping_error(addr); + return dma_mapping_error(dev->dev, addr); default: __ssb_dma_not_implemented(dev); } diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 90b529f7a15..936e333e7ce 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1590,7 +1590,7 @@ static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr) { if (dev->dma_ops) return dev->dma_ops->mapping_error(dev, dma_addr); - return dma_mapping_error(dma_addr); + return dma_mapping_error(dev->dma_device, dma_addr); } /** diff --git a/lib/swiotlb.c b/lib/swiotlb.c index d568894df8c..977edbdbc1d 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -492,7 +492,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, */ dma_addr_t handle; handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE); - if (swiotlb_dma_mapping_error(handle)) + if (swiotlb_dma_mapping_error(hwdev, handle)) return NULL; ret = bus_to_virt(handle); @@ -824,7 +824,7 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, } int -swiotlb_dma_mapping_error(dma_addr_t dma_addr) +swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) { return (dma_addr == virt_to_bus(io_tlb_overflow_buffer)); } diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index a19b22b452a..84d328329d9 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -169,7 +169,8 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp, (void *) vec->sge[xdr_sge_no].iov_base + sge_off, sge_bytes, DMA_TO_DEVICE); - if (dma_mapping_error(sge[sge_no].addr)) + if (dma_mapping_error(xprt->sc_cm_id->device->dma_device, + sge[sge_no].addr)) goto err; sge_off = 0; sge_no++; -- cgit v1.2.3-70-g09d2 From 19fd6231279be3c3bdd02ed99f9b0eb195978064 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 25 Jul 2008 19:45:32 -0700 Subject: mm: spinlock tree_lock mapping->tree_lock has no read lockers. convert the lock from an rwlock to a spinlock. Signed-off-by: Nick Piggin Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Hugh Dickins Cc: "Paul E. McKenney" Reviewed-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 4 ++-- fs/inode.c | 2 +- include/asm-arm/cacheflush.h | 4 ++-- include/asm-parisc/cacheflush.h | 4 ++-- include/linux/fs.h | 2 +- mm/filemap.c | 10 +++++----- mm/migrate.c | 11 +++++------ mm/page-writeback.c | 12 ++++++------ mm/swap_state.c | 10 +++++----- mm/swapfile.c | 4 ++-- mm/truncate.c | 6 +++--- mm/vmscan.c | 8 ++++---- 12 files changed, 38 insertions(+), 39 deletions(-) (limited to 'include/asm-arm') diff --git a/fs/buffer.c b/fs/buffer.c index d48caee12e2..109b261192d 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -706,7 +706,7 @@ static int __set_page_dirty(struct page *page, if (TestSetPageDirty(page)) return 0; - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); if (page->mapping) { /* Race with truncate? */ WARN_ON_ONCE(warn && !PageUptodate(page)); @@ -719,7 +719,7 @@ static int __set_page_dirty(struct page *page, radix_tree_tag_set(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); } - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); return 1; diff --git a/fs/inode.c b/fs/inode.c index c36d9480335..35b6414522e 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -209,7 +209,7 @@ void inode_init_once(struct inode *inode) INIT_LIST_HEAD(&inode->i_dentry); INIT_LIST_HEAD(&inode->i_devices); INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC); - rwlock_init(&inode->i_data.tree_lock); + spin_lock_init(&inode->i_data.tree_lock); spin_lock_init(&inode->i_data.i_mmap_lock); INIT_LIST_HEAD(&inode->i_data.private_list); spin_lock_init(&inode->i_data.private_lock); diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 70b0fe724b6..03cf1ee977b 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -424,9 +424,9 @@ static inline void flush_anon_page(struct vm_area_struct *vma, } #define flush_dcache_mmap_lock(mapping) \ - write_lock_irq(&(mapping)->tree_lock) + spin_lock_irq(&(mapping)->tree_lock) #define flush_dcache_mmap_unlock(mapping) \ - write_unlock_irq(&(mapping)->tree_lock) + spin_unlock_irq(&(mapping)->tree_lock) #define flush_icache_user_range(vma,page,addr,len) \ flush_dcache_page(page) diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h index 2f1e1b05440..b7ca6dc7fdd 100644 --- a/include/asm-parisc/cacheflush.h +++ b/include/asm-parisc/cacheflush.h @@ -45,9 +45,9 @@ void flush_cache_mm(struct mm_struct *mm); extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping) \ - write_lock_irq(&(mapping)->tree_lock) + spin_lock_irq(&(mapping)->tree_lock) #define flush_dcache_mmap_unlock(mapping) \ - write_unlock_irq(&(mapping)->tree_lock) + spin_unlock_irq(&(mapping)->tree_lock) #define flush_icache_page(vma,page) do { \ flush_kernel_dcache_page(page); \ diff --git a/include/linux/fs.h b/include/linux/fs.h index 49d8eb7a71b..53d2edb709b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -499,7 +499,7 @@ struct backing_dev_info; struct address_space { struct inode *host; /* owner: inode, block_device */ struct radix_tree_root page_tree; /* radix tree of all pages */ - rwlock_t tree_lock; /* and rwlock protecting it */ + spinlock_t tree_lock; /* and lock protecting it */ unsigned int i_mmap_writable;/* count VM_SHARED mappings */ struct prio_tree_root i_mmap; /* tree of private and shared mappings */ struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ diff --git a/mm/filemap.c b/mm/filemap.c index feb8448d861..2ed8b0389c5 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -109,7 +109,7 @@ /* * Remove a page from the page cache and free it. Caller has to make * sure the page is locked and that nobody else uses it - or that usage - * is safe. The caller must hold a write_lock on the mapping's tree_lock. + * is safe. The caller must hold the mapping's tree_lock. */ void __remove_from_page_cache(struct page *page) { @@ -141,9 +141,9 @@ void remove_from_page_cache(struct page *page) BUG_ON(!PageLocked(page)); - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); __remove_from_page_cache(page); - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); } static int sync_page(void *word) @@ -469,7 +469,7 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, page->mapping = mapping; page->index = offset; - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); error = radix_tree_insert(&mapping->page_tree, offset, page); if (likely(!error)) { mapping->nrpages++; @@ -480,7 +480,7 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, page_cache_release(page); } - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); radix_tree_preload_end(); } else mem_cgroup_uncharge_cache_page(page); diff --git a/mm/migrate.c b/mm/migrate.c index 3ca6392e82c..153572fb60b 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -323,7 +323,7 @@ static int migrate_page_move_mapping(struct address_space *mapping, return 0; } - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); pslot = radix_tree_lookup_slot(&mapping->page_tree, page_index(page)); @@ -331,12 +331,12 @@ static int migrate_page_move_mapping(struct address_space *mapping, expected_count = 2 + !!PagePrivate(page); if (page_count(page) != expected_count || (struct page *)radix_tree_deref_slot(pslot) != page) { - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); return -EAGAIN; } if (!page_freeze_refs(page, expected_count)) { - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); return -EAGAIN; } @@ -373,10 +373,9 @@ static int migrate_page_move_mapping(struct address_space *mapping, __dec_zone_page_state(page, NR_FILE_PAGES); __inc_zone_page_state(newpage, NR_FILE_PAGES); - write_unlock_irq(&mapping->tree_lock); - if (!PageSwapCache(newpage)) { + spin_unlock_irq(&mapping->tree_lock); + if (!PageSwapCache(newpage)) mem_cgroup_uncharge_cache_page(page); - } return 0; } diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 94c6d8988ab..24de8b65fdb 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -1088,7 +1088,7 @@ int __set_page_dirty_nobuffers(struct page *page) if (!mapping) return 1; - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); mapping2 = page_mapping(page); if (mapping2) { /* Race with truncate? */ BUG_ON(mapping2 != mapping); @@ -1102,7 +1102,7 @@ int __set_page_dirty_nobuffers(struct page *page) radix_tree_tag_set(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); } - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); if (mapping->host) { /* !PageAnon && !swapper_space */ __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); @@ -1258,7 +1258,7 @@ int test_clear_page_writeback(struct page *page) struct backing_dev_info *bdi = mapping->backing_dev_info; unsigned long flags; - write_lock_irqsave(&mapping->tree_lock, flags); + spin_lock_irqsave(&mapping->tree_lock, flags); ret = TestClearPageWriteback(page); if (ret) { radix_tree_tag_clear(&mapping->page_tree, @@ -1269,7 +1269,7 @@ int test_clear_page_writeback(struct page *page) __bdi_writeout_inc(bdi); } } - write_unlock_irqrestore(&mapping->tree_lock, flags); + spin_unlock_irqrestore(&mapping->tree_lock, flags); } else { ret = TestClearPageWriteback(page); } @@ -1287,7 +1287,7 @@ int test_set_page_writeback(struct page *page) struct backing_dev_info *bdi = mapping->backing_dev_info; unsigned long flags; - write_lock_irqsave(&mapping->tree_lock, flags); + spin_lock_irqsave(&mapping->tree_lock, flags); ret = TestSetPageWriteback(page); if (!ret) { radix_tree_tag_set(&mapping->page_tree, @@ -1300,7 +1300,7 @@ int test_set_page_writeback(struct page *page) radix_tree_tag_clear(&mapping->page_tree, page_index(page), PAGECACHE_TAG_DIRTY); - write_unlock_irqrestore(&mapping->tree_lock, flags); + spin_unlock_irqrestore(&mapping->tree_lock, flags); } else { ret = TestSetPageWriteback(page); } diff --git a/mm/swap_state.c b/mm/swap_state.c index 3e3381d6c7e..2c217e33d49 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -39,7 +39,7 @@ static struct backing_dev_info swap_backing_dev_info = { struct address_space swapper_space = { .page_tree = RADIX_TREE_INIT(GFP_ATOMIC|__GFP_NOWARN), - .tree_lock = __RW_LOCK_UNLOCKED(swapper_space.tree_lock), + .tree_lock = __SPIN_LOCK_UNLOCKED(swapper_space.tree_lock), .a_ops = &swap_aops, .i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear), .backing_dev_info = &swap_backing_dev_info, @@ -80,7 +80,7 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) SetPageSwapCache(page); set_page_private(page, entry.val); - write_lock_irq(&swapper_space.tree_lock); + spin_lock_irq(&swapper_space.tree_lock); error = radix_tree_insert(&swapper_space.page_tree, entry.val, page); if (likely(!error)) { @@ -88,7 +88,7 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) __inc_zone_page_state(page, NR_FILE_PAGES); INC_CACHE_INFO(add_total); } - write_unlock_irq(&swapper_space.tree_lock); + spin_unlock_irq(&swapper_space.tree_lock); radix_tree_preload_end(); if (unlikely(error)) { @@ -182,9 +182,9 @@ void delete_from_swap_cache(struct page *page) entry.val = page_private(page); - write_lock_irq(&swapper_space.tree_lock); + spin_lock_irq(&swapper_space.tree_lock); __delete_from_swap_cache(page); - write_unlock_irq(&swapper_space.tree_lock); + spin_unlock_irq(&swapper_space.tree_lock); swap_free(entry); page_cache_release(page); diff --git a/mm/swapfile.c b/mm/swapfile.c index 2f33edb8bee..af283933c14 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -369,13 +369,13 @@ int remove_exclusive_swap_page(struct page *page) retval = 0; if (p->swap_map[swp_offset(entry)] == 1) { /* Recheck the page count with the swapcache lock held.. */ - write_lock_irq(&swapper_space.tree_lock); + spin_lock_irq(&swapper_space.tree_lock); if ((page_count(page) == 2) && !PageWriteback(page)) { __delete_from_swap_cache(page); SetPageDirty(page); retval = 1; } - write_unlock_irq(&swapper_space.tree_lock); + spin_unlock_irq(&swapper_space.tree_lock); } spin_unlock(&swap_lock); diff --git a/mm/truncate.c b/mm/truncate.c index b8961cb6341..e68443d7456 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -349,18 +349,18 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL)) return 0; - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); if (PageDirty(page)) goto failed; BUG_ON(PagePrivate(page)); __remove_from_page_cache(page); - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); ClearPageUptodate(page); page_cache_release(page); /* pagecache ref */ return 1; failed: - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); return 0; } diff --git a/mm/vmscan.c b/mm/vmscan.c index 0075eac1cd0..8f71761bc4b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -399,7 +399,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) BUG_ON(!PageLocked(page)); BUG_ON(mapping != page_mapping(page)); - write_lock_irq(&mapping->tree_lock); + spin_lock_irq(&mapping->tree_lock); /* * The non racy check for a busy page. * @@ -436,17 +436,17 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) if (PageSwapCache(page)) { swp_entry_t swap = { .val = page_private(page) }; __delete_from_swap_cache(page); - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); swap_free(swap); } else { __remove_from_page_cache(page); - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); } return 1; cannot_free: - write_unlock_irq(&mapping->tree_lock); + spin_unlock_irq(&mapping->tree_lock); return 0; } -- cgit v1.2.3-70-g09d2 From aafe0ad81d7458b6c61eeb39068432683c70c9a9 Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Sat, 12 Jul 2008 11:55:42 +0100 Subject: [ARM] pxa: PXA25x UDC - Fix warning during build Fixes an unterminated ' warning building PXA25X UDC. Signed-off-by: Ian Molton --- include/asm-arm/arch-pxa/pxa25x-udc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/arch-pxa/pxa25x-udc.h b/include/asm-arm/arch-pxa/pxa25x-udc.h index 840305916b6..1b80a4805a6 100644 --- a/include/asm-arm/arch-pxa/pxa25x-udc.h +++ b/include/asm-arm/arch-pxa/pxa25x-udc.h @@ -2,7 +2,7 @@ #define _ASM_ARCH_PXA25X_UDC_H #ifdef _ASM_ARCH_PXA27X_UDC_H -#error You can't include both PXA25x and PXA27x UDC support +#error "You can't include both PXA25x and PXA27x UDC support" #endif #define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */ -- cgit v1.2.3-70-g09d2 From 7f2da1e7d0330395e5e9e350b879b98a1ea495df Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 10 May 2008 20:44:54 -0400 Subject: [PATCH] kill altroot long overdue... Signed-off-by: Al Viro --- fs/namei.c | 89 +------------------------------------------ fs/namespace.c | 8 +--- fs/open.c | 3 +- include/asm-alpha/namei.h | 17 --------- include/asm-arm/namei.h | 25 ------------ include/asm-avr32/namei.h | 7 ---- include/asm-blackfin/namei.h | 19 --------- include/asm-cris/namei.h | 17 --------- include/asm-frv/namei.h | 18 --------- include/asm-h8300/namei.h | 17 --------- include/asm-ia64/namei.h | 25 ------------ include/asm-m32r/namei.h | 17 --------- include/asm-m68k/namei.h | 17 --------- include/asm-m68knommu/namei.h | 1 - include/asm-mips/namei.h | 11 ------ include/asm-mn10300/namei.h | 22 ----------- include/asm-parisc/namei.h | 17 --------- include/asm-powerpc/namei.h | 20 ---------- include/asm-s390/namei.h | 21 ---------- include/asm-sh/namei.h | 17 --------- include/asm-sparc/namei.h | 8 ---- include/asm-sparc64/namei.h | 1 - include/asm-um/namei.h | 6 --- include/asm-v850/namei.h | 17 --------- include/asm-x86/namei.h | 11 ------ include/asm-xtensa/namei.h | 26 ------------- include/linux/fs_struct.h | 3 +- include/linux/namei.h | 1 - kernel/exec_domain.c | 1 - kernel/exit.c | 2 - kernel/fork.c | 7 ---- 31 files changed, 5 insertions(+), 466 deletions(-) delete mode 100644 include/asm-alpha/namei.h delete mode 100644 include/asm-arm/namei.h delete mode 100644 include/asm-avr32/namei.h delete mode 100644 include/asm-blackfin/namei.h delete mode 100644 include/asm-cris/namei.h delete mode 100644 include/asm-frv/namei.h delete mode 100644 include/asm-h8300/namei.h delete mode 100644 include/asm-ia64/namei.h delete mode 100644 include/asm-m32r/namei.h delete mode 100644 include/asm-m68k/namei.h delete mode 100644 include/asm-m68knommu/namei.h delete mode 100644 include/asm-mips/namei.h delete mode 100644 include/asm-mn10300/namei.h delete mode 100644 include/asm-parisc/namei.h delete mode 100644 include/asm-powerpc/namei.h delete mode 100644 include/asm-s390/namei.h delete mode 100644 include/asm-sh/namei.h delete mode 100644 include/asm-sparc/namei.h delete mode 100644 include/asm-sparc64/namei.h delete mode 100644 include/asm-um/namei.h delete mode 100644 include/asm-v850/namei.h delete mode 100644 include/asm-x86/namei.h delete mode 100644 include/asm-xtensa/namei.h (limited to 'include/asm-arm') diff --git a/fs/namei.c b/fs/namei.c index 6c76e1ee9c4..095818089ac 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) @@ -562,27 +561,16 @@ out_unlock: return result; } -static int __emul_lookup_dentry(const char *, struct nameidata *); - /* SMP-safe */ -static __always_inline int +static __always_inline void walk_init_root(const char *name, struct nameidata *nd) { struct fs_struct *fs = current->fs; read_lock(&fs->lock); - if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { - nd->path = fs->altroot; - path_get(&fs->altroot); - read_unlock(&fs->lock); - if (__emul_lookup_dentry(name,nd)) - return 0; - read_lock(&fs->lock); - } nd->path = fs->root; path_get(&fs->root); read_unlock(&fs->lock); - return 1; } /* @@ -623,12 +611,9 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l if (*link == '/') { path_put(&nd->path); - if (!walk_init_root(link, nd)) - /* weird __emul_prefix() stuff did it */ - goto out; + walk_init_root(link, nd); } res = link_path_walk(link, nd); -out: if (nd->depth || res || nd->last_type!=LAST_NORM) return res; /* @@ -1077,67 +1062,6 @@ static int path_walk(const char *name, struct nameidata *nd) return link_path_walk(name, nd); } -/* - * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if - * everything is done. Returns 0 and drops input nd, if lookup failed; - */ -static int __emul_lookup_dentry(const char *name, struct nameidata *nd) -{ - if (path_walk(name, nd)) - return 0; /* something went wrong... */ - - if (!nd->path.dentry->d_inode || - S_ISDIR(nd->path.dentry->d_inode->i_mode)) { - struct path old_path = nd->path; - struct qstr last = nd->last; - int last_type = nd->last_type; - struct fs_struct *fs = current->fs; - - /* - * NAME was not found in alternate root or it's a directory. - * Try to find it in the normal root: - */ - nd->last_type = LAST_ROOT; - read_lock(&fs->lock); - nd->path = fs->root; - path_get(&fs->root); - read_unlock(&fs->lock); - if (path_walk(name, nd) == 0) { - if (nd->path.dentry->d_inode) { - path_put(&old_path); - return 1; - } - path_put(&nd->path); - } - nd->path = old_path; - nd->last = last; - nd->last_type = last_type; - } - return 1; -} - -void set_fs_altroot(void) -{ - char *emul = __emul_prefix(); - struct nameidata nd; - struct path path = {}, old_path; - int err; - struct fs_struct *fs = current->fs; - - if (!emul) - goto set_it; - err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); - if (!err) - path = nd.path; -set_it: - write_lock(&fs->lock); - old_path = fs->altroot; - fs->altroot = path; - write_unlock(&fs->lock); - if (old_path.dentry) - path_put(&old_path); -} - /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ static int do_path_lookup(int dfd, const char *name, unsigned int flags, struct nameidata *nd) @@ -1153,14 +1077,6 @@ static int do_path_lookup(int dfd, const char *name, if (*name=='/') { read_lock(&fs->lock); - if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { - nd->path = fs->altroot; - path_get(&fs->altroot); - read_unlock(&fs->lock); - if (__emul_lookup_dentry(name,nd)) - goto out; /* found in altroot */ - read_lock(&fs->lock); - } nd->path = fs->root; path_get(&fs->root); read_unlock(&fs->lock); @@ -1194,7 +1110,6 @@ static int do_path_lookup(int dfd, const char *name, } retval = path_walk(name, nd); -out: if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && nd->path.dentry->d_inode)) audit_inode(name, nd->path.dentry); diff --git a/fs/namespace.c b/fs/namespace.c index f30b11e2240..c4fcf48acef 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1972,7 +1972,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, struct fs_struct *fs) { struct mnt_namespace *new_ns; - struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; + struct vfsmount *rootmnt = NULL, *pwdmnt = NULL; struct vfsmount *p, *q; new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); @@ -2015,10 +2015,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, pwdmnt = p; fs->pwd.mnt = mntget(q); } - if (p == fs->altroot.mnt) { - altrootmnt = p; - fs->altroot.mnt = mntget(q); - } } p = next_mnt(p, mnt_ns->root); q = next_mnt(q, new_ns->root); @@ -2029,8 +2025,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, mntput(rootmnt); if (pwdmnt) mntput(pwdmnt); - if (altrootmnt) - mntput(altrootmnt); return new_ns; } diff --git a/fs/open.c b/fs/open.c index 8e02d42bfe4..d3a2a00f52d 100644 --- a/fs/open.c +++ b/fs/open.c @@ -548,7 +548,7 @@ asmlinkage long sys_chroot(const char __user * filename) struct nameidata nd; int error; - error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); + error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &nd); if (error) goto out; @@ -561,7 +561,6 @@ asmlinkage long sys_chroot(const char __user * filename) goto dput_and_out; set_fs_root(current->fs, &nd.path); - set_fs_altroot(); error = 0; dput_and_out: path_put(&nd.path); diff --git a/include/asm-alpha/namei.h b/include/asm-alpha/namei.h deleted file mode 100644 index 5cc9bb39499..00000000000 --- a/include/asm-alpha/namei.h +++ /dev/null @@ -1,17 +0,0 @@ -/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $ - * linux/include/asm-alpha/namei.h - * - * Included from linux/fs/namei.c - */ - -#ifndef __ALPHA_NAMEI_H -#define __ALPHA_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __ALPHA_NAMEI_H */ diff --git a/include/asm-arm/namei.h b/include/asm-arm/namei.h deleted file mode 100644 index a402d3b9d0f..00000000000 --- a/include/asm-arm/namei.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * linux/include/asm-arm/namei.h - * - * Routines to handle famous /usr/gnemul - * Derived from the Sparc version of this file - * - * Included from linux/fs/namei.c - */ - -#ifndef __ASMARM_NAMEI_H -#define __ASMARM_NAMEI_H - -#define ARM_BSD_EMUL "usr/gnemul/bsd/" - -static inline char *__emul_prefix(void) -{ - switch (current->personality) { - case PER_BSD: - return ARM_BSD_EMUL; - default: - return NULL; - } -} - -#endif /* __ASMARM_NAMEI_H */ diff --git a/include/asm-avr32/namei.h b/include/asm-avr32/namei.h deleted file mode 100644 index f0a26de06ca..00000000000 --- a/include/asm-avr32/namei.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_AVR32_NAMEI_H -#define __ASM_AVR32_NAMEI_H - -/* This dummy routine may be changed to something useful */ -#define __emul_prefix() NULL - -#endif /* __ASM_AVR32_NAMEI_H */ diff --git a/include/asm-blackfin/namei.h b/include/asm-blackfin/namei.h deleted file mode 100644 index 8b89a2d65cb..00000000000 --- a/include/asm-blackfin/namei.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * linux/include/asm/namei.h - * - * Included from linux/fs/namei.c - * - * Changes made by Lineo Inc. May 2001 - */ - -#ifndef __BFIN_NAMEI_H -#define __BFIN_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif diff --git a/include/asm-cris/namei.h b/include/asm-cris/namei.h deleted file mode 100644 index 8a3be7a6d9f..00000000000 --- a/include/asm-cris/namei.h +++ /dev/null @@ -1,17 +0,0 @@ -/* $Id: namei.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ - * linux/include/asm-cris/namei.h - * - * Included from linux/fs/namei.c - */ - -#ifndef __CRIS_NAMEI_H -#define __CRIS_NAMEI_H - -/* used to find file-system prefixes for doing emulations - * see for example asm-sparc/namei.h - * we don't use it... - */ - -#define __emul_prefix() NULL - -#endif /* __CRIS_NAMEI_H */ diff --git a/include/asm-frv/namei.h b/include/asm-frv/namei.h deleted file mode 100644 index 4ea57171d95..00000000000 --- a/include/asm-frv/namei.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * include/asm-frv/namei.h - * - * Included from linux/fs/namei.c - */ - -#ifndef __ASM_NAMEI_H -#define __ASM_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif - diff --git a/include/asm-h8300/namei.h b/include/asm-h8300/namei.h deleted file mode 100644 index ab6f196db6e..00000000000 --- a/include/asm-h8300/namei.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * linux/include/asm-h8300/namei.h - * - * Included from linux/fs/namei.c - */ - -#ifndef __H8300_NAMEI_H -#define __H8300_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif diff --git a/include/asm-ia64/namei.h b/include/asm-ia64/namei.h deleted file mode 100644 index 78e76807908..00000000000 --- a/include/asm-ia64/namei.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _ASM_IA64_NAMEI_H -#define _ASM_IA64_NAMEI_H - -/* - * Modified 1998, 1999, 2001 - * David Mosberger-Tang , Hewlett-Packard Co - */ - -#include -#include - -#define EMUL_PREFIX_LINUX_IA32 "/emul/ia32-linux/" - -static inline char * -__emul_prefix (void) -{ - switch (current->personality) { - case PER_LINUX32: - return EMUL_PREFIX_LINUX_IA32; - default: - return NULL; - } -} - -#endif /* _ASM_IA64_NAMEI_H */ diff --git a/include/asm-m32r/namei.h b/include/asm-m32r/namei.h deleted file mode 100644 index 210f8056b80..00000000000 --- a/include/asm-m32r/namei.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _ASM_M32R_NAMEI_H -#define _ASM_M32R_NAMEI_H - -/* - * linux/include/asm-m32r/namei.h - * - * Included from linux/fs/namei.c - */ - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* _ASM_M32R_NAMEI_H */ diff --git a/include/asm-m68k/namei.h b/include/asm-m68k/namei.h deleted file mode 100644 index f33f243b644..00000000000 --- a/include/asm-m68k/namei.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * linux/include/asm-m68k/namei.h - * - * Included from linux/fs/namei.c - */ - -#ifndef __M68K_NAMEI_H -#define __M68K_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif diff --git a/include/asm-m68knommu/namei.h b/include/asm-m68knommu/namei.h deleted file mode 100644 index 31a85d27b93..00000000000 --- a/include/asm-m68knommu/namei.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-mips/namei.h b/include/asm-mips/namei.h deleted file mode 100644 index a6605a75246..00000000000 --- a/include/asm-mips/namei.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ASM_NAMEI_H -#define _ASM_NAMEI_H - -/* - * This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - */ - -#define __emul_prefix() NULL - -#endif /* _ASM_NAMEI_H */ diff --git a/include/asm-mn10300/namei.h b/include/asm-mn10300/namei.h deleted file mode 100644 index bd9ce94aeb6..00000000000 --- a/include/asm-mn10300/namei.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Emulation stuff - * - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ - -#ifndef _ASM_NAMEI_H -#define _ASM_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* _ASM_NAMEI_H */ diff --git a/include/asm-parisc/namei.h b/include/asm-parisc/namei.h deleted file mode 100644 index 8d29b3d9fb3..00000000000 --- a/include/asm-parisc/namei.h +++ /dev/null @@ -1,17 +0,0 @@ -/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $ - * linux/include/asm-parisc/namei.h - * - * Included from linux/fs/namei.c - */ - -#ifndef __PARISC_NAMEI_H -#define __PARISC_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __PARISC_NAMEI_H */ diff --git a/include/asm-powerpc/namei.h b/include/asm-powerpc/namei.h deleted file mode 100644 index 657443474a6..00000000000 --- a/include/asm-powerpc/namei.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _ASM_POWERPC_NAMEI_H -#define _ASM_POWERPC_NAMEI_H - -#ifdef __KERNEL__ - -/* - * Adapted from include/asm-alpha/namei.h - * - * Included from fs/namei.c - */ - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_NAMEI_H */ diff --git a/include/asm-s390/namei.h b/include/asm-s390/namei.h deleted file mode 100644 index 3e286bdde4b..00000000000 --- a/include/asm-s390/namei.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * include/asm-s390/namei.h - * - * S390 version - * - * Derived from "include/asm-i386/namei.h" - * - * Included from linux/fs/namei.c - */ - -#ifndef __S390_NAMEI_H -#define __S390_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __S390_NAMEI_H */ diff --git a/include/asm-sh/namei.h b/include/asm-sh/namei.h deleted file mode 100644 index 338a5d94714..00000000000 --- a/include/asm-sh/namei.h +++ /dev/null @@ -1,17 +0,0 @@ -/* $Id: namei.h,v 1.3 2000/07/04 06:24:49 gniibe Exp $ - * linux/include/asm-sh/namei.h - * - * Included from linux/fs/namei.c - */ - -#ifndef __ASM_SH_NAMEI_H -#define __ASM_SH_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __ASM_SH_NAMEI_H */ diff --git a/include/asm-sparc/namei.h b/include/asm-sparc/namei.h deleted file mode 100644 index eff944b8e32..00000000000 --- a/include/asm-sparc/namei.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ___ASM_SPARC_NAMEI_H -#define ___ASM_SPARC_NAMEI_H -#if defined(__sparc__) && defined(__arch64__) -#include -#else -#include -#endif -#endif diff --git a/include/asm-sparc64/namei.h b/include/asm-sparc64/namei.h deleted file mode 100644 index 1344a910ba2..00000000000 --- a/include/asm-sparc64/namei.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-um/namei.h b/include/asm-um/namei.h deleted file mode 100644 index 002984d5bc8..00000000000 --- a/include/asm-um/namei.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_NAMEI_H -#define __UM_NAMEI_H - -#include "asm/arch/namei.h" - -#endif diff --git a/include/asm-v850/namei.h b/include/asm-v850/namei.h deleted file mode 100644 index ee8339b2384..00000000000 --- a/include/asm-v850/namei.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * linux/include/asm-v850/namei.h - * - * Included from linux/fs/namei.c - */ - -#ifndef __V850_NAMEI_H__ -#define __V850_NAMEI_H__ - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __V850_NAMEI_H__ */ diff --git a/include/asm-x86/namei.h b/include/asm-x86/namei.h deleted file mode 100644 index 415ef5d9550..00000000000 --- a/include/asm-x86/namei.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ASM_X86_NAMEI_H -#define _ASM_X86_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* _ASM_X86_NAMEI_H */ diff --git a/include/asm-xtensa/namei.h b/include/asm-xtensa/namei.h deleted file mode 100644 index 3fdff039d27..00000000000 --- a/include/asm-xtensa/namei.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * include/asm-xtensa/namei.h - * - * Included from linux/fs/namei.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 - 2005 Tensilica Inc. - */ - -#ifndef _XTENSA_NAMEI_H -#define _XTENSA_NAMEI_H - -#ifdef __KERNEL__ - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __KERNEL__ */ -#endif /* _XTENSA_NAMEI_H */ diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index 282f5421912..9e5a06e78d0 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -7,7 +7,7 @@ struct fs_struct { atomic_t count; rwlock_t lock; int umask; - struct path root, pwd, altroot; + struct path root, pwd; }; #define INIT_FS { \ @@ -19,7 +19,6 @@ struct fs_struct { extern struct kmem_cache *fs_cachep; extern void exit_fs(struct task_struct *); -extern void set_fs_altroot(void); extern void set_fs_root(struct fs_struct *, struct path *); extern void set_fs_pwd(struct fs_struct *, struct path *); extern struct fs_struct *copy_fs_struct(struct fs_struct *); diff --git a/include/linux/namei.h b/include/linux/namei.h index 3cf62d26d49..768773d5785 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -47,7 +47,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; #define LOOKUP_DIRECTORY 2 #define LOOKUP_CONTINUE 4 #define LOOKUP_PARENT 16 -#define LOOKUP_NOALT 32 #define LOOKUP_REVAL 64 /* * Intent data diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c index c1ef192aa65..0d407e88673 100644 --- a/kernel/exec_domain.c +++ b/kernel/exec_domain.c @@ -168,7 +168,6 @@ __set_personality(u_long personality) current->personality = personality; oep = current_thread_info()->exec_domain; current_thread_info()->exec_domain = ep; - set_fs_altroot(); module_put(oep->module); return 0; diff --git a/kernel/exit.c b/kernel/exit.c index 6cdf60712bd..0caf590548a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -565,8 +565,6 @@ void put_fs_struct(struct fs_struct *fs) if (atomic_dec_and_test(&fs->count)) { path_put(&fs->root); path_put(&fs->pwd); - if (fs->altroot.dentry) - path_put(&fs->altroot); kmem_cache_free(fs_cachep, fs); } } diff --git a/kernel/fork.c b/kernel/fork.c index abb3ed6298f..5e050c1317c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -657,13 +657,6 @@ static struct fs_struct *__copy_fs_struct(struct fs_struct *old) path_get(&old->root); fs->pwd = old->pwd; path_get(&old->pwd); - if (old->altroot.dentry) { - fs->altroot = old->altroot; - path_get(&old->altroot); - } else { - fs->altroot.mnt = NULL; - fs->altroot.dentry = NULL; - } read_unlock(&old->lock); } return fs; -- cgit v1.2.3-70-g09d2 From 6cab48602996cdbcb277375a8107d53e21e8c9b9 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 27 Jul 2008 04:23:31 +0100 Subject: [ARM] 5179/1: Replace obsolete IRQT_* and __IRQT_* values with IRQ_TYPE_* IRQT_* and __IRQT_* were obsoleted long ago by patch [3692/1]. Remove them completely. Sed script for the reference: s/__IRQT_RISEDGE/IRQ_TYPE_EDGE_RISING/g s/__IRQT_FALEDGE/IRQ_TYPE_EDGE_FALLING/g s/__IRQT_LOWLVL/IRQ_TYPE_LEVEL_LOW/g s/__IRQT_HIGHLVL/IRQ_TYPE_LEVEL_HIGH/g s/IRQT_RISING/IRQ_TYPE_EDGE_RISING/g s/IRQT_FALLING/IRQ_TYPE_EDGE_FALLING/g s/IRQT_BOTHEDGE/IRQ_TYPE_EDGE_BOTH/g s/IRQT_LOW/IRQ_TYPE_LEVEL_LOW/g s/IRQT_HIGH/IRQ_TYPE_LEVEL_HIGH/g s/IRQT_PROBE/IRQ_TYPE_PROBE/g s/IRQT_NOEDGE/IRQ_TYPE_NONE/g Signed-off-by: Dmitry Baryshkov Signed-off-by: Russell King --- Documentation/arm/Interrupts | 10 ++---- arch/arm/common/locomo.c | 10 +++--- arch/arm/common/sa1111.c | 14 ++++---- arch/arm/mach-at91/board-cap9adk.c | 6 ++-- arch/arm/mach-at91/irq.c | 8 ++--- arch/arm/mach-ep93xx/core.c | 14 ++++---- arch/arm/mach-imx/irq.c | 12 +++---- arch/arm/mach-ixp2000/core.c | 8 ++--- arch/arm/mach-ixp23xx/core.c | 10 +++--- arch/arm/mach-ixp23xx/roadrunner.c | 4 +-- arch/arm/mach-ixp4xx/avila-pci.c | 8 ++--- arch/arm/mach-ixp4xx/common.c | 10 +++--- arch/arm/mach-ixp4xx/coyote-pci.c | 4 +-- arch/arm/mach-ixp4xx/dsmg600-pci.c | 12 +++---- arch/arm/mach-ixp4xx/fsg-pci.c | 6 ++-- arch/arm/mach-ixp4xx/gateway7001-pci.c | 4 +-- arch/arm/mach-ixp4xx/gtwx5715-pci.c | 8 ++--- arch/arm/mach-ixp4xx/ixdp425-pci.c | 8 ++--- arch/arm/mach-ixp4xx/ixdpg425-pci.c | 4 +-- arch/arm/mach-ixp4xx/nas100d-pci.c | 10 +++--- arch/arm/mach-ixp4xx/nslu2-pci.c | 6 ++-- arch/arm/mach-ixp4xx/wg302v2-pci.c | 4 +-- arch/arm/mach-ks8695/irq.c | 10 +++--- arch/arm/mach-netx/generic.c | 8 ++--- arch/arm/mach-omap1/board-osk.c | 6 ++-- arch/arm/mach-omap1/board-palmz71.c | 4 +-- arch/arm/mach-omap1/board-voiceblue.c | 8 ++--- arch/arm/mach-omap1/fpga.c | 2 +- arch/arm/mach-omap2/board-apollon.c | 6 ++-- arch/arm/mach-orion5x/db88f5281-setup.c | 4 +-- arch/arm/mach-orion5x/irq.c | 12 +++---- arch/arm/mach-orion5x/rd88f5182-setup.c | 4 +-- arch/arm/mach-orion5x/ts209-setup.c | 4 +-- arch/arm/mach-pnx4008/irq.c | 10 +++--- arch/arm/mach-pxa/cm-x270-pci.c | 2 +- arch/arm/mach-pxa/lpd270.c | 2 +- arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/mach-pxa/mainstone.c | 2 +- arch/arm/mach-pxa/sharpsl_pm.c | 8 ++--- arch/arm/mach-pxa/trizeps4.c | 2 +- arch/arm/mach-sa1100/cerf.c | 2 +- arch/arm/mach-sa1100/h3600.c | 2 +- arch/arm/mach-sa1100/irq.c | 8 ++--- arch/arm/mach-sa1100/neponset.c | 2 +- arch/arm/mach-sa1100/pleb.c | 2 +- arch/arm/plat-mxc/gpio.c | 10 +++--- arch/arm/plat-omap/gpio.c | 28 ++++++++-------- arch/arm/plat-s3c24xx/irq.c | 12 +++---- drivers/ata/pata_ixp4xx_cf.c | 2 +- drivers/input/touchscreen/corgi_ts.c | 8 ++--- drivers/input/touchscreen/mainstone-wm97xx.c | 2 +- drivers/mfd/asic3.c | 14 ++++---- drivers/mfd/tc6393xb.c | 2 +- drivers/pcmcia/soc_common.c | 12 +++---- drivers/video/am200epd.c | 2 +- drivers/video/omap/sossi.c | 2 +- include/asm-arm/arch-pnx4008/irqs.h | 48 ++++++++++++++-------------- include/asm-arm/arch-pxa/idp.h | 10 +++--- include/asm-arm/arch-pxa/pcm990_baseboard.h | 14 ++++---- include/asm-arm/arch-sa1100/ide.h | 2 +- include/asm-arm/irq.h | 17 ---------- 61 files changed, 227 insertions(+), 250 deletions(-) (limited to 'include/asm-arm') diff --git a/Documentation/arm/Interrupts b/Documentation/arm/Interrupts index 0d3dbf1099b..c202ed35d7d 100644 --- a/Documentation/arm/Interrupts +++ b/Documentation/arm/Interrupts @@ -138,14 +138,8 @@ So, what's changed? Set active the IRQ edge(s)/level. This replaces the SA1111 INTPOL manipulation, and the set_GPIO_IRQ_edge() - function. Type should be one of the following: - - #define IRQT_NOEDGE (0) - #define IRQT_RISING (__IRQT_RISEDGE) - #define IRQT_FALLING (__IRQT_FALEDGE) - #define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE) - #define IRQT_LOW (__IRQT_LOWLVL) - #define IRQT_HIGH (__IRQT_HIGHLVL) + function. Type should be one of IRQ_TYPE_xxx defined in + 3. set_GPIO_IRQ_edge() is obsolete, and should be replaced by set_irq_type. diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index c3c3a333904..85579654d3b 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -331,17 +331,17 @@ static int locomo_gpio_type(unsigned int irq, unsigned int type) mask = 1 << (irq - LOCOMO_IRQ_GPIO_START); - if (type == IRQT_PROBE) { + if (type == IRQ_TYPE_PROBE) { if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) return 0; - type = __IRQT_RISEDGE | __IRQT_FALEDGE; + type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; } - if (type & __IRQT_RISEDGE) + if (type & IRQ_TYPE_EDGE_RISING) GPIO_IRQ_rising_edge |= mask; else GPIO_IRQ_rising_edge &= ~mask; - if (type & __IRQT_FALEDGE) + if (type & IRQ_TYPE_EDGE_FALLING) GPIO_IRQ_falling_edge |= mask; else GPIO_IRQ_falling_edge &= ~mask; @@ -473,7 +473,7 @@ static void locomo_setup_irq(struct locomo *lchip) /* * Install handler for IRQ_LOCOMO_HW. */ - set_irq_type(lchip->irq, IRQT_FALLING); + set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING); set_irq_chip_data(lchip->irq, irqbase); set_irq_chained_handler(lchip->irq, locomo_handler); diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 0a8e1ff2af8..f6d3fdda706 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -241,14 +241,14 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ip0; - if (flags == IRQT_PROBE) + if (flags == IRQ_TYPE_PROBE) return 0; - if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) + if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0) return -EINVAL; ip0 = sa1111_readl(mapbase + SA1111_INTPOL0); - if (flags & __IRQT_RISEDGE) + if (flags & IRQ_TYPE_EDGE_RISING) ip0 &= ~mask; else ip0 |= mask; @@ -338,14 +338,14 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags) void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ip1; - if (flags == IRQT_PROBE) + if (flags == IRQ_TYPE_PROBE) return 0; - if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) + if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0) return -EINVAL; ip1 = sa1111_readl(mapbase + SA1111_INTPOL1); - if (flags & __IRQT_RISEDGE) + if (flags & IRQ_TYPE_EDGE_RISING) ip1 &= ~mask; else ip1 |= mask; @@ -427,7 +427,7 @@ static void sa1111_setup_irq(struct sa1111 *sachip) /* * Register SA1111 interrupt */ - set_irq_type(sachip->irq, IRQT_RISING); + set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); set_irq_data(sachip->irq, irqbase); set_irq_chained_handler(sachip->irq, sa1111_irq_handler); } diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 8a2a958639d..b4b67eb1cbc 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -330,10 +330,10 @@ static void __init cap9adk_board_init(void) /* Serial */ at91_add_device_serial(); /* USB Host */ - set_irq_type(AT91CAP9_ID_UHP, IRQT_HIGH); + set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH); at91_add_device_usbh(&cap9adk_usbh_data); /* USB HS */ - set_irq_type(AT91CAP9_ID_UDPHS, IRQT_HIGH); + set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH); at91_add_device_usba(&cap9adk_usba_udc_data); /* SPI */ at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices)); @@ -350,7 +350,7 @@ static void __init cap9adk_board_init(void) /* I2C */ at91_add_device_i2c(NULL, 0); /* LCD Controller */ - set_irq_type(AT91CAP9_ID_LCDC, IRQT_HIGH); + set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH); at91_add_device_lcdc(&cap9adk_lcdc_data); /* AC97 */ at91_add_device_ac97(&cap9adk_ac97_data); diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index 78a5cdb746d..ca87587b2b4 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c @@ -56,19 +56,19 @@ static int at91_aic_set_type(unsigned irq, unsigned type) unsigned int smr, srctype; switch (type) { - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: srctype = AT91_AIC_SRCTYPE_HIGH; break; - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: srctype = AT91_AIC_SRCTYPE_RISING; break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ srctype = AT91_AIC_SRCTYPE_LOW; else return -EINVAL; break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ srctype = AT91_AIC_SRCTYPE_FALLING; else diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 1d7bca6aa44..5fed5760850 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -226,7 +226,7 @@ static void ep93xx_gpio_irq_ack(unsigned int irq) int port = line >> 3; int port_mask = 1 << (line & 7); - if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) { + if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { gpio_int_type2[port] ^= port_mask; /* switch edge direction */ ep93xx_gpio_update_int_params(port); } @@ -240,7 +240,7 @@ static void ep93xx_gpio_irq_mask_ack(unsigned int irq) int port = line >> 3; int port_mask = 1 << (line & 7); - if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) + if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) gpio_int_type2[port] ^= port_mask; /* switch edge direction */ gpio_int_unmasked[port] &= ~port_mask; @@ -283,27 +283,27 @@ static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type) gpio_direction_input(gpio); switch (type) { - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: gpio_int_type1[port] |= port_mask; gpio_int_type2[port] |= port_mask; desc->handle_irq = handle_edge_irq; break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: gpio_int_type1[port] |= port_mask; gpio_int_type2[port] &= ~port_mask; desc->handle_irq = handle_edge_irq; break; - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: gpio_int_type1[port] &= ~port_mask; gpio_int_type2[port] |= port_mask; desc->handle_irq = handle_level_irq; break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: gpio_int_type1[port] &= ~port_mask; gpio_int_type2[port] &= ~port_mask; desc->handle_irq = handle_level_irq; break; - case IRQT_BOTHEDGE: + case IRQ_TYPE_EDGE_BOTH: gpio_int_type1[port] |= port_mask; /* set initial polarity based on current input level */ if (gpio_get_value(gpio)) diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c index e6695c4e623..e1b1f028b93 100644 --- a/arch/arm/mach-imx/irq.c +++ b/arch/arm/mach-imx/irq.c @@ -111,7 +111,7 @@ imx_gpio_irq_type(unsigned int _irq, unsigned int type) reg = irq >> 5; bit = 1 << (irq % 32); - if (type == IRQT_PROBE) { + if (type == IRQ_TYPE_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or GPIOs set to alternate function during probe */ /* TODO: support probe */ @@ -120,7 +120,7 @@ imx_gpio_irq_type(unsigned int _irq, unsigned int type) // return 0; // if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2))) // return 0; -// type = __IRQT_RISEDGE | __IRQT_FALEDGE; +// type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; } GIUS(reg) |= bit; @@ -128,19 +128,19 @@ imx_gpio_irq_type(unsigned int _irq, unsigned int type) DEBUG_IRQ("setting type of irq %d to ", _irq); - if (type & __IRQT_RISEDGE) { + if (type & IRQ_TYPE_EDGE_RISING) { DEBUG_IRQ("rising edges\n"); irq_type = 0x0; } - if (type & __IRQT_FALEDGE) { + if (type & IRQ_TYPE_EDGE_FALLING) { DEBUG_IRQ("falling edges\n"); irq_type = 0x1; } - if (type & __IRQT_LOWLVL) { + if (type & IRQ_TYPE_LEVEL_LOW) { DEBUG_IRQ("low level\n"); irq_type = 0x3; } - if (type & __IRQT_HIGHLVL) { + if (type & IRQ_TYPE_LEVEL_HIGH) { DEBUG_IRQ("high level\n"); irq_type = 0x2; } diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 81cdc826720..daf28074134 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -329,19 +329,19 @@ static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type) /* * Then, set the proper trigger type. */ - if (type & IRQT_FALLING) + if (type & IRQ_TYPE_EDGE_FALLING) GPIO_IRQ_falling_edge |= 1 << line; else GPIO_IRQ_falling_edge &= ~(1 << line); - if (type & IRQT_RISING) + if (type & IRQ_TYPE_EDGE_RISING) GPIO_IRQ_rising_edge |= 1 << line; else GPIO_IRQ_rising_edge &= ~(1 << line); - if (type & IRQT_LOW) + if (type & IRQ_TYPE_LEVEL_LOW) GPIO_IRQ_level_low |= 1 << line; else GPIO_IRQ_level_low &= ~(1 << line); - if (type & IRQT_HIGH) + if (type & IRQ_TYPE_LEVEL_HIGH) GPIO_IRQ_level_high |= 1 << line; else GPIO_IRQ_level_high &= ~(1 << line); diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c index 5fea5a13293..df16a4eac49 100644 --- a/arch/arm/mach-ixp23xx/core.c +++ b/arch/arm/mach-ixp23xx/core.c @@ -126,23 +126,23 @@ static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type) return -EINVAL; switch (type) { - case IRQT_BOTHEDGE: + case IRQ_TYPE_EDGE_BOTH: int_style = IXP23XX_GPIO_STYLE_TRANSITIONAL; irq_type = IXP23XX_IRQ_EDGE; break; - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: int_style = IXP23XX_GPIO_STYLE_RISING_EDGE; irq_type = IXP23XX_IRQ_EDGE; break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: int_style = IXP23XX_GPIO_STYLE_FALLING_EDGE; irq_type = IXP23XX_IRQ_EDGE; break; - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: int_style = IXP23XX_GPIO_STYLE_ACTIVE_HIGH; irq_type = IXP23XX_IRQ_LEVEL; break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: int_style = IXP23XX_GPIO_STYLE_ACTIVE_LOW; irq_type = IXP23XX_IRQ_LEVEL; break; diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c index f0f70ba1e46..896ff9f840d 100644 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ b/arch/arm/mach-ixp23xx/roadrunner.c @@ -110,8 +110,8 @@ static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) static void __init roadrunner_pci_preinit(void) { - set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW); - set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_LOW); + set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW); ixp23xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/avila-pci.c b/arch/arm/mach-ixp4xx/avila-pci.c index 3f867691d9f..c6e044befcc 100644 --- a/arch/arm/mach-ixp4xx/avila-pci.c +++ b/arch/arm/mach-ixp4xx/avila-pci.c @@ -30,10 +30,10 @@ void __init avila_pci_preinit(void) { - set_irq_type(IRQ_AVILA_PCI_INTA, IRQT_LOW); - set_irq_type(IRQ_AVILA_PCI_INTB, IRQT_LOW); - set_irq_type(IRQ_AVILA_PCI_INTC, IRQT_LOW); - set_irq_type(IRQ_AVILA_PCI_INTD, IRQT_LOW); + set_irq_type(IRQ_AVILA_PCI_INTA, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_AVILA_PCI_INTB, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_AVILA_PCI_INTC, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_AVILA_PCI_INTD, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 3781b3db9f4..3947c506b4f 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -142,23 +142,23 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) return -EINVAL; switch (type){ - case IRQT_BOTHEDGE: + case IRQ_TYPE_EDGE_BOTH: int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL; irq_type = IXP4XX_IRQ_EDGE; break; - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: int_style = IXP4XX_GPIO_STYLE_RISING_EDGE; irq_type = IXP4XX_IRQ_EDGE; break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE; irq_type = IXP4XX_IRQ_EDGE; break; - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH; irq_type = IXP4XX_IRQ_LEVEL; break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW; irq_type = IXP4XX_IRQ_LEVEL; break; diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c index ad2e5b97966..be4f4a208b9 100644 --- a/arch/arm/mach-ixp4xx/coyote-pci.c +++ b/arch/arm/mach-ixp4xx/coyote-pci.c @@ -27,8 +27,8 @@ void __init coyote_pci_preinit(void) { - set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW); - set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQT_LOW); + set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/dsmg600-pci.c b/arch/arm/mach-ixp4xx/dsmg600-pci.c index 9db7e1f4201..926d15f885f 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-pci.c +++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c @@ -25,12 +25,12 @@ void __init dsmg600_pci_preinit(void) { - set_irq_type(IRQ_DSMG600_PCI_INTA, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTB, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTC, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTD, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTE, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTF, IRQT_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTA, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTB, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTC, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTD, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTE, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_DSMG600_PCI_INTF, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/fsg-pci.c b/arch/arm/mach-ixp4xx/fsg-pci.c index f19f3f6feda..ca12a9ca083 100644 --- a/arch/arm/mach-ixp4xx/fsg-pci.c +++ b/arch/arm/mach-ixp4xx/fsg-pci.c @@ -25,9 +25,9 @@ void __init fsg_pci_preinit(void) { - set_irq_type(IRQ_FSG_PCI_INTA, IRQT_LOW); - set_irq_type(IRQ_FSG_PCI_INTB, IRQT_LOW); - set_irq_type(IRQ_FSG_PCI_INTC, IRQT_LOW); + set_irq_type(IRQ_FSG_PCI_INTA, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_FSG_PCI_INTB, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_FSG_PCI_INTC, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c index 6abf568322d..afd1dc14e59 100644 --- a/arch/arm/mach-ixp4xx/gateway7001-pci.c +++ b/arch/arm/mach-ixp4xx/gateway7001-pci.c @@ -29,8 +29,8 @@ void __init gateway7001_pci_preinit(void) { - set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW); - set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW); + set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c index 49dec786880..20960704183 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-pci.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c @@ -41,10 +41,10 @@ */ void __init gtwx5715_pci_preinit(void) { - set_irq_type(GTWX5715_PCI_SLOT0_INTA_IRQ, IRQT_LOW); - set_irq_type(GTWX5715_PCI_SLOT0_INTB_IRQ, IRQT_LOW); - set_irq_type(GTWX5715_PCI_SLOT1_INTA_IRQ, IRQT_LOW); - set_irq_type(GTWX5715_PCI_SLOT1_INTB_IRQ, IRQT_LOW); + set_irq_type(GTWX5715_PCI_SLOT0_INTA_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_type(GTWX5715_PCI_SLOT0_INTB_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_type(GTWX5715_PCI_SLOT1_INTA_IRQ, IRQ_TYPE_LEVEL_LOW); + set_irq_type(GTWX5715_PCI_SLOT1_INTB_IRQ, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c index 40879600481..7d9bb4d2310 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -27,10 +27,10 @@ void __init ixdp425_pci_preinit(void) { - set_irq_type(IRQ_IXDP425_PCI_INTA, IRQT_LOW); - set_irq_type(IRQ_IXDP425_PCI_INTB, IRQT_LOW); - set_irq_type(IRQ_IXDP425_PCI_INTC, IRQT_LOW); - set_irq_type(IRQ_IXDP425_PCI_INTD, IRQT_LOW); + set_irq_type(IRQ_IXDP425_PCI_INTA, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXDP425_PCI_INTB, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXDP425_PCI_INTC, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXDP425_PCI_INTD, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c index d1e75b7dc3b..37d9f2e8f60 100644 --- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c @@ -25,8 +25,8 @@ void __init ixdpg425_pci_preinit(void) { - set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW); - set_irq_type(IRQ_IXP4XX_GPIO7, IRQT_LOW); + set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c index b8ebaf4a9c8..1088426fdce 100644 --- a/arch/arm/mach-ixp4xx/nas100d-pci.c +++ b/arch/arm/mach-ixp4xx/nas100d-pci.c @@ -24,11 +24,11 @@ void __init nas100d_pci_preinit(void) { - set_irq_type(IRQ_NAS100D_PCI_INTA, IRQT_LOW); - set_irq_type(IRQ_NAS100D_PCI_INTB, IRQT_LOW); - set_irq_type(IRQ_NAS100D_PCI_INTC, IRQT_LOW); - set_irq_type(IRQ_NAS100D_PCI_INTD, IRQT_LOW); - set_irq_type(IRQ_NAS100D_PCI_INTE, IRQT_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTA, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTB, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTC, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTD, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTE, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c index 04661fef97f..4429b8448b6 100644 --- a/arch/arm/mach-ixp4xx/nslu2-pci.c +++ b/arch/arm/mach-ixp4xx/nslu2-pci.c @@ -24,9 +24,9 @@ void __init nslu2_pci_preinit(void) { - set_irq_type(IRQ_NSLU2_PCI_INTA, IRQT_LOW); - set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW); - set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW); + set_irq_type(IRQ_NSLU2_PCI_INTA, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_NSLU2_PCI_INTB, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_NSLU2_PCI_INTC, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c index 6588f2c758e..0f00feab67f 100644 --- a/arch/arm/mach-ixp4xx/wg302v2-pci.c +++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c @@ -29,8 +29,8 @@ void __init wg302v2_pci_preinit(void) { - set_irq_type(IRQ_IXP4XX_GPIO8, IRQT_LOW); - set_irq_type(IRQ_IXP4XX_GPIO9, IRQT_LOW); + set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW); + set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW); ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c index 4c3ab43e104..0b06941a1ee 100644 --- a/arch/arm/mach-ks8695/irq.c +++ b/arch/arm/mach-ks8695/irq.c @@ -72,21 +72,21 @@ static int ks8695_irq_set_type(unsigned int irqno, unsigned int type) ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC); switch (type) { - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: mode = IOPC_TM_HIGH; level_triggered = 1; break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: mode = IOPC_TM_LOW; level_triggered = 1; break; - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: mode = IOPC_TM_RISING; break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: mode = IOPC_TM_FALLING; break; - case IRQT_BOTHEDGE: + case IRQ_TYPE_EDGE_BOTH: mode = IOPC_TM_EDGE; break; default: diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c index fd7537f7d11..99d4fb19a08 100644 --- a/arch/arm/mach-netx/generic.c +++ b/arch/arm/mach-netx/generic.c @@ -99,19 +99,19 @@ netx_hif_irq_type(unsigned int _irq, unsigned int type) irq = _irq - NETX_IRQ_HIF_CHAINED(0); - if (type & __IRQT_RISEDGE) { + if (type & IRQ_TYPE_EDGE_RISING) { DEBUG_IRQ("rising edges\n"); val |= (1 << 26) << irq; } - if (type & __IRQT_FALEDGE) { + if (type & IRQ_TYPE_EDGE_FALLING) { DEBUG_IRQ("falling edges\n"); val &= ~((1 << 26) << irq); } - if (type & __IRQT_LOWLVL) { + if (type & IRQ_TYPE_LEVEL_LOW) { DEBUG_IRQ("low level\n"); val &= ~((1 << 26) << irq); } - if (type & __IRQT_HIGHLVL) { + if (type & IRQ_TYPE_LEVEL_HIGH) { DEBUG_IRQ("high level\n"); val |= (1 << 26) << irq; } diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 845c66371ca..41f94f6fc15 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -288,7 +288,7 @@ static void __init osk_init_cf(void) return; } /* the CF I/O IRQ is really active-low */ - set_irq_type(OMAP_GPIO_IRQ(62), IRQT_FALLING); + set_irq_type(OMAP_GPIO_IRQ(62), IRQ_TYPE_EDGE_FALLING); } static void __init osk_init_irq(void) @@ -483,7 +483,7 @@ static void __init osk_mistral_init(void) omap_cfg_reg(P20_1610_GPIO4); /* PENIRQ */ gpio_request(4, "ts_int"); gpio_direction_input(4); - set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING); + set_irq_type(OMAP_GPIO_IRQ(4), IRQ_TYPE_EDGE_FALLING); spi_register_board_info(mistral_boardinfo, ARRAY_SIZE(mistral_boardinfo)); @@ -494,7 +494,7 @@ static void __init osk_mistral_init(void) int ret = 0; gpio_direction_input(OMAP_MPUIO(2)); - set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQT_RISING); + set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQ_TYPE_EDGE_RISING); #ifdef CONFIG_PM /* share the IRQ in case someone wants to use the * button for more than wakeup from system sleep. diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index e020c277460..34389b63b0e 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -298,11 +298,11 @@ palmz71_powercable(int irq, void *dev_id) if (omap_get_gpio_datain(PALMZ71_USBDETECT_GPIO)) { printk(KERN_INFO "PM: Power cable connected\n"); set_irq_type(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO), - IRQT_FALLING); + IRQ_TYPE_EDGE_FALLING); } else { printk(KERN_INFO "PM: Power cable disconnected\n"); set_irq_type(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO), - IRQT_RISING); + IRQ_TYPE_EDGE_RISING); } return IRQ_HANDLED; } diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 5c00b3f39cd..8948d45a276 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -186,10 +186,10 @@ static void __init voiceblue_init(void) omap_request_gpio(13); omap_request_gpio(14); omap_request_gpio(15); - set_irq_type(OMAP_GPIO_IRQ(12), IRQT_RISING); - set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING); - set_irq_type(OMAP_GPIO_IRQ(14), IRQT_RISING); - set_irq_type(OMAP_GPIO_IRQ(15), IRQT_RISING); + set_irq_type(OMAP_GPIO_IRQ(12), IRQ_TYPE_EDGE_RISING); + set_irq_type(OMAP_GPIO_IRQ(13), IRQ_TYPE_EDGE_RISING); + set_irq_type(OMAP_GPIO_IRQ(14), IRQ_TYPE_EDGE_RISING); + set_irq_type(OMAP_GPIO_IRQ(15), IRQ_TYPE_EDGE_RISING); platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); omap_board_config = voiceblue_config; diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c index 0cf62ef5ecb..d963125ed75 100644 --- a/arch/arm/mach-omap1/fpga.c +++ b/arch/arm/mach-omap1/fpga.c @@ -181,7 +181,7 @@ void omap1510_fpga_init_irq(void) */ omap_request_gpio(13); omap_set_gpio_direction(13, 1); - set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING); + set_irq_type(OMAP_GPIO_IRQ(13), IRQ_TYPE_EDGE_RISING); set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux); } diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 620fa0f120e..870b34972d3 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -337,17 +337,17 @@ static void __init apollon_sw_init(void) omap_request_gpio(SW_DOWN_GPIO58); omap_set_gpio_direction(SW_DOWN_GPIO58, 1); - set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING); + set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQ_TYPE_EDGE_RISING); if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt, IRQF_SHARED, "enter sw", &apollon_sw_interrupt)) return; - set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING); + set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQ_TYPE_EDGE_RISING); if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt, IRQF_SHARED, "up sw", &apollon_sw_interrupt)) return; - set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING); + set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQ_TYPE_EDGE_RISING); if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt, IRQF_SHARED, "down sw", &apollon_sw_interrupt)) diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c index 88405e74e5e..40a0bee4fbb 100644 --- a/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/arch/arm/mach-orion5x/db88f5281-setup.c @@ -213,7 +213,7 @@ void __init db88f5281_pci_preinit(void) pin = DB88F5281_PCI_SLOT0_IRQ_PIN; if (gpio_request(pin, "PCI Int1") == 0) { if (gpio_direction_input(pin) == 0) { - set_irq_type(gpio_to_irq(pin), IRQT_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "db88f5281_pci_preinit faield to " "set_irq_type pin %d\n", pin); @@ -226,7 +226,7 @@ void __init db88f5281_pci_preinit(void) pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN; if (gpio_request(pin, "PCI Int2") == 0) { if (gpio_direction_input(pin) == 0) { - set_irq_type(gpio_to_irq(pin), IRQT_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "db88f5281_pci_preinit faield " "to set_irq_type pin %d\n", pin); diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c index e2a0084ab4a..9ae3f6dc783 100644 --- a/arch/arm/mach-orion5x/irq.c +++ b/arch/arm/mach-orion5x/irq.c @@ -91,27 +91,27 @@ static int orion5x_gpio_set_irq_type(u32 irq, u32 type) desc = irq_desc + irq; switch (type) { - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: desc->handle_irq = handle_level_irq; desc->status |= IRQ_LEVEL; orion5x_clrbits(GPIO_IN_POL, (1 << pin)); break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: desc->handle_irq = handle_level_irq; desc->status |= IRQ_LEVEL; orion5x_setbits(GPIO_IN_POL, (1 << pin)); break; - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: desc->handle_irq = handle_edge_irq; desc->status &= ~IRQ_LEVEL; orion5x_clrbits(GPIO_IN_POL, (1 << pin)); break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: desc->handle_irq = handle_edge_irq; desc->status &= ~IRQ_LEVEL; orion5x_setbits(GPIO_IN_POL, (1 << pin)); break; - case IRQT_BOTHEDGE: + case IRQ_TYPE_EDGE_BOTH: desc->handle_irq = handle_edge_irq; desc->status &= ~IRQ_LEVEL; /* @@ -156,7 +156,7 @@ static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) if (cause & (1 << pin)) { irq = gpio_to_irq(pin); desc = irq_desc + irq; - if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) { + if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { /* Swap polarity (race with GPIO line) */ u32 polarity = readl(GPIO_IN_POL); polarity ^= 1 << pin; diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c index 10ae6286426..2a46d27209c 100644 --- a/arch/arm/mach-orion5x/rd88f5182-setup.c +++ b/arch/arm/mach-orion5x/rd88f5182-setup.c @@ -148,7 +148,7 @@ void __init rd88f5182_pci_preinit(void) pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN; if (gpio_request(pin, "PCI IntA") == 0) { if (gpio_direction_input(pin) == 0) { - set_irq_type(gpio_to_irq(pin), IRQT_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "rd88f5182_pci_preinit faield to " "set_irq_type pin %d\n", pin); @@ -161,7 +161,7 @@ void __init rd88f5182_pci_preinit(void) pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN; if (gpio_request(pin, "PCI IntB") == 0) { if (gpio_direction_input(pin) == 0) { - set_irq_type(gpio_to_irq(pin), IRQT_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "rd88f5182_pci_preinit faield to " "set_irq_type pin %d\n", pin); diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index a9cef9703d5..f270ada2def 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c @@ -117,7 +117,7 @@ void __init qnap_ts209_pci_preinit(void) pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN; if (gpio_request(pin, "PCI Int1") == 0) { if (gpio_direction_input(pin) == 0) { - set_irq_type(gpio_to_irq(pin), IRQT_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "qnap_ts209_pci_preinit failed to " "set_irq_type pin %d\n", pin); @@ -131,7 +131,7 @@ void __init qnap_ts209_pci_preinit(void) pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN; if (gpio_request(pin, "PCI Int2") == 0) { if (gpio_direction_input(pin) == 0) { - set_irq_type(gpio_to_irq(pin), IRQT_LOW); + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); } else { printk(KERN_ERR "qnap_ts209_pci_preinit failed " "to set_irq_type pin %d\n", pin); diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c index 968d0b02759..5ed67e1947a 100644 --- a/arch/arm/mach-pnx4008/irq.c +++ b/arch/arm/mach-pnx4008/irq.c @@ -56,28 +56,28 @@ static void pnx4008_mask_ack_irq(unsigned int irq) static int pnx4008_set_irq_type(unsigned int irq, unsigned int type) { switch (type) { - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */ __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /*rising edge */ set_irq_handler(irq, handle_edge_irq); break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */ __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*falling edge */ set_irq_handler(irq, handle_edge_irq); break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */ __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*low level */ set_irq_handler(irq, handle_level_irq); break; - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */ __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /* high level */ set_irq_handler(irq, handle_level_irq); break; - /* IRQT_BOTHEDGE is not supported */ + /* IRQ_TYPE_EDGE_BOTH is not supported */ default: printk(KERN_ERR "PNX4008 IRQ: Unsupported irq type %d\n", type); return -1; diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c index bcf0cde6ccc..31f5bd411ce 100644 --- a/arch/arm/mach-pxa/cm-x270-pci.c +++ b/arch/arm/mach-pxa/cm-x270-pci.c @@ -71,7 +71,7 @@ void __cmx270_pci_init_irq(int irq_gpio) cmx270_it8152_irq_gpio = irq_gpio; - set_irq_type(gpio_to_irq(irq_gpio), IRQT_RISING); + set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING); set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx270_it8152_irq_demux); } diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index cc1c4fa0614..8d1ab54e7b2 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -113,7 +113,7 @@ static void __init lpd270_init_irq(void) set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler); - set_irq_type(IRQ_GPIO(0), IRQT_FALLING); + set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); } diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index ac26423cd20..af7375bb46a 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -152,7 +152,7 @@ static void __init lubbock_init_irq(void) } set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler); - set_irq_type(IRQ_GPIO(0), IRQT_FALLING); + set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 851ec2d9b69..c8e38b5ff1c 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -191,7 +191,7 @@ static void __init mainstone_init_irq(void) MST_INTSETCLR = 0; set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); - set_irq_type(IRQ_GPIO(0), IRQT_FALLING); + set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); } #ifdef CONFIG_PM diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 34cd585075b..23e9b928330 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -146,18 +146,18 @@ void sharpsl_pm_pxa_init(void) if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED, "AC Input Detect", sharpsl_ac_isr)) { dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); } - else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE); + else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQ_TYPE_EDGE_BOTH); if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED, "Battery Cover", sharpsl_fatal_isr)) { dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); } - else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING); + else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQ_TYPE_EDGE_FALLING); if (sharpsl_pm.machinfo->gpio_fatal) { if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED, "Fatal Battery", sharpsl_fatal_isr)) { dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); } - else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING); + else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQ_TYPE_EDGE_FALLING); } if (sharpsl_pm.machinfo->batfull_irq) @@ -166,7 +166,7 @@ void sharpsl_pm_pxa_init(void) if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED, "CO", sharpsl_chrg_full_isr)) { dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); } - else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING); + else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQ_TYPE_EDGE_RISING); } } diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index dee7bf36f01..12811b7aea0 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -122,7 +122,7 @@ static struct resource dm9000_resources[] = { [2] = { .start = TRIZEPS4_ETH_IRQ, .end = TRIZEPS4_ETH_IRQ, - .flags = (IORESOURCE_IRQ | IRQT_RISING), + .flags = (IORESOURCE_IRQ | IRQ_TYPE_EDGE_RISING), }, }; diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index 31afe50d7cd..56d3ee01baa 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -96,7 +96,7 @@ static struct resource cerf_flash_resource = { static void __init cerf_init_irq(void) { sa1100_init_irq(); - set_irq_type(CERF_ETH_IRQ, IRQT_RISING); + set_irq_type(CERF_ETH_IRQ, IRQ_TYPE_EDGE_RISING); } static struct map_desc cerf_io_desc[] __initdata = { diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index 8473c37b77d..b34ff42bbd7 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -834,7 +834,7 @@ static void __init h3800_init_irq(void) set_irq_chip(irq, &h3800_gpio_irqchip); } #endif - set_irq_type(IRQ_GPIO_H3800_ASIC, IRQT_RISING); + set_irq_type(IRQ_GPIO_H3800_ASIC, IRQ_TYPE_EDGE_RISING); set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, h3800_IRQ_demux); } diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index fa0403af7ee..c5e438b12ec 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c @@ -46,17 +46,17 @@ static int sa1100_gpio_type(unsigned int irq, unsigned int type) else mask = GPIO11_27_MASK(irq); - if (type == IRQT_PROBE) { + if (type == IRQ_TYPE_PROBE) { if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) return 0; - type = __IRQT_RISEDGE | __IRQT_FALEDGE; + type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; } - if (type & __IRQT_RISEDGE) { + if (type & IRQ_TYPE_EDGE_RISING) { GPIO_IRQ_rising_edge |= mask; } else GPIO_IRQ_rising_edge &= ~mask; - if (type & __IRQT_FALEDGE) { + if (type & IRQ_TYPE_EDGE_FALLING) { GPIO_IRQ_falling_edge |= mask; } else GPIO_IRQ_falling_edge &= ~mask; diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 9f1ed150930..967a48454f6 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -151,7 +151,7 @@ static int __devinit neponset_probe(struct platform_device *dev) /* * Install handler for GPIO25. */ - set_irq_type(IRQ_GPIO25, IRQT_RISING); + set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING); set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler); /* diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index c7bf7e0038f..69a71f11625 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c @@ -143,7 +143,7 @@ static void __init pleb_map_io(void) GPDR &= ~GPIO_ETH0_IRQ; - set_irq_type(GPIO_ETH0_IRQ, IRQT_FALLING); + set_irq_type(GPIO_ETH0_IRQ, IRQ_TYPE_EDGE_FALLING); } MACHINE_START(PLEB, "PLEB") diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index 4a7736717d8..318b268f938 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -73,19 +73,19 @@ static int gpio_set_irq_type(u32 irq, u32 type) void __iomem *reg = port->base; switch (type) { - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: edge = GPIO_INT_RISE_EDGE; break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: edge = GPIO_INT_FALL_EDGE; break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: edge = GPIO_INT_LOW_LEV; break; - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: edge = GPIO_INT_HIGH_LEV; break; - default: /* this includes IRQT_BOTHEDGE */ + default: /* this includes IRQ_TYPE_EDGE_BOTH */ return -EINVAL; } diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index d8e9c2c3f0f..63e094342ef 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -517,13 +517,13 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, u32 gpio_bit = 1 << gpio; MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, - trigger & __IRQT_LOWLVL); + trigger & IRQ_TYPE_LEVEL_LOW); MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, - trigger & __IRQT_HIGHLVL); + trigger & IRQ_TYPE_LEVEL_HIGH); MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, - trigger & __IRQT_RISEDGE); + trigger & IRQ_TYPE_EDGE_RISING); MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, - trigger & __IRQT_FALEDGE); + trigger & IRQ_TYPE_EDGE_FALLING); if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { if (trigger != 0) @@ -555,9 +555,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_INT_EDGE; l = __raw_readl(reg); - if (trigger & __IRQT_RISEDGE) + if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; - else if (trigger & __IRQT_FALEDGE) + else if (trigger & IRQ_TYPE_EDGE_FALLING) l &= ~(1 << gpio); else goto bad; @@ -567,9 +567,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_CONTROL; l = __raw_readl(reg); - if (trigger & __IRQT_RISEDGE) + if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; - else if (trigger & __IRQT_FALEDGE) + else if (trigger & IRQ_TYPE_EDGE_FALLING) l &= ~(1 << gpio); else goto bad; @@ -584,9 +584,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) gpio &= 0x07; l = __raw_readl(reg); l &= ~(3 << (gpio << 1)); - if (trigger & __IRQT_RISEDGE) + if (trigger & IRQ_TYPE_EDGE_RISING) l |= 2 << (gpio << 1); - if (trigger & __IRQT_FALEDGE) + if (trigger & IRQ_TYPE_EDGE_FALLING) l |= 1 << (gpio << 1); if (trigger) /* Enable wake-up during idle for dynamic tick */ @@ -599,9 +599,9 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_CONTROL; l = __raw_readl(reg); - if (trigger & __IRQT_RISEDGE) + if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; - else if (trigger & __IRQT_FALEDGE) + else if (trigger & IRQ_TYPE_EDGE_FALLING) l &= ~(1 << gpio); else goto bad; @@ -887,7 +887,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) _set_gpio_direction(bank, get_gpio_index(gpio), 1); _set_gpio_irqenable(bank, gpio, 0); _clear_gpio_irqstatus(bank, gpio); - _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); + _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); } /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ @@ -924,7 +924,7 @@ int omap_request_gpio(int gpio) /* Set trigger to none. You need to enable the desired trigger with * request_irq() or set_irq_type(). */ - _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); + _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE); #ifdef CONFIG_ARCH_OMAP15XX if (bank->method == METHOD_GPIO_1510) { diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index ae2c5d7efc9..001436c04b1 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c @@ -292,27 +292,27 @@ s3c_irqext_type(unsigned int irq, unsigned int type) /* Set the external interrupt to pointed trigger type */ switch (type) { - case IRQT_NOEDGE: + case IRQ_TYPE_NONE: printk(KERN_WARNING "No edge setting!\n"); break; - case IRQT_RISING: + case IRQ_TYPE_EDGE_RISING: newvalue = S3C2410_EXTINT_RISEEDGE; break; - case IRQT_FALLING: + case IRQ_TYPE_EDGE_FALLING: newvalue = S3C2410_EXTINT_FALLEDGE; break; - case IRQT_BOTHEDGE: + case IRQ_TYPE_EDGE_BOTH: newvalue = S3C2410_EXTINT_BOTHEDGE; break; - case IRQT_LOW: + case IRQ_TYPE_LEVEL_LOW: newvalue = S3C2410_EXTINT_LOWLEV; break; - case IRQT_HIGH: + case IRQ_TYPE_LEVEL_HIGH: newvalue = S3C2410_EXTINT_HILEV; break; diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index de8d186f5ab..2014253f6c8 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -169,7 +169,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq) - set_irq_type(irq, IRQT_RISING); + set_irq_type(irq, IRQ_TYPE_EDGE_RISING); /* Setup expansion bus chip selects */ *data->cs0_cfg = data->cs0_bits; diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 4e9d8eece2e..d0e13fc4a88 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -195,7 +195,7 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) { if ((GPLR(IRQ_TO_GPIO(corgi_ts->irq_gpio)) & GPIO_bit(IRQ_TO_GPIO(corgi_ts->irq_gpio))) == 0) { /* Disable Interrupt */ - set_irq_type(corgi_ts->irq_gpio, IRQT_NOEDGE); + set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_NONE); if (read_xydata(corgi_ts)) { corgi_ts->pendown = 1; new_data(corgi_ts); @@ -214,7 +214,7 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) } /* Enable Falling Edge */ - set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); + set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING); corgi_ts->pendown = 0; } } @@ -258,7 +258,7 @@ static int corgits_resume(struct platform_device *dev) corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS); /* Enable Falling Edge */ - set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); + set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING); corgi_ts->power_mode = PWR_MODE_ACTIVE; return 0; @@ -333,7 +333,7 @@ static int __init corgits_probe(struct platform_device *pdev) corgi_ts->power_mode = PWR_MODE_ACTIVE; /* Enable Falling Edge */ - set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); + set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING); return 0; diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index a79f029b91c..590a1379aa3 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c @@ -198,7 +198,7 @@ static int wm97xx_acc_startup(struct wm97xx *wm) switch (wm->id) { case WM9705_ID2: wm->pen_irq = IRQ_GPIO(4); - set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE); + set_irq_type(IRQ_GPIO(4), IRQ_TYPE_EDGE_BOTH); break; case WM9712_ID2: case WM9713_ID2: diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index eabf0bfccab..c6408a62d95 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -256,28 +256,28 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) bank + ASIC3_GPIO_TRIGGER_TYPE); asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit; - if (type == IRQT_RISING) { + if (type == IRQ_TYPE_EDGE_RISING) { trigger |= bit; edge |= bit; - } else if (type == IRQT_FALLING) { + } else if (type == IRQ_TYPE_EDGE_FALLING) { trigger |= bit; edge &= ~bit; - } else if (type == IRQT_BOTHEDGE) { + } else if (type == IRQ_TYPE_EDGE_BOTH) { trigger |= bit; if (asic3_gpio_get(&asic->gpio, irq - asic->irq_base)) edge &= ~bit; else edge |= bit; asic->irq_bothedge[(irq - asic->irq_base) >> 4] |= bit; - } else if (type == IRQT_LOW) { + } else if (type == IRQ_TYPE_LEVEL_LOW) { trigger &= ~bit; level &= ~bit; - } else if (type == IRQT_HIGH) { + } else if (type == IRQ_TYPE_LEVEL_HIGH) { trigger &= ~bit; level |= bit; } else { /* - * if type == IRQT_NOEDGE, we should mask interrupts, but + * if type == IRQ_TYPE_NONE, we should mask interrupts, but * be careful to not unmask them if mask was also called. * Probably need internal state for mask. */ @@ -343,7 +343,7 @@ static int __init asic3_irq_probe(struct platform_device *pdev) ASIC3_INTMASK_GINTMASK); set_irq_chained_handler(asic->irq_nr, asic3_irq_demux); - set_irq_type(asic->irq_nr, IRQT_RISING); + set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); set_irq_data(asic->irq_nr, asic); return 0; diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 2d87501b6fd..94e55e8e7ce 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -324,7 +324,7 @@ static void tc6393xb_attach_irq(struct platform_device *dev) set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - set_irq_type(tc6393xb->irq, IRQT_FALLING); + set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING); set_irq_data(tc6393xb->irq, tc6393xb); set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq); } diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 420a77540f4..8c21446996f 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -149,10 +149,10 @@ soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *stat */ if (skt->irq_state != 1 && state->io_irq) { skt->irq_state = 1; - set_irq_type(skt->irq, IRQT_FALLING); + set_irq_type(skt->irq, IRQ_TYPE_EDGE_FALLING); } else if (skt->irq_state == 1 && state->io_irq == 0) { skt->irq_state = 0; - set_irq_type(skt->irq, IRQT_NOEDGE); + set_irq_type(skt->irq, IRQ_TYPE_NONE); } skt->cs_state = *state; @@ -527,7 +527,7 @@ int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, IRQF_DISABLED, irqs[i].str, skt); if (res) break; - set_irq_type(irqs[i].irq, IRQT_NOEDGE); + set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); } if (res) { @@ -560,7 +560,7 @@ void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, for (i = 0; i < nr; i++) if (irqs[i].sock == skt->nr) - set_irq_type(irqs[i].irq, IRQT_NOEDGE); + set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); } EXPORT_SYMBOL(soc_pcmcia_disable_irqs); @@ -571,8 +571,8 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, for (i = 0; i < nr; i++) if (irqs[i].sock == skt->nr) { - set_irq_type(irqs[i].irq, IRQT_RISING); - set_irq_type(irqs[i].irq, IRQT_BOTHEDGE); + set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING); + set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH); } } EXPORT_SYMBOL(soc_pcmcia_enable_irqs); diff --git a/drivers/video/am200epd.c b/drivers/video/am200epd.c index 51e26c1f5e8..32dd8512693 100644 --- a/drivers/video/am200epd.c +++ b/drivers/video/am200epd.c @@ -221,7 +221,7 @@ static int am200_setup_irq(struct fb_info *info) return retval; } - return set_irq_type(IRQ_GPIO(RDY_GPIO_PIN), IRQT_FALLING); + return set_irq_type(IRQ_GPIO(RDY_GPIO_PIN), IRQ_TYPE_EDGE_FALLING); } static void am200_set_rst(struct metronomefb_par *par, int state) diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c index 81dbcf53cf0..fafd0f26b90 100644 --- a/drivers/video/omap/sossi.c +++ b/drivers/video/omap/sossi.c @@ -646,7 +646,7 @@ static int sossi_init(struct omapfb_device *fbdev) sossi_write_reg(SOSSI_INIT1_REG, l); if ((r = request_irq(INT_1610_SoSSI_MATCH, sossi_match_irq, - IRQT_FALLING, + IRQ_TYPE_EDGE_FALLING, "sossi_match", sossi.fbdev->dev)) < 0) { dev_err(sossi.fbdev->dev, "can't get SoSSI match IRQ\n"); goto err; diff --git a/include/asm-arm/arch-pnx4008/irqs.h b/include/asm-arm/arch-pnx4008/irqs.h index 13ec7ed0f50..a25d18f2d87 100644 --- a/include/asm-arm/arch-pnx4008/irqs.h +++ b/include/asm-arm/arch-pnx4008/irqs.h @@ -135,30 +135,30 @@ #define PNX4008_IRQ_TYPES \ { /*IRQ #'s: */ \ -IRQT_LOW, IRQT_LOW, IRQT_LOW, IRQT_HIGH, /* 0, 1, 2, 3 */ \ -IRQT_LOW, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 4, 5, 6, 7 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 8, 9,10,11 */ \ -IRQT_LOW, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 12,13,14,15 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 16,17,18,19 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 20,21,22,23 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 24,25,26,27 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_LOW, IRQT_LOW, /* 28,29,30,31 */ \ -IRQT_HIGH, IRQT_LOW, IRQT_HIGH, IRQT_HIGH, /* 32,33,34,35 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_FALLING, IRQT_HIGH, /* 36,37,38,39 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 40,41,42,43 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 44,45,46,47 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_LOW, IRQT_LOW, /* 48,49,50,51 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 52,53,54,55 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_LOW, IRQT_HIGH, /* 56,57,58,59 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 60,61,62,63 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 64,65,66,67 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 68,69,70,71 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 72,73,74,75 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 76,77,78,79 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 80,81,82,83 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 84,85,86,87 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 88,89,90,91 */ \ -IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, IRQT_HIGH, /* 92,93,94,95 */ \ +IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, /* 0, 1, 2, 3 */ \ +IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 4, 5, 6, 7 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 8, 9,10,11 */ \ +IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 12,13,14,15 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 16,17,18,19 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 20,21,22,23 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 24,25,26,27 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_LOW, /* 28,29,30,31 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 32,33,34,35 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_LEVEL_HIGH, /* 36,37,38,39 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 40,41,42,43 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 44,45,46,47 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_LOW, /* 48,49,50,51 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 52,53,54,55 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, /* 56,57,58,59 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 60,61,62,63 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 64,65,66,67 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 68,69,70,71 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 72,73,74,75 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 76,77,78,79 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 80,81,82,83 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 84,85,86,87 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 88,89,90,91 */ \ +IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 92,93,94,95 */ \ } /* Start Enable Pin Interrupts - table 58 page 66 */ diff --git a/include/asm-arm/arch-pxa/idp.h b/include/asm-arm/arch-pxa/idp.h index b6952534a4e..21aa8ac35c1 100644 --- a/include/asm-arm/arch-pxa/idp.h +++ b/include/asm-arm/arch-pxa/idp.h @@ -138,18 +138,18 @@ #define TOUCH_PANEL_IRQ IRQ_GPIO(5) #define IDE_IRQ IRQ_GPIO(21) -#define TOUCH_PANEL_IRQ_EDGE IRQT_FALLING +#define TOUCH_PANEL_IRQ_EDGE IRQ_TYPE_EDGE_FALLING #define ETHERNET_IRQ IRQ_GPIO(4) -#define ETHERNET_IRQ_EDGE IRQT_RISING +#define ETHERNET_IRQ_EDGE IRQ_TYPE_EDGE_RISING -#define IDE_IRQ_EDGE IRQT_RISING +#define IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCMCIA_S0_CD_VALID IRQ_GPIO(7) -#define PCMCIA_S0_CD_VALID_EDGE IRQT_BOTHEDGE +#define PCMCIA_S0_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH #define PCMCIA_S1_CD_VALID IRQ_GPIO(8) -#define PCMCIA_S1_CD_VALID_EDGE IRQT_BOTHEDGE +#define PCMCIA_S1_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH #define PCMCIA_S0_RDYINT IRQ_GPIO(19) #define PCMCIA_S1_RDYINT IRQ_GPIO(22) diff --git a/include/asm-arm/arch-pxa/pcm990_baseboard.h b/include/asm-arm/arch-pxa/pcm990_baseboard.h index b699d0d7bdb..2e201317906 100644 --- a/include/asm-arm/arch-pxa/pcm990_baseboard.h +++ b/include/asm-arm/arch-pxa/pcm990_baseboard.h @@ -29,14 +29,14 @@ /* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */ #define PCM990_CTRL_INT_IRQ_GPIO 9 #define PCM990_CTRL_INT_IRQ IRQ_GPIO(PCM990_CTRL_INT_IRQ_GPIO) -#define PCM990_CTRL_INT_IRQ_EDGE IRQT_RISING +#define PCM990_CTRL_INT_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CTRL_PHYS PXA_CS1_PHYS /* 16-Bit */ #define PCM990_CTRL_BASE 0xea000000 #define PCM990_CTRL_SIZE (1*1024*1024) #define PCM990_CTRL_PWR_IRQ_GPIO 14 #define PCM990_CTRL_PWR_IRQ IRQ_GPIO(PCM990_CTRL_PWR_IRQ_GPIO) -#define PCM990_CTRL_PWR_IRQ_EDGE IRQT_RISING +#define PCM990_CTRL_PWR_IRQ_EDGE IRQ_TYPE_EDGE_RISING /* visible CPLD (U7) registers */ #define PCM990_CTRL_REG0 0x0000 /* RESET REGISTER */ @@ -133,7 +133,7 @@ */ #define PCM990_IDE_IRQ_GPIO 13 #define PCM990_IDE_IRQ IRQ_GPIO(PCM990_IDE_IRQ_GPIO) -#define PCM990_IDE_IRQ_EDGE IRQT_RISING +#define PCM990_IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_IDE_PLD_PHYS 0x20000000 /* 16 bit wide */ #define PCM990_IDE_PLD_BASE 0xee000000 #define PCM990_IDE_PLD_SIZE (1*1024*1024) @@ -189,11 +189,11 @@ */ #define PCM990_CF_IRQ_GPIO 11 #define PCM990_CF_IRQ IRQ_GPIO(PCM990_CF_IRQ_GPIO) -#define PCM990_CF_IRQ_EDGE IRQT_RISING +#define PCM990_CF_IRQ_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CF_CD_GPIO 12 #define PCM990_CF_CD IRQ_GPIO(PCM990_CF_CD_GPIO) -#define PCM990_CF_CD_EDGE IRQT_RISING +#define PCM990_CF_CD_EDGE IRQ_TYPE_EDGE_RISING #define PCM990_CF_PLD_PHYS 0x30000000 /* 16 bit wide */ #define PCM990_CF_PLD_BASE 0xef000000 @@ -259,14 +259,14 @@ */ #define PCM990_AC97_IRQ_GPIO 10 #define PCM990_AC97_IRQ IRQ_GPIO(PCM990_AC97_IRQ_GPIO) -#define PCM990_AC97_IRQ_EDGE IRQT_RISING +#define PCM990_AC97_IRQ_EDGE IRQ_TYPE_EDGE_RISING /* * MMC phyCORE */ #define PCM990_MMC0_IRQ_GPIO 9 #define PCM990_MMC0_IRQ IRQ_GPIO(PCM990_MMC0_IRQ_GPIO) -#define PCM990_MMC0_IRQ_EDGE IRQT_FALLING +#define PCM990_MMC0_IRQ_EDGE IRQ_TYPE_EDGE_FALLING /* * USB phyCore diff --git a/include/asm-arm/arch-sa1100/ide.h b/include/asm-arm/arch-sa1100/ide.h index b14cbda01dc..193f6c15f4d 100644 --- a/include/asm-arm/arch-sa1100/ide.h +++ b/include/asm-arm/arch-sa1100/ide.h @@ -61,7 +61,7 @@ ide_init_default_hwifs(void) /* Enable GPIO as interrupt line */ GPDR &= ~LART_GPIO_IDE; - set_irq_type(LART_IRQ_IDE, IRQT_RISING); + set_irq_type(LART_IRQ_IDE, IRQ_TYPE_EDGE_RISING); /* set PCMCIA interface timing */ MECR = 0x00060006; diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h index 1b882a255e3..9cb01907e43 100644 --- a/include/asm-arm/irq.h +++ b/include/asm-arm/irq.h @@ -19,23 +19,6 @@ #define NO_IRQ ((unsigned int)(-1)) #endif - -/* - * Migration helpers - */ -#define __IRQT_FALEDGE IRQ_TYPE_EDGE_FALLING -#define __IRQT_RISEDGE IRQ_TYPE_EDGE_RISING -#define __IRQT_LOWLVL IRQ_TYPE_LEVEL_LOW -#define __IRQT_HIGHLVL IRQ_TYPE_LEVEL_HIGH - -#define IRQT_NOEDGE (0) -#define IRQT_RISING (__IRQT_RISEDGE) -#define IRQT_FALLING (__IRQT_FALEDGE) -#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE) -#define IRQT_LOW (__IRQT_LOWLVL) -#define IRQT_HIGH (__IRQT_HIGHLVL) -#define IRQT_PROBE IRQ_TYPE_PROBE - #ifndef __ASSEMBLY__ struct irqaction; extern void migrate_irqs(void); -- cgit v1.2.3-70-g09d2 From daf93dd55c48b65ab2f1907e0fc5ef994896c787 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 27 Jul 2008 10:10:58 +0100 Subject: [ARM] fix VIPT/VIVT macro optimisations, add comments cacheflush.h was doing: ... VIVT only stuff ... VIPT only stuff ... VIVT or VIPT stuff which is clearly bogus - we would only ever use the "VIVT or VIPT" case when both VIVT and VIPT are not selected. Fix this. Add comments to each case, including noting the impossibility of correctly detecting the cache type of ARM926 and ARMv6 cores from the cache type register in the "VIVT or VIPT" case. Signed-off-by: Russell King --- include/asm-arm/cacheflush.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'include/asm-arm') diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index 03cf1ee977b..e68a1cbcc85 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -459,15 +459,19 @@ static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt, #define __cacheid_vivt_asid_tagged_instr(val) (__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0) #if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) - +/* + * VIVT caches only + */ #define cache_is_vivt() 1 #define cache_is_vipt() 0 #define cache_is_vipt_nonaliasing() 0 #define cache_is_vipt_aliasing() 0 #define icache_is_vivt_asid_tagged() 0 -#elif defined(CONFIG_CPU_CACHE_VIPT) - +#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT) +/* + * VIPT caches only + */ #define cache_is_vivt() 0 #define cache_is_vipt() 1 #define cache_is_vipt_nonaliasing() \ @@ -489,7 +493,12 @@ static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt, }) #else - +/* + * VIVT or VIPT caches. Note that this is unreliable since ARM926 + * and V6 CPUs satisfy the "(val & (15 << 25)) == (14 << 25)" test. + * There's no way to tell from the CacheType register what type (!) + * the cache is. + */ #define cache_is_vivt() \ ({ \ unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ -- cgit v1.2.3-70-g09d2 From 399dee2371787825a1845de87c0cbee7b7c30ad6 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 28 Jul 2008 12:04:06 +0100 Subject: i2c: S3C2410: Pass the I2C bus number via drivers platform data Allow the platform data to specify the bus bumber that the new I2C bus will be given. This is to allow the use of the board registration mechanism to specify the new style of I2C device registration which allows boards to provide a list of attached devices. Note, as discussed on the mailing list, we have dropped backwards compatibility of adding an dynamic bus number as it should not affect most boards to have the bus pinned to 0 if they have either not specified platform data for driver. Any board supplying platform data will automatically have the bus_num field set to 0, and anyone who needs the driver on a different bus number can supply platform data to set bus_num. Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-s3c2410.c | 13 ++++++++++++- include/asm-arm/plat-s3c/iic.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'include/asm-arm') diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 007390ad981..eef35d3f607 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -752,9 +752,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) static int s3c24xx_i2c_probe(struct platform_device *pdev) { struct s3c24xx_i2c *i2c = &s3c24xx_i2c; + struct s3c2410_platform_i2c *pdata; struct resource *res; int ret; + pdata = s3c24xx_i2c_get_platformdata(&pdev->dev); + /* find the clock and enable it */ i2c->dev = &pdev->dev; @@ -832,7 +835,15 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res, (unsigned long)res->start); - ret = i2c_add_adapter(&i2c->adap); + /* Note, previous versions of the driver used i2c_add_adapter() + * to add the bus at any number. We now pass the bus number via + * the platform data, so if unset it will now default to always + * being bus 0. + */ + + i2c->adap.nr = pdata->bus_num; + + ret = i2c_add_numbered_adapter(&i2c->adap); if (ret < 0) { dev_err(&pdev->dev, "failed to add bus to i2c core\n"); goto err_irq; diff --git a/include/asm-arm/plat-s3c/iic.h b/include/asm-arm/plat-s3c/iic.h index 71211c8b538..d08a1f2863e 100644 --- a/include/asm-arm/plat-s3c/iic.h +++ b/include/asm-arm/plat-s3c/iic.h @@ -21,6 +21,7 @@ */ struct s3c2410_platform_i2c { + int bus_num; /* bus number to use */ unsigned int flags; unsigned int slave_addr; /* slave address for controller */ unsigned long bus_freq; /* standard bus frequency */ -- cgit v1.2.3-70-g09d2 From cb1d0a7a5d2e537f2f6ada22883abee1762e94b2 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 28 Jul 2008 15:46:33 -0700 Subject: spi_s3c24xx: really assign busnum The original "Pass the bus number we expect the S3C24XX SPI driver to attach to via the platform data." [1] patch was mis-sent, and missed two important parts of the diff, which was to actually set the bus_num field and add the relevant field to the platform data. The previous commit 50f426b55d919dd017af35bb6a08753d1f262920 promised to add a bus_num field, but failed to include the two hunks that added this field to include/asm-arm/arch-s3c2410/spi.h and then pass it to the spi core when creating the new master field in drivers/spi/spi_s3c24xx.c. [1] git commit 50f426b55d919dd017af35bb6a08753d1f262920 Signed-off-by: Ben Dooks Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/spi_s3c24xx.c | 1 + include/asm-arm/arch-s3c2410/spi.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include/asm-arm') diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 0885cc357a3..1c643c9e1f1 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -270,6 +270,7 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) /* setup the master state. */ master->num_chipselect = hw->pdata->num_cs; + master->bus_num = pdata->bus_num; /* setup the state for the bitbang driver */ diff --git a/include/asm-arm/arch-s3c2410/spi.h b/include/asm-arm/arch-s3c2410/spi.h index 352d33860b6..442169887d3 100644 --- a/include/asm-arm/arch-s3c2410/spi.h +++ b/include/asm-arm/arch-s3c2410/spi.h @@ -16,6 +16,7 @@ struct s3c2410_spi_info { unsigned long pin_cs; /* simple gpio cs */ unsigned int num_cs; /* total chipselects */ + int bus_num; /* bus number to use. */ void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); }; -- cgit v1.2.3-70-g09d2