diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-01-27 22:11:32 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-01-27 22:11:32 +0000 |
commit | a814290e17ae314bd614476cffc6119846eca27e (patch) | |
tree | 9fc40e6a34cd275bedcd2344383bd5e84f6c20df /arch/arm | |
parent | e55d1936f207f81c4e225d6c513e0fa487e544c5 (diff) | |
parent | ab5d97db1c6ced3e95c00d097931471707032b1f (diff) |
Merge branch 'for-rmk/samsung3' of git://git.fluff.org/bjdooks/linux into devel-stable
Diffstat (limited to 'arch/arm')
260 files changed, 7217 insertions, 2702 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 233a222752c..3bc5169f0f8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -18,6 +18,8 @@ config ARM select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) select HAVE_GENERIC_DMA_COHERENT + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_LZO help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -631,6 +633,14 @@ config ARCH_S3C64XX help Samsung S3C64XX series based systems +config ARCH_S5P6440 + bool "Samsung S5P6440" + select CPU_V6 + select GENERIC_GPIO + select HAVE_CLK + help + Samsung S5P6440 CPU based systems + config ARCH_S5PC1XX bool "Samsung S5PC1XX" select GENERIC_GPIO @@ -688,6 +698,7 @@ config ARCH_DAVINCI select HAVE_IDE select COMMON_CLKDEV select GENERIC_ALLOCATOR + select ARCH_HAS_HOLES_MEMORYMODEL help Support for TI's DaVinci platform. @@ -775,6 +786,7 @@ source "arch/arm/plat-samsung/Kconfig" source "arch/arm/plat-s3c24xx/Kconfig" source "arch/arm/plat-s3c64xx/Kconfig" source "arch/arm/plat-s3c/Kconfig" +source "arch/arm/plat-s5p/Kconfig" source "arch/arm/plat-s5pc1xx/Kconfig" if ARCH_S3C2410 @@ -791,6 +803,8 @@ source "arch/arm/mach-s3c6400/Kconfig" source "arch/arm/mach-s3c6410/Kconfig" endif +source "arch/arm/mach-s5p6440/Kconfig" + source "arch/arm/plat-stmp3xxx/Kconfig" if ARCH_S5PC1XX @@ -1071,7 +1085,7 @@ source kernel/Kconfig.preempt config HZ int default 128 if ARCH_L7200 - default 200 if ARCH_EBSA110 || ARCH_S3C2410 + default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER default AT91_TIMER_HZ if ARCH_AT91 default 100 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e9da08483b3..bbcd512ccf7 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -161,6 +161,7 @@ machine-$(CONFIG_ARCH_RPC) := rpc machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 +machine-$(CONFIG_ARCH_S5P6440) := s5p6440 machine-$(CONFIG_ARCH_S5PC1XX) := s5pc100 machine-$(CONFIG_ARCH_SA1100) := sa1100 machine-$(CONFIG_ARCH_SHARK) := shark @@ -184,6 +185,7 @@ plat-$(CONFIG_PLAT_PXA) := pxa plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c samsung plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c samsung plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx s3c samsung +plat-$(CONFIG_PLAT_S5P) := s5p samsung s3c plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx ifeq ($(CONFIG_ARCH_EBSA110),y) diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index ce39dc54008..2d4d88ba73b 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -63,8 +63,12 @@ endif SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ -targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ - head.o misc.o $(OBJS) +suffix_$(CONFIG_KERNEL_GZIP) = gzip +suffix_$(CONFIG_KERNEL_LZO) = lzo + +targets := vmlinux vmlinux.lds \ + piggy.$(suffix_y) piggy.$(suffix_y).o \ + font.o font.c head.o misc.o $(OBJS) ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS) @@ -87,22 +91,34 @@ endif ifneq ($(PARAMS_PHYS),) LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS) endif -LDFLAGS_vmlinux += -p --no-undefined -X \ - $(shell $(CC) $(KBUILD_CFLAGS) --print-libgcc-file-name) -T +# ? +LDFLAGS_vmlinux += -p +# Report unresolved symbol references +LDFLAGS_vmlinux += --no-undefined +# Delete all temporary local symbols +LDFLAGS_vmlinux += -X +# Next argument is a linker script +LDFLAGS_vmlinux += -T + +# For __aeabi_uidivmod +lib1funcs = $(obj)/lib1funcs.o + +$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE + $(call cmd,shipped) # Don't allow any static data in misc.o, which # would otherwise mess up our GOT table CFLAGS_misc.o := -Dstatic= -$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ - $(addprefix $(obj)/, $(OBJS)) FORCE +$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ + $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE $(call if_changed,ld) @: -$(obj)/piggy.gz: $(obj)/../Image FORCE - $(call if_changed,gzip) +$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE + $(call if_changed,$(suffix_y)) -$(obj)/piggy.o: $(obj)/piggy.gz FORCE +$(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE CFLAGS_font.o := -Dstatic= diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 17153b54613..7e0fe4d42c7 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -18,10 +18,15 @@ unsigned int __machine_arch_type; +#define _LINUX_STRING_H_ + #include <linux/compiler.h> /* for inline */ #include <linux/types.h> /* for size_t */ #include <linux/stddef.h> /* for NULL */ #include <asm/string.h> +#include <linux/linkage.h> + +#include <asm/unaligned.h> #ifdef STANDALONE_DEBUG #define putstr printf @@ -188,34 +193,8 @@ static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src, /* * gzip delarations */ -#define OF(args) args #define STATIC static -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ - -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ - -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - /* Diagnostic functions */ #ifdef DEBUG # define Assert(cond,msg) {if(!(cond)) error(msg);} @@ -233,24 +212,20 @@ static unsigned outcnt; /* bytes in output buffer */ # define Tracecv(c,x) #endif -static int fill_inbuf(void); -static void flush_window(void); static void error(char *m); extern char input_data[]; extern char input_data_end[]; -static uch *output_data; -static ulg output_ptr; -static ulg bytes_out; +static unsigned char *output_data; +static unsigned long output_ptr; static void error(char *m); static void putstr(const char *); -extern int end; -static ulg free_mem_ptr; -static ulg free_mem_end_ptr; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; #ifdef STANDALONE_DEBUG #define NO_INFLATE_MALLOC @@ -258,46 +233,13 @@ static ulg free_mem_end_ptr; #define ARCH_HAS_DECOMP_WDOG -#include "../../../../lib/inflate.c" - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -int fill_inbuf(void) -{ - if (insize != 0) - error("ran out of input data"); - - inbuf = input_data; - insize = &input_data_end[0] - &input_data[0]; - - inptr = 1; - return inbuf[0]; -} +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -void flush_window(void) -{ - ulg c = crc; - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out++ = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; - putstr("."); -} +#ifdef CONFIG_KERNEL_LZO +#include "../../../../lib/decompress_unlzo.c" +#endif #ifndef arch_error #define arch_error(x) @@ -314,22 +256,33 @@ static void error(char *x) while(1); /* Halt */ } +asmlinkage void __div0(void) +{ + error("Attempting division by 0!"); +} + #ifndef STANDALONE_DEBUG -ulg -decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, - int arch_id) +unsigned long +decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, + unsigned long free_mem_ptr_end_p, + int arch_id) { - output_data = (uch *)output_start; /* Points to kernel start */ + unsigned char *tmp; + + output_data = (unsigned char *)output_start; free_mem_ptr = free_mem_ptr_p; free_mem_end_ptr = free_mem_ptr_end_p; __machine_arch_type = arch_id; arch_decomp_setup(); - makecrc(); + tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); + output_ptr = get_unaligned_le32(tmp); + putstr("Uncompressing Linux..."); - gunzip(); + decompress(input_data, input_data_end - input_data, + NULL, NULL, output_data, NULL, error); putstr(" done, booting the kernel.\n"); return output_ptr; } @@ -341,11 +294,10 @@ int main() { output_data = output_buffer; - makecrc(); putstr("Uncompressing Linux..."); - gunzip(); + decompress(input_data, input_data_end - input_data, + NULL, NULL, output_data, NULL, error); putstr("done.\n"); return 0; } #endif - diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.gzip.S new file mode 100644 index 00000000000..a68adf91a16 --- /dev/null +++ b/arch/arm/boot/compressed/piggy.gzip.S @@ -0,0 +1,6 @@ + .section .piggydata,#alloc + .globl input_data +input_data: + .incbin "arch/arm/boot/compressed/piggy.gzip" + .globl input_data_end +input_data_end: diff --git a/arch/arm/boot/compressed/piggy.S b/arch/arm/boot/compressed/piggy.lzo.S index 54c951800eb..a425ad95959 100644 --- a/arch/arm/boot/compressed/piggy.S +++ b/arch/arm/boot/compressed/piggy.lzo.S @@ -1,6 +1,6 @@ .section .piggydata,#alloc .globl input_data input_data: - .incbin "arch/arm/boot/compressed/piggy.gz" + .incbin "arch/arm/boot/compressed/piggy.lzo" .globl input_data_end input_data_end: diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index d2a90eb844a..ff44bd1615c 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig @@ -184,7 +184,7 @@ CONFIG_S3C24XX_PWM=y CONFIG_S3C24XX_GPIO_EXTRA=0 CONFIG_S3C2410_DMA=y # CONFIG_S3C2410_DMA_DEBUG is not set -CONFIG_S3C24XX_ADC=y +CONFIG_S3C_ADC=y CONFIG_PLAT_S3C=y CONFIG_CPU_LLSERIAL_S3C2440_ONLY=y CONFIG_CPU_LLSERIAL_S3C2440=y @@ -199,8 +199,8 @@ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y # # Power management # -# CONFIG_S3C2410_PM_DEBUG is not set -# CONFIG_S3C2410_PM_CHECK is not set +# CONFIG_SAMSUNG_PM_DEBUG is not set +# CONFIG_SAMSUNG_PM_CHECK is not set CONFIG_S3C_LOWLEVEL_UART_PORT=0 CONFIG_S3C_GPIO_SPACE=0 diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 2f10dae0279..8e94c3caeb8 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -187,7 +187,7 @@ CONFIG_S3C24XX_GPIO_EXTRA128=y CONFIG_PM_SIMTEC=y CONFIG_S3C2410_DMA=y # CONFIG_S3C2410_DMA_DEBUG is not set -CONFIG_S3C24XX_ADC=y +CONFIG_S3C_ADC=y CONFIG_MACH_SMDK=y CONFIG_PLAT_S3C=y CONFIG_CPU_LLSERIAL_S3C2410=y @@ -203,8 +203,8 @@ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y # # Power management # -# CONFIG_S3C2410_PM_DEBUG is not set -# CONFIG_S3C2410_PM_CHECK is not set +# CONFIG_SAMSUNG_PM_DEBUG is not set +# CONFIG_SAMSUNG_PM_CHECK is not set CONFIG_S3C_LOWLEVEL_UART_PORT=0 CONFIG_S3C_GPIO_SPACE=0 CONFIG_S3C_DEV_HSMMC=y diff --git a/arch/arm/configs/s5p6440_defconfig b/arch/arm/configs/s5p6440_defconfig new file mode 100644 index 00000000000..279a15e5311 --- /dev/null +++ b/arch/arm/configs/s5p6440_defconfig @@ -0,0 +1,969 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.33-rc2 +# Sat Jan 9 16:33:55 2010 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_NO_IOPORT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_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_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +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_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +# CONFIG_FREEZER is not set + +# +# System Type +# +CONFIG_MMU=y +# 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_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_NOMADIK 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_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +CONFIG_ARCH_S5P6440=y +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_U8500 is not set +CONFIG_PLAT_SAMSUNG=y +CONFIG_SAMSUNG_CLKSRC=y +CONFIG_SAMSUNG_IRQ_VIC_TIMER=y +CONFIG_SAMSUNG_IRQ_UART=y +CONFIG_SAMSUNG_GPIO_EXTRA=0 +CONFIG_PLAT_S3C=y + +# +# Boot options +# +CONFIG_S3C_BOOT_ERROR_RESET=y +CONFIG_S3C_BOOT_UART_FORCE_FIFO=y + +# +# Power management +# +CONFIG_S3C_LOWLEVEL_UART_PORT=1 +CONFIG_S3C_GPIO_SPACE=0 +CONFIG_S3C_GPIO_TRACK=y +CONFIG_PLAT_S5P=y +CONFIG_CPU_S5P6440_INIT=y +CONFIG_CPU_S5P6440_CLOCK=y +CONFIG_CPU_S5P6440=y +CONFIG_MACH_SMDK6440=y + +# +# Processor Type +# +CONFIG_CPU_V6=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_PABRT_V6=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_ARM_L1_CACHE_SHIFT=5 +# CONFIG_ARM_ERRATA_411920 is not set +CONFIG_ARM_VIC=y +CONFIG_ARM_VIC_NR=2 + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=200 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM 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_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=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 +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_MTD 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 + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_MG_DISK 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=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# 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_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO 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_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=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=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SAMSUNG=y +CONFIG_SERIAL_SAMSUNG_UARTS=4 +# CONFIG_SERIAL_SAMSUNG_DEBUG is not set +CONFIG_SERIAL_SAMSUNG_CONSOLE=y +CONFIG_SERIAL_S5P6440=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM 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 + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT 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=y + +# +# Display hardware drivers +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +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 +CONFIG_GENERIC_ACL=y + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_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=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# 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=y +# CONFIG_STRIP_ASM_SYMS 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_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_PI_LIST=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_EARLY_PRINTK is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_OC_ETM is not set +CONFIG_DEBUG_S3C_UART=1 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 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 +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 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_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF 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_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index 610ac3c47b0..9155196e623 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.32-rc5 -# Sat Oct 17 23:32:24 2009 +# Linux kernel version: 2.6.33-rc2 +# Wed Jan 6 00:01:36 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -46,6 +46,7 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -119,14 +120,41 @@ CONFIG_BLOCK=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set CONFIG_IOSCHED_DEADLINE=y # CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set # CONFIG_FREEZER is not set # @@ -155,6 +183,7 @@ CONFIG_MMU=y # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set # CONFIG_ARCH_KIRKWOOD is not set # CONFIG_ARCH_LOKI is not set # CONFIG_ARCH_MV78XX0 is not set @@ -177,6 +206,7 @@ CONFIG_ARCH_U300=y # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_U8500 is not set # # ST-Ericsson AB U300/U330/U335/U365 Platform @@ -265,12 +295,10 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_SPLIT_PTLOCK_CPUS=999999 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ALIGNMENT_TRAP=y @@ -499,14 +527,21 @@ CONFIG_MTD_NAND_IDS=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# # 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=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set # @@ -517,6 +552,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -539,6 +575,7 @@ CONFIG_HAVE_IDE=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -645,7 +682,6 @@ CONFIG_I2C_STU300=y # # Miscellaneous I2C Chip support # -# CONFIG_DS1682 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -661,6 +697,8 @@ CONFIG_SPI_MASTER=y # CONFIG_SPI_BITBANG is not set # CONFIG_SPI_GPIO is not set CONFIG_SPI_PL022=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set # # SPI Protocol Masters @@ -708,6 +746,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set # CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set @@ -716,6 +755,8 @@ CONFIG_SSB_POSSIBLE=y CONFIG_AB3100_CORE=y CONFIG_AB3100_OTP=y # CONFIG_EZX_PCAP is not set +# CONFIG_MFD_88PM8607 is not set +# CONFIG_AB4500_CORE is not set CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set # CONFIG_REGULATOR_FIXED_VOLTAGE is not set @@ -723,6 +764,7 @@ CONFIG_REGULATOR=y # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set # CONFIG_REGULATOR_BQ24022 is not set # CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8660 is not set # CONFIG_REGULATOR_LP3971 is not set CONFIG_REGULATOR_AB3100=y # CONFIG_REGULATOR_TPS65023 is not set @@ -840,7 +882,9 @@ CONFIG_LEDS_CLASS=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_REGULATOR is not set # CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set # # LED Triggers @@ -882,6 +926,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set @@ -911,7 +956,9 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set CONFIG_RTC_DRV_AB3100=y @@ -926,6 +973,15 @@ CONFIG_DMADEVICES=y # # DMA Devices # +CONFIG_COH901318=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set @@ -1018,7 +1074,7 @@ CONFIG_MISC_FILESYSTEMS=y CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set +CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set @@ -1135,6 +1191,7 @@ CONFIG_ARM_UNWIND=y # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_LL is not set +# CONFIG_OC_ETM is not set # # Security options @@ -1142,7 +1199,11 @@ CONFIG_ARM_UNWIND=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" # CONFIG_CRYPTO is not set # CONFIG_BINARY_PRINTF is not set diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h index 634b2d7c612..793968173be 100644 --- a/arch/arm/include/asm/cpu.h +++ b/arch/arm/include/asm/cpu.h @@ -11,6 +11,7 @@ #define __ASM_ARM_CPU_H #include <linux/percpu.h> +#include <linux/cpu.h> struct cpuinfo_arm { struct cpu cpu; diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index 7edf3536df2..ca51143f97f 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -138,12 +138,12 @@ extern int get_dma_residue(unsigned int chan); #define NO_DMA 255 #endif +#endif /* CONFIG_ISA_DMA_API */ + #ifdef CONFIG_PCI extern int isa_dma_bridge_buggy; #else #define isa_dma_bridge_buggy (0) #endif -#endif /* CONFIG_ISA_DMA_API */ - #endif /* __ASM_ARM_DMA_H */ diff --git a/arch/arm/include/asm/entry-macro-vic2.S b/arch/arm/include/asm/entry-macro-vic2.S new file mode 100644 index 00000000000..3ceb85e4385 --- /dev/null +++ b/arch/arm/include/asm/entry-macro-vic2.S @@ -0,0 +1,57 @@ +/* arch/arm/include/asm/entry-macro-vic2.S + * + * Originally arch/arm/mach-s3c6400/include/mach/entry-macro.S + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * Low-level IRQ helper macros for a device with two VICs + * + * 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. +*/ + +/* This should be included from <mach/entry-macro.S> with the necessary + * defines for virtual addresses and IRQ bases for the two vics. + * + * The code needs the following defined: + * IRQ_VIC0_BASE IRQ number of VIC0's first IRQ + * IRQ_VIC1_BASE IRQ number of VIC1's first IRQ + * VA_VIC0 Virtual address of VIC0 + * VA_VIC1 Virtual address of VIC1 + * + * Note, code assumes VIC0's virtual address is an ARM immediate constant + * away from VIC1. +*/ + +#include <asm/hardware/vic.h> + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =VA_VIC0 + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + @ check the vic0 + mov \irqnr, #IRQ_VIC0_BASE + 31 + ldr \irqstat, [ \base, # VIC_IRQ_STATUS ] + teq \irqstat, #0 + + @ otherwise try vic1 + addeq \tmp, \base, #(VA_VIC1 - VA_VIC0) + addeq \irqnr, \irqnr, #(IRQ_VIC1_BASE - IRQ_VIC0_BASE) + ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] + teqeq \irqstat, #0 + + clzne \irqstat, \irqstat + subne \irqnr, \irqnr, \irqstat + .endm diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index bbecccda76d..eec6e897ceb 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -97,9 +97,15 @@ * stack during a system call. Note that sizeof(struct pt_regs) * has to be a multiple of 8. */ +#ifndef __KERNEL__ struct pt_regs { long uregs[18]; }; +#else /* __KERNEL__ */ +struct pt_regs { + unsigned long uregs[18]; +}; +#endif /* __KERNEL__ */ #define ARM_cpsr uregs[16] #define ARM_pc uregs[15] diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 4e506d09e5f..cf9cdaa2d4d 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -391,6 +391,7 @@ #define __NR_pwritev (__NR_SYSCALL_BASE+362) #define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363) #define __NR_perf_event_open (__NR_SYSCALL_BASE+364) +#define __NR_recvmmsg (__NR_SYSCALL_BASE+365) /* * The following SWIs are ARM private. diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d2903e3bc86..6c5cf369183 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -957,9 +957,7 @@ kuser_cmpxchg_fixup: #else -#ifdef CONFIG_SMP - mcr p15, 0, r0, c7, c10, 5 @ dmb -#endif + smp_dmb 1: ldrex r3, [r2] subs r3, r3, r0 strexeq r3, r1, [r2] diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 67304138a2c..ba2adefa53f 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -212,7 +212,8 @@ void __show_regs(struct pt_regs *regs) char buf[64]; printk("CPU: %d %s (%s %.*s)\n", - smp_processor_id(), print_tainted(), init_utsname()->release, + raw_smp_processor_id(), print_tainted(), + init_utsname()->release, (int)strcspn(init_utsname()->version, " "), init_utsname()->version); print_symbol("PC is at %s\n", instruction_pointer(regs)); diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index a9b650dcc17..077ecf4fecd 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -236,6 +236,7 @@ static struct vpfe_subdev_info vpfe_sub_devs[] = { static struct vpfe_config vpfe_cfg = { .num_subdevs = ARRAY_SIZE(vpfe_sub_devs), + .i2c_adapter_id = 1, .sub_devs = vpfe_sub_devs, .card_name = "DM355 EVM", .ccdc = "DM355 CCDC", diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 289fe1b7d25..b476395d2cd 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -192,7 +192,11 @@ static struct davinci_i2c_platform_data i2c_pdata = { .bus_delay = 0 /* usec */, }; -#ifdef CONFIG_KEYBOARD_DAVINCI +static int dm365evm_keyscan_enable(struct device *dev) +{ + return davinci_cfg_reg(DM365_KEYSCAN); +} + static unsigned short dm365evm_keymap[] = { KEY_KP2, KEY_LEFT, @@ -214,6 +218,7 @@ static unsigned short dm365evm_keymap[] = { }; static struct davinci_ks_platform_data dm365evm_ks_data = { + .device_enable = dm365evm_keyscan_enable, .keymap = dm365evm_keymap, .keymapsize = ARRAY_SIZE(dm365evm_keymap), .rep = 1, @@ -222,7 +227,6 @@ static struct davinci_ks_platform_data dm365evm_ks_data = { .interval = 0x2, .matrix_type = DAVINCI_KEYSCAN_MATRIX_4X4, }; -#endif static int cpld_mmc_get_cd(int module) { @@ -511,10 +515,7 @@ static __init void dm365_evm_init(void) dm365_init_asp(&dm365_evm_snd_data); dm365_init_rtc(); - -#ifdef CONFIG_KEYBOARD_DAVINCI dm365_init_ks(&dm365evm_ks_data); -#endif } static __init void dm365_evm_irq_init(void) diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index fd0398bc6db..e9612cf727b 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -247,6 +247,7 @@ static struct vpfe_subdev_info vpfe_sub_devs[] = { static struct vpfe_config vpfe_cfg = { .num_subdevs = ARRAY_SIZE(vpfe_sub_devs), + .i2c_adapter_id = 1, .sub_devs = vpfe_sub_devs, .card_name = "DM6446 EVM", .ccdc = "DM6446 CCDC", diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c index 52b287cf3a4..37311d1830e 100644 --- a/arch/arm/mach-davinci/cp_intc.c +++ b/arch/arm/mach-davinci/cp_intc.c @@ -81,12 +81,23 @@ static int cp_intc_set_irq_type(unsigned int irq, unsigned int flow_type) return 0; } +/* + * Faking this allows us to to work with suspend functions of + * generic drivers which call {enable|disable}_irq_wake for + * wake up interrupt sources (eg RTC on DA850). + */ +static int cp_intc_set_wake(unsigned int irq, unsigned int on) +{ + return 0; +} + static struct irq_chip cp_intc_irq_chip = { .name = "cp_intc", .ack = cp_intc_ack_irq, .mask = cp_intc_mask_irq, .unmask = cp_intc_unmask_irq, .set_type = cp_intc_set_irq_type, + .set_wake = cp_intc_set_wake, }; void __init cp_intc_init(void __iomem *base, unsigned short num_irq, diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index dd2d32c4ce8..a5105f03fd8 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -481,11 +481,18 @@ static struct platform_device da8xx_rtc_device = { int da8xx_register_rtc(void) { + int ret; + /* Unlock the rtc's registers */ __raw_writel(0x83e70b13, IO_ADDRESS(DA8XX_RTC_BASE + 0x6c)); __raw_writel(0x95a4f1e0, IO_ADDRESS(DA8XX_RTC_BASE + 0x70)); - return platform_device_register(&da8xx_rtc_device); + ret = platform_device_register(&da8xx_rtc_device); + if (!ret) + /* Atleast on DA850, RTC is a wakeup source */ + device_init_wakeup(&da8xx_rtc_device.dev, true); + + return ret; } static struct resource da8xx_cpuidle_resources[] = { diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 2ec619ec165..f53735cb922 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -993,7 +993,6 @@ void __init dm365_init_asp(struct snd_platform_data *pdata) void __init dm365_init_ks(struct davinci_ks_platform_data *pdata) { - davinci_cfg_reg(DM365_KEYSCAN); dm365_ks_device.dev.platform_data = pdata; platform_device_register(&dm365_ks_device); } diff --git a/arch/arm/mach-lh7a40x/clocks.c b/arch/arm/mach-lh7a40x/clocks.c index fcaf876f19b..0651f96653f 100644 --- a/arch/arm/mach-lh7a40x/clocks.c +++ b/arch/arm/mach-lh7a40x/clocks.c @@ -10,6 +10,8 @@ #include <mach/hardware.h> #include <mach/clocks.h> #include <linux/err.h> +#include <linux/device.h> +#include <linux/string.h> struct module; diff --git a/arch/arm/mach-mx2/mxt_td60.c b/arch/arm/mach-mx2/mxt_td60.c index 03dbbdc9895..8bcc1a5b882 100644 --- a/arch/arm/mach-mx2/mxt_td60.c +++ b/arch/arm/mach-mx2/mxt_td60.c @@ -58,21 +58,6 @@ static unsigned int mxt_td60_pins[] __initdata = { PE9_PF_UART3_RXD, PE10_PF_UART3_CTS, PE11_PF_UART3_RTS, - /* UART3 */ - PB26_AF_UART4_RTS, - PB28_AF_UART4_TXD, - PB29_AF_UART4_CTS, - PB31_AF_UART4_RXD, - /* UART4 */ - PB18_AF_UART5_TXD, - PB19_AF_UART5_RXD, - PB20_AF_UART5_CTS, - PB21_AF_UART5_RTS, - /* UART5 */ - PB10_AF_UART6_TXD, - PB12_AF_UART6_CTS, - PB11_AF_UART6_RXD, - PB13_AF_UART6_RTS, /* FEC */ PD0_AIN_FEC_TXD0, PD1_AIN_FEC_TXD1, @@ -261,12 +246,6 @@ static struct imxuart_platform_data uart_pdata[] = { .flags = IMXUART_HAVE_RTSCTS, }, { .flags = IMXUART_HAVE_RTSCTS, - }, { - .flags = IMXUART_HAVE_RTSCTS, - }, { - .flags = IMXUART_HAVE_RTSCTS, - }, { - .flags = IMXUART_HAVE_RTSCTS, }, }; @@ -278,9 +257,6 @@ static void __init mxt_td60_board_init(void) mxc_register_device(&mxc_uart_device0, &uart_pdata[0]); mxc_register_device(&mxc_uart_device1, &uart_pdata[1]); mxc_register_device(&mxc_uart_device2, &uart_pdata[2]); - mxc_register_device(&mxc_uart_device3, &uart_pdata[3]); - mxc_register_device(&mxc_uart_device4, &uart_pdata[4]); - mxc_register_device(&mxc_uart_device5, &uart_pdata[5]); mxc_register_device(&mxc_nand_device, &mxt_td60_nand_board_info); i2c_register_board_info(0, mxt_td60_i2c_devices, diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c index ef26951a527..6e838b85771 100644 --- a/arch/arm/mach-mx25/clock.c +++ b/arch/arm/mach-mx25/clock.c @@ -173,6 +173,7 @@ DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL); DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL); DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL); DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL); +DEFINE_CLOCK(fec_clk, 0, CCM_CGCR0, 23, get_rate_ipg, NULL); #define _REGISTER_CLOCK(d, n, c) \ { \ @@ -204,6 +205,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk) _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk) + _REGISTER_CLOCK("fec.0", NULL, fec_clk) }; int __init mx25_clocks_init(unsigned long fref) diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c index 63511de3a55..9fdeea1c083 100644 --- a/arch/arm/mach-mx25/devices.c +++ b/arch/arm/mach-mx25/devices.c @@ -419,3 +419,22 @@ int __init mxc_register_gpios(void) return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); } +static struct resource mx25_fec_resources[] = { + { + .start = MX25_FEC_BASE_ADDR, + .end = MX25_FEC_BASE_ADDR + 0xfff, + .flags = IORESOURCE_MEM, + }, + { + .start = MX25_INT_FEC, + .end = MX25_INT_FEC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mx25_fec_device = { + .name = "fec", + .id = 0, + .num_resources = ARRAY_SIZE(mx25_fec_resources), + .resource = mx25_fec_resources, +}; diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h index fe6bf88ad1d..fe5420fcd11 100644 --- a/arch/arm/mach-mx25/devices.h +++ b/arch/arm/mach-mx25/devices.h @@ -17,3 +17,4 @@ extern struct platform_device mxc_keypad_device; extern struct platform_device mxc_i2c_device0; extern struct platform_device mxc_i2c_device1; extern struct platform_device mxc_i2c_device2; +extern struct platform_device mx25_fec_device; diff --git a/arch/arm/mach-mx25/mx25pdk.c b/arch/arm/mach-mx25/mx25pdk.c index d23ae571c03..921bc99ea23 100644 --- a/arch/arm/mach-mx25/mx25pdk.c +++ b/arch/arm/mach-mx25/mx25pdk.c @@ -18,10 +18,11 @@ #include <linux/types.h> #include <linux/init.h> +#include <linux/delay.h> #include <linux/clk.h> #include <linux/irq.h> #include <linux/gpio.h> -#include <linux/smsc911x.h> +#include <linux/fec.h> #include <linux/platform_device.h> #include <mach/hardware.h> @@ -35,16 +36,57 @@ #include <mach/mx25.h> #include <mach/mxc_nand.h> #include "devices.h" -#include <mach/iomux-v3.h> +#include <mach/iomux.h> static struct imxuart_platform_data uart_pdata = { .flags = IMXUART_HAVE_RTSCTS, }; +static struct pad_desc mx25pdk_pads[] = { + MX25_PAD_FEC_MDC__FEC_MDC, + MX25_PAD_FEC_MDIO__FEC_MDIO, + MX25_PAD_FEC_TDATA0__FEC_TDATA0, + MX25_PAD_FEC_TDATA1__FEC_TDATA1, + MX25_PAD_FEC_TX_EN__FEC_TX_EN, + MX25_PAD_FEC_RDATA0__FEC_RDATA0, + MX25_PAD_FEC_RDATA1__FEC_RDATA1, + MX25_PAD_FEC_RX_DV__FEC_RX_DV, + MX25_PAD_FEC_TX_CLK__FEC_TX_CLK, + MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */ + MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */ +}; + +static struct fec_platform_data mx25_fec_pdata = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + +#define FEC_ENABLE_GPIO 35 +#define FEC_RESET_B_GPIO 104 + +static void __init mx25pdk_fec_reset(void) +{ + gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable"); + gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset"); + + gpio_direction_output(FEC_ENABLE_GPIO, 0); /* drop PHY power */ + gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */ + udelay(2); + + /* turn on PHY power and lift reset */ + gpio_set_value(FEC_ENABLE_GPIO, 1); + gpio_set_value(FEC_RESET_B_GPIO, 1); +} + static void __init mx25pdk_init(void) { + mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads, + ARRAY_SIZE(mx25pdk_pads)); + mxc_register_device(&mxc_uart_device0, &uart_pdata); mxc_register_device(&mxc_usbh2, NULL); + + mx25pdk_fec_reset(); + mxc_register_device(&mx25_fec_device, &mx25_fec_pdata); } static void __init mx25pdk_timer_init(void) diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index ea8ed109a7c..28294416b0a 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -49,6 +49,7 @@ config MACH_PCM037_EET config MACH_MX31LITE bool "Support MX31 LITEKIT (LogicPD)" select ARCH_MX31 + select MXC_ULPI if USB_ULPI help Include support for MX31 LITEKIT platform. This includes specific configurations for the board and its peripherals. @@ -63,7 +64,7 @@ config MACH_MX31_3DS config MACH_MX31MOBOARD bool "Support mx31moboard platforms (EPFL Mobots group)" select ARCH_MX31 - select MXC_ULPI + select MXC_ULPI if USB_ULPI help Include support for mx31moboard platform. This includes specific configurations for the board and its peripherals. diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c index bedf5b8d976..6858a4f9806 100644 --- a/arch/arm/mach-mx3/mm.c +++ b/arch/arm/mach-mx3/mm.c @@ -65,6 +65,11 @@ static struct map_desc mxc_io_desc[] __initdata = { .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), .length = AIPS2_SIZE, .type = MT_DEVICE_NONSHARED + }, { + .virtual = SPBA0_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), + .length = SPBA0_SIZE, + .type = MT_DEVICE_NONSHARED }, }; diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 0497c152be1..3e7bafa2ddb 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c @@ -494,11 +494,6 @@ static void mxc_init_i2c(void) */ static struct map_desc mx31ads_io_desc[] __initdata = { { - .virtual = SPBA0_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), - .length = SPBA0_SIZE, - .type = MT_DEVICE_NONSHARED - }, { .virtual = CS4_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(CS4_BASE_ADDR), .length = CS4_SIZE / 2, diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index def6b673659..789b20d1730 100644 --- a/arch/arm/mach-mx3/mx31lite.c +++ b/arch/arm/mach-mx3/mx31lite.c @@ -135,6 +135,7 @@ static struct spi_board_info mc13783_spi_dev __initdata = { * USB */ +#if defined(CONFIG_USB_ULPI) #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) @@ -180,6 +181,7 @@ static struct mxc_usbh_platform_data usbh2_pdata = { .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, .flags = MXC_EHCI_POWER_PINS_ENABLED, }; +#endif /* * NOR flash @@ -212,11 +214,6 @@ static struct platform_device physmap_flash_device = { */ static struct map_desc mx31lite_io_desc[] __initdata = { { - .virtual = SPBA0_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), - .length = SPBA0_SIZE, - .type = MT_DEVICE_NONSHARED - }, { .virtual = CS4_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(CS4_BASE_ADDR), .length = CS4_SIZE, @@ -261,11 +258,13 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_spi_device1, &spi1_pdata); spi_register_board_info(&mc13783_spi_dev, 1); +#if defined(CONFIG_USB_ULPI) /* USB */ usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); mxc_register_device(&mxc_usbh2, &usbh2_pdata); +#endif /* SMSC9117 IRQ pin */ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq"); diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c index 8fc624f141c..438428eaf76 100644 --- a/arch/arm/mach-mx3/mx31moboard-devboard.c +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c @@ -179,7 +179,7 @@ static int __init devboard_usbh1_init(void) usbh1_pdata.otg = otg; - return mxc_register_device(&mx31_usbh1, &usbh1_pdata); + return mxc_register_device(&mxc_usbh1, &usbh1_pdata); } /* diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index 85184a35e67..1f44b9ccbb0 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c @@ -294,7 +294,7 @@ static int __init marxbot_usbh1_init(void) usbh1_pdata.otg = otg; - return mxc_register_device(&mx31_usbh1, &usbh1_pdata); + return mxc_register_device(&mxc_usbh1, &usbh1_pdata); } /* diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index b7052914593..cfd605d078e 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c @@ -346,6 +346,8 @@ static struct fsl_usb2_platform_data usb_pdata = { .phy_mode = FSL_USB2_PHY_ULPI, }; +#if defined(CONFIG_USB_ULPI) + #define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6) static int moboard_usbh2_hw_init(struct platform_device *pdev) @@ -392,8 +394,11 @@ static int __init moboard_usbh2_init(void) usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); - return mxc_register_device(&mx31_usbh2, &usbh2_pdata); + return mxc_register_device(&mxc_usbh2, &usbh2_pdata); } +#else +static inline int moboard_usbh2_init(void) { return 0; } +#endif static struct gpio_led mx31moboard_leds[] = { diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c index 0f7a2f06bc2..18715f1aa7e 100644 --- a/arch/arm/mach-mx3/mx31pdk.c +++ b/arch/arm/mach-mx3/mx31pdk.c @@ -211,11 +211,6 @@ static int __init mx31pdk_init_expio(void) */ static struct map_desc mx31pdk_io_desc[] __initdata = { { - .virtual = SPBA0_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), - .length = SPBA0_SIZE, - .type = MT_DEVICE_NONSHARED, - }, { .virtual = CS5_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(CS5_BASE_ADDR), .length = CS5_SIZE, diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c index 6cbaabedf38..5be396917c9 100644 --- a/arch/arm/mach-mx3/pcm037.c +++ b/arch/arm/mach-mx3/pcm037.c @@ -322,16 +322,25 @@ static int pcm037_camera_power(struct device *dev, int on) return 0; } -static struct i2c_board_info pcm037_i2c_2_devices[] = { +static struct i2c_board_info pcm037_i2c_camera[] = { { I2C_BOARD_INFO("mt9t031", 0x5d), + }, { + I2C_BOARD_INFO("mt9v022", 0x48), }, }; -static struct soc_camera_link iclink = { +static struct soc_camera_link iclink_mt9v022 = { + .bus_id = 0, /* Must match with the camera ID */ + .board_info = &pcm037_i2c_camera[1], + .i2c_adapter_id = 2, + .module_name = "mt9v022", +}; + +static struct soc_camera_link iclink_mt9t031 = { .bus_id = 0, /* Must match with the camera ID */ .power = pcm037_camera_power, - .board_info = &pcm037_i2c_2_devices[0], + .board_info = &pcm037_i2c_camera[0], .i2c_adapter_id = 2, .module_name = "mt9t031", }; @@ -345,11 +354,19 @@ static struct i2c_board_info pcm037_i2c_devices[] = { } }; -static struct platform_device pcm037_camera = { +static struct platform_device pcm037_mt9t031 = { .name = "soc-camera-pdrv", .id = 0, .dev = { - .platform_data = &iclink, + .platform_data = &iclink_mt9t031, + }, +}; + +static struct platform_device pcm037_mt9v022 = { + .name = "soc-camera-pdrv", + .id = 1, + .dev = { + .platform_data = &iclink_mt9v022, }, }; @@ -449,7 +466,8 @@ static int __init pcm037_camera_alloc_dma(const size_t buf_size) static struct platform_device *devices[] __initdata = { &pcm037_flash, &pcm037_sram_device, - &pcm037_camera, + &pcm037_mt9t031, + &pcm037_mt9v022, }; static struct ipu_platform_data mx3_ipu_data = { @@ -599,7 +617,7 @@ static void __init mxc_board_init(void) if (!ret) gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1); else - iclink.power = NULL; + iclink_mt9t031.power = NULL; if (!pcm037_camera_alloc_dma(4 * 1024 * 1024)) mxc_register_device(&mx3_camera, &camera_pdata); diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index ab995a9c606..65e7b5b85d8 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -599,7 +599,7 @@ static struct clk i2c_ick = { static struct omap_clk omap_clks[] = { /* non-ULPD clocks */ CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310 | CK_7XX), - CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310 | CK_7XX), /* CK_GEN1 clocks */ CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX), CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX), @@ -627,7 +627,7 @@ static struct omap_clk omap_clks[] = { CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX), CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310), CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX), - CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310), + CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310), CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX), CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX), @@ -658,6 +658,10 @@ static struct omap_clk omap_clks[] = { CLK("i2c_omap.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310 | CK_7XX), CLK("i2c_omap.1", "ick", &i2c_ick, CK_16XX), CLK("i2c_omap.1", "ick", &dummy_ck, CK_1510 | CK_310 | CK_7XX), + CLK("omap1_spi100k.1", "fck", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.1", "ick", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.2", "fck", &dummy_ck, CK_7XX), + CLK("omap1_spi100k.2", "ick", &dummy_ck, CK_7XX), CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310), CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX), CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310), @@ -674,7 +678,7 @@ static struct omap_clk omap_clks[] = { * init */ -static struct clk_functions omap1_clk_functions __initdata = { +static struct clk_functions omap1_clk_functions = { .clk_enable = omap1_clk_enable, .clk_disable = omap1_clk_disable, .clk_round_rate = omap1_clk_round_rate, diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 23ded2d4960..a2d07aa75c9 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -14,6 +14,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/spi/spi.h> #include <mach/hardware.h> #include <asm/mach/map.h> @@ -23,6 +24,7 @@ #include <plat/mux.h> #include <mach/gpio.h> #include <plat/mmc.h> +#include <plat/omap7xx.h> /*-------------------------------------------------------------------------*/ @@ -196,6 +198,38 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, /*-------------------------------------------------------------------------*/ +/* OMAP7xx SPI support */ +#if defined(CONFIG_SPI_OMAP_100K) || defined(CONFIG_SPI_OMAP_100K_MODULE) + +struct platform_device omap_spi1 = { + .name = "omap1_spi100k", + .id = 1, +}; + +struct platform_device omap_spi2 = { + .name = "omap1_spi100k", + .id = 2, +}; + +static void omap_init_spi100k(void) +{ + omap_spi1.dev.platform_data = ioremap(OMAP7XX_SPI1_BASE, 0x7ff); + if (omap_spi1.dev.platform_data) + platform_device_register(&omap_spi1); + + omap_spi2.dev.platform_data = ioremap(OMAP7XX_SPI2_BASE, 0x7ff); + if (omap_spi2.dev.platform_data) + platform_device_register(&omap_spi2); +} + +#else +static inline void omap_init_spi100k(void) +{ +} +#endif + +/*-------------------------------------------------------------------------*/ + #if defined(CONFIG_OMAP_STI) #define OMAP1_STI_BASE 0xfffea000 @@ -263,6 +297,7 @@ static int __init omap1_init_devices(void) omap_init_mbox(); omap_init_rtc(); + omap_init_spi100k(); omap_init_sti(); return 0; diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 07212cc621a..84341377232 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -62,6 +62,14 @@ MUX_CFG_7XX("MMC_7XX_DAT0", 2, 17, 0, 16, 1, 0) /* I2C interface */ MUX_CFG_7XX("I2C_7XX_SCL", 5, 1, 0, 0, 1, 0) MUX_CFG_7XX("I2C_7XX_SDA", 5, 5, 0, 0, 1, 0) + +/* SPI pins */ +MUX_CFG_7XX("SPI_7XX_1", 6, 5, 4, 4, 1, 0) +MUX_CFG_7XX("SPI_7XX_2", 6, 9, 4, 8, 1, 0) +MUX_CFG_7XX("SPI_7XX_3", 6, 13, 4, 12, 1, 0) +MUX_CFG_7XX("SPI_7XX_4", 6, 17, 4, 16, 1, 0) +MUX_CFG_7XX("SPI_7XX_5", 8, 25, 0, 24, 0, 0) +MUX_CFG_7XX("SPI_7XX_6", 9, 5, 0, 4, 0, 0) }; #define OMAP7XX_PINS_SZ ARRAY_SIZE(omap7xx_pins) #else diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 10eafa70a90..606bf04f51b 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -80,6 +80,7 @@ config MACH_OVERO config MACH_OMAP3EVM bool "OMAP 3530 EVM board" depends on ARCH_OMAP3 && ARCH_OMAP34XX + select OMAP_PACKAGE_CBB config MACH_OMAP3517EVM bool "OMAP3517/ AM3517 EVM board" diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 8dd277c3666..1e3dfb652ac 100755 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -63,21 +63,21 @@ static int board_keymap[] = { KEY(5, 1, KEY_H), KEY(5, 2, KEY_J), KEY(5, 3, KEY_F3), + KEY(5, 4, KEY_UNKNOWN), KEY(5, 5, KEY_VOLUMEDOWN), KEY(5, 6, KEY_M), - KEY(5, 7, KEY_ENTER), + KEY(5, 7, KEY_RIGHT), KEY(6, 0, KEY_Q), KEY(6, 1, KEY_A), KEY(6, 2, KEY_N), KEY(6, 3, KEY_BACKSPACE), KEY(6, 6, KEY_P), - KEY(6, 7, KEY_SELECT), + KEY(6, 7, KEY_UP), KEY(7, 0, KEY_PROG1), /*MACRO 1 <User defined> */ KEY(7, 1, KEY_PROG2), /*MACRO 2 <User defined> */ KEY(7, 2, KEY_PROG3), /*MACRO 3 <User defined> */ KEY(7, 3, KEY_PROG4), /*MACRO 4 <User defined> */ - KEY(7, 5, KEY_RIGHT), - KEY(7, 6, KEY_UP), + KEY(7, 6, KEY_SELECT), KEY(7, 7, KEY_DOWN) }; diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c index d0e3fb7f929..5420356eb40 100644 --- a/arch/arm/mach-omap2/clock2xxx.c +++ b/arch/arm/mach-omap2/clock2xxx.c @@ -449,40 +449,78 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) #ifdef CONFIG_CPU_FREQ /* * Walk PRCM rate table and fillout cpufreq freq_table + * XXX This should be replaced by an OPP layer in the near future */ -static struct cpufreq_frequency_table freq_table[ARRAY_SIZE(rate_table)]; +static struct cpufreq_frequency_table *freq_table; void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) { - struct prcm_config *prcm; + const struct prcm_config *prcm; + long sys_ck_rate; int i = 0; + int tbl_sz = 0; + + sys_ck_rate = clk_get_rate(sclk); for (prcm = rate_table; prcm->mpu_speed; prcm++) { if (!(prcm->flags & cpu_mask)) continue; - if (prcm->xtal_speed != sys_ck.rate) + if (prcm->xtal_speed != sys_ck_rate) continue; /* don't put bypass rates in table */ if (prcm->dpll_speed == prcm->xtal_speed) continue; - freq_table[i].index = i; - freq_table[i].frequency = prcm->mpu_speed / 1000; - i++; + tbl_sz++; } - if (i == 0) { - printk(KERN_WARNING "%s: failed to initialize frequency " - "table\n", __func__); + /* + * XXX Ensure that we're doing what CPUFreq expects for this error + * case and the following one + */ + if (tbl_sz == 0) { + pr_warning("%s: no matching entries in rate_table\n", + __func__); + return; + } + + /* Include the CPUFREQ_TABLE_END terminator entry */ + tbl_sz++; + + freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz, + GFP_ATOMIC); + if (!freq_table) { + pr_err("%s: could not kzalloc frequency table\n", __func__); return; } + for (prcm = rate_table; prcm->mpu_speed; prcm++) { + if (!(prcm->flags & cpu_mask)) + continue; + if (prcm->xtal_speed != sys_ck_rate) + continue; + + /* don't put bypass rates in table */ + if (prcm->dpll_speed == prcm->xtal_speed) + continue; + + freq_table[i].index = i; + freq_table[i].frequency = prcm->mpu_speed / 1000; + i++; + } + freq_table[i].index = i; freq_table[i].frequency = CPUFREQ_TABLE_END; *table = &freq_table[0]; } + +void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) +{ + kfree(freq_table); +} + #endif struct clk_functions omap2_clk_functions = { @@ -494,6 +532,7 @@ struct clk_functions omap2_clk_functions = { .clk_disable_unused = omap2_clk_disable_unused, #ifdef CONFIG_CPU_FREQ .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table, + .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table, #endif }; diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index ded32364f32..d4217b93e10 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -34,7 +34,6 @@ #include <asm/div64.h> #include <asm/clkdev.h> -#include <plat/sdrc.h> #include "clock.h" #include "clock34xx.h" #include "sdrc.h" diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c index 8bdcc9cc7f9..c6031d74d6f 100644 --- a/arch/arm/mach-omap2/clock34xx_data.c +++ b/arch/arm/mach-omap2/clock34xx_data.c @@ -776,6 +776,8 @@ static struct clk dpll4_m5_ck = { .clksel_mask = OMAP3430_CLKSEL_CAM_MASK, .clksel = div16_dpll4_clksel, .clkdm_name = "dpll4_clkdm", + .set_rate = &omap2_clksel_set_rate, + .round_rate = &omap2_clksel_round_rate, .recalc = &omap2_clksel_recalc, }; @@ -1500,6 +1502,7 @@ static struct clk uart2_fck = { .parent = &core_48m_fck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_UART2_SHIFT, + .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -1509,6 +1512,7 @@ static struct clk uart1_fck = { .parent = &core_48m_fck, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_UART1_SHIFT, + .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -2745,7 +2749,7 @@ static struct clk mcbsp4_ick = { }; static const struct clksel mcbsp_234_clksel[] = { - { .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates }, + { .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates }, { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates }, { .parent = NULL } }; diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 1a45ed1e8ba..dd285f00146 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -559,7 +559,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) * downstream clocks for debugging purposes? */ - if (!clkdm || !clk) + if (!clkdm || !clk || !clkdm->clktrctrl_mask) return -EINVAL; if (atomic_inc_return(&clkdm->usecount) > 1) @@ -610,7 +610,7 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) * downstream clocks for debugging purposes? */ - if (!clkdm || !clk) + if (!clkdm || !clk || !clkdm->clktrctrl_mask) return -EINVAL; #ifdef DEBUG diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index a8749e8017b..5a7996402c5 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -33,7 +33,6 @@ #include <plat/sdrc.h> #include <plat/gpmc.h> #include <plat/serial.h> -#include <plat/mux.h> #include <plat/vram.h> #include "clock.h" @@ -73,21 +72,21 @@ static struct map_desc omap24xx_io_desc[] __initdata = { #ifdef CONFIG_ARCH_OMAP2420 static struct map_desc omap242x_io_desc[] __initdata = { { - .virtual = DSP_MEM_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), - .length = DSP_MEM_24XX_SIZE, + .virtual = DSP_MEM_2420_VIRT, + .pfn = __phys_to_pfn(DSP_MEM_2420_PHYS), + .length = DSP_MEM_2420_SIZE, .type = MT_DEVICE }, { - .virtual = DSP_IPI_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS), - .length = DSP_IPI_24XX_SIZE, + .virtual = DSP_IPI_2420_VIRT, + .pfn = __phys_to_pfn(DSP_IPI_2420_PHYS), + .length = DSP_IPI_2420_SIZE, .type = MT_DEVICE }, { - .virtual = DSP_MMU_24XX_VIRT, - .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS), - .length = DSP_MMU_24XX_SIZE, + .virtual = DSP_MMU_2420_VIRT, + .pfn = __phys_to_pfn(DSP_MMU_2420_PHYS), + .length = DSP_MMU_2420_SIZE, .type = MT_DEVICE }, }; diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index e071b3fd187..459ef23ab8a 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -994,8 +994,10 @@ int __init omap_mux_init(u32 mux_pbase, u32 mux_size, } #ifdef CONFIG_OMAP_MUX - omap_mux_package_fixup(package_subset, superset); - omap_mux_package_init_balls(package_balls, superset); + if (package_subset) + omap_mux_package_fixup(package_subset, superset); + if (package_balls) + omap_mux_package_init_balls(package_balls, superset); omap_mux_set_cmdline_signals(); omap_mux_set_board_signals(board_mux); #endif diff --git a/arch/arm/mach-omap2/opp2420_data.c b/arch/arm/mach-omap2/opp2420_data.c index 126a9396b3a..e6dda694fd5 100644 --- a/arch/arm/mach-omap2/opp2420_data.c +++ b/arch/arm/mach-omap2/opp2420_data.c @@ -9,45 +9,47 @@ * The OMAP2 processor can be run at several discrete 'PRCM configurations'. * These configurations are characterized by voltage and speed for clocks. * The device is only validated for certain combinations. One way to express - * these combinations is via the 'ratio's' which the clocks operate with + * these combinations is via the 'ratios' which the clocks operate with * respect to each other. These ratio sets are for a given voltage/DPLL - * setting. All configurations can be described by a DPLL setting and a ratio - * There are 3 ratio sets for the 2430 and X ratio sets for 2420. - * - * 2430 differs from 2420 in that there are no more phase synchronizers used. - * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs - * 2430 (iva2.1, NOdsp, mdm) + * setting. All configurations can be described by a DPLL setting and a ratio. * * XXX Missing voltage data. + * XXX Missing 19.2MHz sys_clk rate sets (needed for N800/N810) * * THe format described in this file is deprecated. Once a reasonable * OPP API exists, the data in this file should be converted to use it. * * This is technically part of the OMAP2xxx clock code. + * + * Considerable work is still needed to fully support dynamic frequency + * changes on OMAP2xxx-series chips. Readers interested in such a + * project are encouraged to review the Maemo Diablo RX-34 and RX-44 + * kernel source at: + * http://repository.maemo.org/pool/diablo/free/k/kernel-source-diablo/ */ #include "opp2xxx.h" #include "sdrc.h" #include "clock.h" -/*------------------------------------------------------------------------- - * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. +/* + * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated. * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU, * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL, * CM_CLKSEL2_PLL, CM_CLKSEL_MDM * - * Filling in table based on H4 boards and 2430-SDPs variants available. - * There are quite a few more rates combinations which could be defined. + * Filling in table based on H4 boards available. There are quite a + * few more rate combinations which could be defined. * - * When multiple values are defined the start up will try and choose the - * fastest one. If a 'fast' value is defined, then automatically, the /2 - * one should be included as it can be used. Generally having more that - * one fast set does not make sense, as static timings need to be changed - * to change the set. The exception is the bypass setting which is - * availble for low power bypass. + * When multiple values are defined the start up will try and choose + * the fastest one. If a 'fast' value is defined, then automatically, + * the /2 one should be included as it can be used. Generally having + * more than one fast set does not make sense, as static timings need + * to be changed to change the set. The exception is the bypass + * setting which is available for low power bypass. * * Note: This table needs to be sorted, fastest to slowest. - *-------------------------------------------------------------------------*/ + **/ const struct prcm_config omap2420_rate_table[] = { /* PRCM I - FAST */ {S12M, S660M, S330M, RI_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */ diff --git a/arch/arm/mach-omap2/opp2430_data.c b/arch/arm/mach-omap2/opp2430_data.c index edb81672c84..1b9596ae201 100644 --- a/arch/arm/mach-omap2/opp2430_data.c +++ b/arch/arm/mach-omap2/opp2430_data.c @@ -1,5 +1,5 @@ /* - * opp2420_data.c - old-style "OPP" table for OMAP2420 + * opp2430_data.c - old-style "OPP" table for OMAP2430 * * Copyright (C) 2005-2009 Texas Instruments, Inc. * Copyright (C) 2004-2009 Nokia Corporation @@ -9,16 +9,16 @@ * The OMAP2 processor can be run at several discrete 'PRCM configurations'. * These configurations are characterized by voltage and speed for clocks. * The device is only validated for certain combinations. One way to express - * these combinations is via the 'ratio's' which the clocks operate with + * these combinations is via the 'ratios' which the clocks operate with * respect to each other. These ratio sets are for a given voltage/DPLL - * setting. All configurations can be described by a DPLL setting and a ratio - * There are 3 ratio sets for the 2430 and X ratio sets for 2420. + * setting. All configurations can be described by a DPLL setting and a ratio. * * 2430 differs from 2420 in that there are no more phase synchronizers used. * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs * 2430 (iva2.1, NOdsp, mdm) * * XXX Missing voltage data. + * XXX Missing 19.2MHz sys_clk rate sets. * * THe format described in this file is deprecated. Once a reasonable * OPP API exists, the data in this file should be converted to use it. @@ -30,24 +30,24 @@ #include "sdrc.h" #include "clock.h" -/*------------------------------------------------------------------------- - * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. +/* + * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated. * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU, * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL, * CM_CLKSEL2_PLL, CM_CLKSEL_MDM * - * Filling in table based on H4 boards and 2430-SDPs variants available. - * There are quite a few more rates combinations which could be defined. + * Filling in table based on 2430-SDPs variants available. There are + * quite a few more rate combinations which could be defined. * - * When multiple values are defined the start up will try and choose the - * fastest one. If a 'fast' value is defined, then automatically, the /2 - * one should be included as it can be used. Generally having more that - * one fast set does not make sense, as static timings need to be changed - * to change the set. The exception is the bypass setting which is - * availble for low power bypass. + * When multiple values are defined the start up will try and choose + * the fastest one. If a 'fast' value is defined, then automatically, + * the /2 one should be included as it can be used. Generally having + * more than one fast set does not make sense, as static timings need + * to be changed to change the set. The exception is the bypass + * setting which is available for low power bypass. * * Note: This table needs to be sorted, fastest to slowest. - *-------------------------------------------------------------------------*/ + */ const struct prcm_config omap2430_rate_table[] = { /* PRCM #4 - ratio2 (ES2.1) - FAST */ {S13M, S798M, S399M, R2_CM_CLKSEL_MPU_VAL, /* 399MHz ARM */ diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 81ed252a0f8..c6cc809afb7 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -124,8 +124,8 @@ static void omap3_core_save_context(void) control_padconf_off |= START_PADCONF_SAVE; omap_ctrl_writel(control_padconf_off, OMAP343X_CONTROL_PADCONF_OFF); /* wait for the save to complete */ - while (!omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS) - & PADCONF_SAVE_DONE) + while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS) + & PADCONF_SAVE_DONE)) ; /* Save the Interrupt controller context */ omap_intc_save_context(); diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 19805a7de06..8c964bec815 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -125,6 +125,13 @@ static struct plat_serial8250_port serial_platform_data3[] = { } }; #endif +static inline unsigned int __serial_read_reg(struct uart_port *up, + int offset) +{ + offset <<= up->regshift; + return (unsigned int)__raw_readb(up->membase + offset); +} + static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, int offset) { @@ -583,11 +590,12 @@ static unsigned int serial_in_override(struct uart_port *up, int offset) { if (UART_RX == offset) { unsigned int lsr; - lsr = serial_read_reg(omap_uart[up->line].p, UART_LSR); + lsr = __serial_read_reg(up, UART_LSR); if (!(lsr & UART_LSR_DR)) return -EPERM; } - return serial_read_reg(omap_uart[up->line].p, offset); + + return __serial_read_reg(up, offset); } void __init omap_serial_early_init(void) diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index fdb966e590a..385c30ee3f2 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -37,6 +37,8 @@ config MACH_ZYLONITE320 config MACH_LITTLETON bool "PXA3xx Form Factor Platform (aka Littleton)" select PXA3xx + select CPU_PXA300 + select CPU_PXA310 select PXA_SSP config MACH_TAVOREVB diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 50f1297bf5a..e741bf1bfb2 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h @@ -250,20 +250,17 @@ #define cpu_is_pxa930() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa930(id); \ + __cpu_is_pxa930(read_cpuid_id()); \ }) #define cpu_is_pxa935() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa935(id); \ + __cpu_is_pxa935(read_cpuid_id()); \ }) #define cpu_is_pxa950() \ ({ \ - unsigned int id = read_cpuid(CPUID_ID); \ - __cpu_is_pxa950(id); \ + __cpu_is_pxa950(read_cpuid_id()); \ }) diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h index bf6785adccf..9edf645368d 100644 --- a/arch/arm/mach-pxa/include/mach/zylonite.h +++ b/arch/arm/mach-pxa/include/mach/zylonite.h @@ -8,13 +8,6 @@ /* the following variables are processor specific and initialized * by the corresponding zylonite_pxa3xx_init() */ -struct platform_mmc_slot { - int gpio_cd; - int gpio_wp; -}; - -extern struct platform_mmc_slot zylonite_mmc_slot[]; - extern int gpio_eth_irq; extern int gpio_debug_led1; extern int gpio_debug_led2; diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index f28c1715b91..fa527b258d6 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -110,6 +110,12 @@ static mfp_cfg_t littleton_mfp_cfg[] __initdata = { GPIO7_MMC1_CLK, GPIO8_MMC1_CMD, GPIO15_GPIO, /* card detect */ + + /* UART3 */ + GPIO107_UART3_CTS, + GPIO108_UART3_RTS, + GPIO109_UART3_TXD, + GPIO110_UART3_RXD, }; static struct resource smc91x_resources[] = { diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 8a38d604dc7..189f330719a 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -381,7 +381,7 @@ err: return ret; } -static int magician_backlight_notify(int brightness) +static int magician_backlight_notify(struct device *dev, int brightness) { gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness); if (brightness >= 200) { diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 59140217890..e100af78b16 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -270,7 +270,7 @@ err: return ret; } -static int palmld_backlight_notify(int brightness) +static int palmld_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMLD_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMLD_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 7f89ca20f13..8fe3ec27568 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -209,7 +209,7 @@ err: return ret; } -static int palmt5_backlight_notify(int brightness) +static int palmt5_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMT5_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMT5_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 30841759200..b992f07ece2 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -185,7 +185,7 @@ err: return ret; } -static int palmtc_backlight_notify(int brightness) +static int palmtc_backlight_notify(struct device *dev, int brightness) { /* backlight is on when GPIO16 AF0 is high */ gpio_set_value(GPIO_NR_PALMTC_BL_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 265d62bae7d..dc728d6ab94 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -181,7 +181,7 @@ err: return ret; } -static int palmte2_backlight_notify(int brightness) +static int palmte2_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index 606eb7e8a17..b433bb49671 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -375,7 +375,7 @@ err: return ret; } -static int treo_backlight_notify(int brightness) +static int treo_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_TREO_BL_POWER, brightness); return TREO_MAX_INTENSITY - brightness; diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 7bf18c2f002..b37a025c0b7 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -269,7 +269,7 @@ err: return ret; } -static int palmtx_backlight_notify(int brightness) +static int palmtx_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index d787ac7cfdd..1c5d68a9451 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -196,7 +196,7 @@ err: return ret; } -static int palmz72_backlight_notify(int brightness) +static int palmz72_backlight_notify(struct device *dev, int brightness) { gpio_set_value(GPIO_NR_PALMZ72_BL_POWER, brightness); gpio_set_value(GPIO_NR_PALMZ72_LCD_POWER, brightness); diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index e5eeb3a62d0..c2b938a4d5c 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -293,7 +293,7 @@ static struct pxamci_platform_data poodle_mci_platform_data = { .init = poodle_mci_init, .setpower = poodle_mci_setpower, .exit = poodle_mci_exit, - .gpio_card_detect = POODLE_IRQ_GPIO_nSD_DETECT, + .gpio_card_detect = POODLE_GPIO_nSD_DETECT, .gpio_card_ro = POODLE_GPIO_nSD_WP, .gpio_power = -1, }; diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 4b50f144fa4..28352c0b8c3 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -389,13 +389,13 @@ static struct gpio_keys_button spitz_gpio_keys[] = { .type = EV_SW, .code = 0, .gpio = SPITZ_GPIO_SWA, - .desc = "Display Down", + .desc = "Display Down", }, { .type = EV_SW, .code = 1, .gpio = SPITZ_GPIO_SWB, - .desc = "Lid Closed", + .desc = "Lid Closed", }, }; diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 5352b4e5a7d..89f258c9e12 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -379,7 +379,7 @@ err_request_bckl: return ret; } -static int viper_backlight_notify(int brightness) +static int viper_backlight_notify(struct device *dev, int brightness) { gpio_set_value(VIPER_LCD_EN_GPIO, !!brightness); gpio_set_value(VIPER_BCKLIGHT_EN_GPIO, !!brightness); diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 5b986a8bd9e..75f2a37f945 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -25,6 +25,7 @@ #include <linux/mtd/physmap.h> #include <linux/i2c.h> #include <linux/i2c/pca953x.h> +#include <linux/apm-emulation.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -626,8 +627,27 @@ static void zeus_power_off(void) pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP); } -int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio, - unsigned ngpio, void *context) +#ifdef CONFIG_APM_EMULATION +static void zeus_get_power_status(struct apm_power_info *info) +{ + /* Power supply is always present */ + info->ac_line_status = APM_AC_ONLINE; + info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT; + info->battery_flag = APM_BATTERY_FLAG_NOT_PRESENT; +} + +static inline void zeus_setup_apm(void) +{ + apm_get_power_status = zeus_get_power_status; +} +#else +static inline void zeus_setup_apm(void) +{ +} +#endif + +static int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio, + unsigned ngpio, void *context) { int i; u8 pcb_info = 0; @@ -726,9 +746,18 @@ static mfp_cfg_t zeus_pin_config[] __initdata = { GPIO99_GPIO, /* CF RDY */ }; +/* + * DM9k MSCx settings: SRAM, 16 bits + * 17 cycles delay first access + * 5 cycles delay next access + * 13 cycles recovery time + * faster device + */ +#define DM9K_MSC_VALUE 0xe4c9 + static void __init zeus_init(void) { - u16 dm9000_msc = 0xe279; + u16 dm9000_msc = DM9K_MSC_VALUE; system_rev = __raw_readw(ZEUS_CPLD_VERSION); pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f)); @@ -738,6 +767,7 @@ static void __init zeus_init(void) MSC1 = (MSC1 & 0xffff0000) | dm9000_msc; pm_power_off = zeus_power_off; + zeus_setup_apm(); pxa2xx_mfp_config(ARRAY_AND_SIZE(zeus_pin_config)); diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index b66e9e2d06e..2b4043c04d0 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -36,9 +36,6 @@ #include "devices.h" #include "generic.h" -#define MAX_SLOTS 3 -struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS]; - int gpio_eth_irq; int gpio_debug_led1; int gpio_debug_led2; @@ -220,84 +217,28 @@ static inline void zylonite_init_lcd(void) {} #endif #if defined(CONFIG_MMC) -static int zylonite_mci_ro(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - - return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp); -} - -static int zylonite_mci_init(struct device *dev, - irq_handler_t zylonite_detect_int, - void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - int err, cd_irq, gpio_cd, gpio_wp; - - cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd); - gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd; - gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp; - - /* - * setup GPIO for Zylonite MMC controller - */ - err = gpio_request(gpio_cd, "mmc card detect"); - if (err) - goto err_request_cd; - gpio_direction_input(gpio_cd); - - err = gpio_request(gpio_wp, "mmc write protect"); - if (err) - goto err_request_wp; - gpio_direction_input(gpio_wp); - - err = request_irq(cd_irq, zylonite_detect_int, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "MMC card detect", data); - if (err) { - printk(KERN_ERR "%s: MMC/SD/SDIO: " - "can't request card detect IRQ\n", __func__); - goto err_request_irq; - } - - return 0; - -err_request_irq: - gpio_free(gpio_wp); -err_request_wp: - gpio_free(gpio_cd); -err_request_cd: - return err; -} - -static void zylonite_mci_exit(struct device *dev, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - int cd_irq, gpio_cd, gpio_wp; - - cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd); - gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd; - gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp; - - free_irq(cd_irq, data); - gpio_free(gpio_cd); - gpio_free(gpio_wp); -} - static struct pxamci_platform_data zylonite_mci_platform_data = { .detect_delay = 20, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = zylonite_mci_init, - .exit = zylonite_mci_exit, - .get_ro = zylonite_mci_ro, - .gpio_card_detect = -1, - .gpio_card_ro = -1, + .gpio_card_detect = EXT_GPIO(0), + .gpio_card_ro = EXT_GPIO(2), .gpio_power = -1, }; static struct pxamci_platform_data zylonite_mci2_platform_data = { .detect_delay = 20, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = EXT_GPIO(1), + .gpio_card_ro = EXT_GPIO(3), + .gpio_power = -1, +}; + +static struct pxamci_platform_data zylonite_mci3_platform_data = { + .detect_delay = 20, + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .gpio_card_detect = EXT_GPIO(30), + .gpio_card_ro = EXT_GPIO(31), + .gpio_power = -1, }; static void __init zylonite_init_mmc(void) @@ -305,7 +246,7 @@ static void __init zylonite_init_mmc(void) pxa_set_mci_info(&zylonite_mci_platform_data); pxa3xx_set_mci2_info(&zylonite_mci2_platform_data); if (cpu_is_pxa310()) - pxa3xx_set_mci3_info(&zylonite_mci_platform_data); + pxa3xx_set_mci3_info(&zylonite_mci3_platform_data); } #else static inline void zylonite_init_mmc(void) {} diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 84095440a87..3aa73b3e33f 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -129,8 +129,8 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO22_I2C_SDA, /* GPIO */ - GPIO18_GPIO, /* GPIO Expander #0 INT_N */ - GPIO19_GPIO, /* GPIO Expander #1 INT_N */ + GPIO18_GPIO | MFP_PULL_HIGH, /* GPIO Expander #0 INT_N */ + GPIO19_GPIO | MFP_PULL_HIGH, /* GPIO Expander #1 INT_N */ }; static mfp_cfg_t pxa300_mfp_cfg[] __initdata = { @@ -258,10 +258,6 @@ void __init zylonite_pxa300_init(void) /* detect LCD panel */ zylonite_detect_lcd_panel(); - /* 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); - /* WM9713 IRQ */ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26); @@ -276,10 +272,6 @@ void __init zylonite_pxa300_init(void) if (cpu_is_pxa310()) { pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg)); gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102); - - /* MMC card detect & write protect for controller 2 */ - zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30); - zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31); } /* GPIOs for Debug LEDs */ diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 60d08f23f5e..9942bac4cf7 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -209,10 +209,6 @@ void __init zylonite_pxa320_init(void) 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); - zylonite_mmc_slot[0].gpio_wp = mfp_to_gpio(MFP_PIN_GPIO5); - /* WM9713 IRQ */ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO15); } diff --git a/arch/arm/mach-realview/include/mach/board-pb1176.h b/arch/arm/mach-realview/include/mach/board-pb1176.h index 34b80b7d40b..2f5ccb29885 100644 --- a/arch/arm/mach-realview/include/mach/board-pb1176.h +++ b/arch/arm/mach-realview/include/mach/board-pb1176.h @@ -74,8 +74,8 @@ #define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */ /* - * Control register SYS_RESETCTL is set to 1 to force a soft reset + * Control register SYS_RESETCTL Bit 8 is set to 1 to force a soft reset */ -#define REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL 0x0100 +#define REALVIEW_PB1176_SYS_SOFT_RESET 0x0100 #endif /* __ASM_ARCH_BOARD_PB1176_H */ diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h index 4f46bf71e75..86c0c4435a4 100644 --- a/arch/arm/mach-realview/include/mach/platform.h +++ b/arch/arm/mach-realview/include/mach/platform.h @@ -140,7 +140,7 @@ * SYS_CLD, SYS_BOOTCS */ #define REALVIEW_SYS_LOCK_LOCKED (1 << 16) -#define REALVIEW_SYS_LOCKVAL_MASK 0xA05F /* Enable write access */ +#define REALVIEW_SYS_LOCK_VAL 0xA05F /* Enable write access */ /* * REALVIEW_SYS_FLASH diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 917f8ca3abf..7d857d30055 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -381,6 +381,20 @@ static struct sys_timer realview_eb_timer = { .init = realview_eb_timer_init, }; +static void realview_eb_reset(char mode) +{ + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); + + /* + * To reset, we hit the on-board reset register + * in the system FPGA + */ + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + if (core_tile_eb11mp()) + __raw_writel(0x0008, reset_ctrl); +} + static void __init realview_eb_init(void) { int i; @@ -408,6 +422,7 @@ static void __init realview_eb_init(void) #ifdef CONFIG_LEDS leds_event = realview_leds_event; #endif + realview_reset = realview_eb_reset; } MACHINE_START(REALVIEW_EB, "ARM-RealView EB") diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index 7fb726d5f8b..44392e51dd5 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -292,12 +292,10 @@ static struct sys_timer realview_pb1176_timer = { static void realview_pb1176_reset(char mode) { - void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_RESETCTL_OFFSET; - void __iomem *rst_hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_LOCK_OFFSET; - __raw_writel(REALVIEW_SYS_LOCKVAL_MASK, rst_hdr_ctrl); - __raw_writel(REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL, hdr_ctrl); + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + __raw_writel(REALVIEW_PB1176_SYS_SOFT_RESET, reset_ctrl); } static void realview_pb1176_fixup(struct machine_desc *mdesc, diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 9bbbfc05f22..3e02731af95 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -301,17 +301,16 @@ static struct sys_timer realview_pb11mp_timer = { static void realview_pb11mp_reset(char mode) { - void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + - REALVIEW_SYS_RESETCTL_OFFSET; - unsigned int val; + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); /* * To reset, we hit the on-board reset register * in the system FPGA */ - val = __raw_readl(hdr_ctrl); - val |= REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR; - __raw_writel(val, hdr_ctrl); + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + __raw_writel(0x0000, reset_ctrl); + __raw_writel(0x0004, reset_ctrl); } static void __init realview_pb11mp_init(void) diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index fe861e96c56..fe4e25c4201 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -272,6 +272,20 @@ static struct sys_timer realview_pba8_timer = { .init = realview_pba8_timer_init, }; +static void realview_pba8_reset(char mode) +{ + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); + + /* + * To reset, we hit the on-board reset register + * in the system FPGA + */ + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + __raw_writel(0x0000, reset_ctrl); + __raw_writel(0x0004, reset_ctrl); +} + static void __init realview_pba8_init(void) { int i; @@ -291,6 +305,7 @@ static void __init realview_pba8_init(void) #ifdef CONFIG_LEDS leds_event = realview_leds_event; #endif + realview_reset = realview_pba8_reset; } MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8") diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index ec39488e2b4..a21a4b395f7 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -324,6 +324,20 @@ static void realview_pbx_fixup(struct machine_desc *mdesc, struct tag *tags, #endif } +static void realview_pbx_reset(char mode) +{ + void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL); + void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK); + + /* + * To reset, we hit the on-board reset register + * in the system FPGA + */ + __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl); + __raw_writel(0x0000, reset_ctrl); + __raw_writel(0x0004, reset_ctrl); +} + static void __init realview_pbx_init(void) { int i; @@ -358,6 +372,7 @@ static void __init realview_pbx_init(void) #ifdef CONFIG_LEDS leds_event = realview_leds_event; #endif + realview_reset = realview_pbx_reset; } MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-core.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h index f8b879a7973..acb25910380 100644 --- a/arch/arm/mach-s3c2410/include/mach/gpio-core.h +++ b/arch/arm/mach-s3c2410/include/mach/gpio-track.h @@ -15,7 +15,6 @@ #ifndef __ASM_ARCH_GPIO_CORE_H #define __ASM_ARCH_GPIO_CORE_H __FILE__ -#include <plat/gpio-core.h> #include <mach/regs-gpio.h> extern struct s3c_gpio_chip s3c24xx_gpios[]; diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index 06a84adfb13..7047317ed7f 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -153,7 +153,7 @@ static struct platform_device *amlm5900_devices[] __initdata = { &s3c_device_adc, &s3c_device_wdt, &s3c_device_i2c0, - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_rtc, &s3c_device_usbgadget, &s3c_device_sdi, diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 97162fdd059..02b1b6220cb 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -584,7 +584,7 @@ static struct s3c_hwmon_pdata bast_hwmon_info = { // cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0 static struct platform_device *bast_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 1e34abe1a19..fbedd076094 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -196,7 +196,7 @@ static struct platform_device h1940_device_bluetooth = { .id = -1, }; -static struct s3c24xx_mci_pdata h1940_mmc_cfg = { +static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = { .gpio_detect = S3C2410_GPF(5), .gpio_wprotect = S3C2410_GPH(8), .set_power = NULL, @@ -272,7 +272,7 @@ static struct platform_device h1940_lcd_powerdev = { static struct platform_device *h1940_devices[] __initdata = { &s3c_device_ts, - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, @@ -311,12 +311,11 @@ static void __init h1940_init(void) u32 tmp; s3c24xx_fb_set_platdata(&h1940_fb_info); + s3c24xx_mci_set_platdata(&h1940_mmc_cfg); s3c24xx_udc_set_platdata(&h1940_udc_cfg); s3c24xx_ts_set_platdata(&h1940_ts_cfg); s3c_i2c0_set_platdata(NULL); - s3c_device_sdi.dev.platform_data = &h1940_mmc_cfg; - /* Turn off suspend on both USB ports, and switch the * selectable USB port to USB device mode. */ diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 0405712c226..684710f8814 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -322,7 +322,7 @@ static struct platform_device *n30_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_usbgadget, &n30_button_device, &n30_blue_led, diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index f6c7261a4a1..d8c7f2efc1a 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c @@ -92,7 +92,7 @@ static struct platform_device otom_device_nor = { /* Standard OTOM devices */ static struct platform_device *otom11_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c index ab092bcda39..92a4ec375d8 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c2410/mach-qt2410.c @@ -246,7 +246,7 @@ static struct platform_device qt2410_spi = { /* Board devices */ static struct platform_device *qt2410_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index c49126ccb1d..45222304220 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -87,7 +87,7 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = { }; static struct platform_device *smdk2410_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c index 8fdb0430bd4..929164a8e9b 100644 --- a/arch/arm/mach-s3c2410/mach-tct_hammer.c +++ b/arch/arm/mach-s3c2410/mach-tct_hammer.c @@ -129,7 +129,7 @@ static struct platform_device *tct_hammer_devices[] __initdata = { &s3c_device_adc, &s3c_device_wdt, &s3c_device_i2c0, - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_rtc, &s3c_device_usbgadget, &s3c_device_sdi, diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 0d61fb57717..9051f0d3112 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -334,7 +334,7 @@ static struct i2c_board_info vr1000_i2c_devs[] __initdata = { /* devices for this board */ static struct platform_device *vr1000_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c index 6b9d0d83a6f..29bd3d987be 100644 --- a/arch/arm/mach-s3c2410/usb-simtec.c +++ b/arch/arm/mach-s3c2410/usb-simtec.c @@ -91,7 +91,7 @@ static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on) } } -static struct s3c2410_hcd_info usb_simtec_info = { +static struct s3c2410_hcd_info usb_simtec_info __initdata = { .port[0] = { .flags = S3C_HCDFLG_USED }, @@ -127,6 +127,6 @@ int usb_simtec_init(void) gpio_direction_output(S3C2410_GPB(4), 1); gpio_direction_input(S3C2410_GPG(10)); - s3c_device_usb.dev.platform_data = &usb_simtec_info; + s3c_ohci_set_platdata(&usb_simtec_info); return 0; } diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c index a037df5e1c2..0c0505b025c 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c2412/clock.c @@ -124,7 +124,9 @@ static struct clk clk_usysclk = { .name = "usysclk", .id = -1, .parent = &clk_xtal, - .set_parent = s3c2412_setparent_usysclk, + .ops = &(struct clk_ops) { + .set_parent = s3c2412_setparent_usysclk, + }, }; static struct clk clk_mrefclk = { @@ -199,10 +201,12 @@ static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate) static struct clk clk_usbsrc = { .name = "usbsrc", .id = -1, - .get_rate = s3c2412_getrate_usbsrc, - .set_rate = s3c2412_setrate_usbsrc, - .round_rate = s3c2412_roundrate_usbsrc, - .set_parent = s3c2412_setparent_usbsrc, + .ops = &(struct clk_ops) { + .get_rate = s3c2412_getrate_usbsrc, + .set_rate = s3c2412_setrate_usbsrc, + .round_rate = s3c2412_roundrate_usbsrc, + .set_parent = s3c2412_setparent_usbsrc, + }, }; static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent) @@ -225,7 +229,9 @@ static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent) static struct clk clk_msysclk = { .name = "msysclk", .id = -1, - .set_parent = s3c2412_setparent_msysclk, + .ops = &(struct clk_ops) { + .set_parent = s3c2412_setparent_msysclk, + }, }; static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent) @@ -264,7 +270,9 @@ static struct clk clk_armclk = { .name = "armclk", .id = -1, .parent = &clk_msysclk, - .set_parent = s3c2412_setparent_armclk, + .ops = &(struct clk_ops) { + .set_parent = s3c2412_setparent_armclk, + }, }; /* these next clocks have an divider immediately after them, @@ -337,10 +345,12 @@ static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate) static struct clk clk_uart = { .name = "uartclk", .id = -1, - .get_rate = s3c2412_getrate_uart, - .set_rate = s3c2412_setrate_uart, - .set_parent = s3c2412_setparent_uart, - .round_rate = s3c2412_roundrate_clksrc, + .ops = &(struct clk_ops) { + .get_rate = s3c2412_getrate_uart, + .set_rate = s3c2412_setrate_uart, + .set_parent = s3c2412_setparent_uart, + .round_rate = s3c2412_roundrate_clksrc, + }, }; static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent) @@ -388,10 +398,12 @@ static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate) static struct clk clk_i2s = { .name = "i2sclk", .id = -1, - .get_rate = s3c2412_getrate_i2s, - .set_rate = s3c2412_setrate_i2s, - .set_parent = s3c2412_setparent_i2s, - .round_rate = s3c2412_roundrate_clksrc, + .ops = &(struct clk_ops) { + .get_rate = s3c2412_getrate_i2s, + .set_rate = s3c2412_setrate_i2s, + .set_parent = s3c2412_setparent_i2s, + .round_rate = s3c2412_roundrate_clksrc, + }, }; static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent) @@ -438,10 +450,12 @@ static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate) static struct clk clk_cam = { .name = "camif-upll", /* same as 2440 name */ .id = -1, - .get_rate = s3c2412_getrate_cam, - .set_rate = s3c2412_setrate_cam, - .set_parent = s3c2412_setparent_cam, - .round_rate = s3c2412_roundrate_clksrc, + .ops = &(struct clk_ops) { + .get_rate = s3c2412_getrate_cam, + .set_rate = s3c2412_setrate_cam, + .set_parent = s3c2412_setparent_cam, + .round_rate = s3c2412_roundrate_clksrc, + }, }; /* standard clock definitions */ diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c index c9fa3fca486..14f4798291a 100644 --- a/arch/arm/mach-s3c2412/mach-jive.c +++ b/arch/arm/mach-s3c2412/mach-jive.c @@ -468,7 +468,7 @@ static struct i2c_board_info jive_i2c_devs[] __initdata = { /* The platform devices being used. */ static struct platform_device *jive_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_rtc, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c index 9a5e4341972..0392065af1a 100644 --- a/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/arch/arm/mach-s3c2412/mach-smdk2413.c @@ -104,8 +104,7 @@ static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = { static struct platform_device *smdk2413_devices[] __initdata = { - &s3c_device_usb, - //&s3c_device_lcd, + &s3c_device_ohci, &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c index a6ba591b26b..3ca9265b699 100644 --- a/arch/arm/mach-s3c2412/mach-vstms.c +++ b/arch/arm/mach-s3c2412/mach-vstms.c @@ -121,7 +121,7 @@ static struct s3c2410_platform_nand __initdata vstms_nand_info = { }; static struct platform_device *vstms_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c index d1c29b2537c..3dc2426e234 100644 --- a/arch/arm/mach-s3c2440/clock.c +++ b/arch/arm/mach-s3c2440/clock.c @@ -98,8 +98,10 @@ static struct clk s3c2440_clk_cam = { static struct clk s3c2440_clk_cam_upll = { .name = "camif-upll", .id = -1, - .set_rate = s3c2440_camif_upll_setrate, - .round_rate = s3c2440_camif_upll_round, + .ops = &(struct clk_ops) { + .set_rate = s3c2440_camif_upll_setrate, + .round_rate = s3c2440_camif_upll_round, + }, }; static struct clk s3c2440_clk_ac97 = { diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index 62a4c3eba97..b73f78a9da5 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -409,7 +409,7 @@ static struct platform_device anubis_device_sm501 = { /* Standard Anubis devices */ static struct platform_device *anubis_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_wdt, &s3c_device_adc, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c index aa69290e04c..84725791e6b 100644 --- a/arch/arm/mach-s3c2440/mach-at2440evb.c +++ b/arch/arm/mach-s3c2440/mach-at2440evb.c @@ -165,7 +165,7 @@ static struct platform_device at2440evb_device_eth = { }, }; -static struct s3c24xx_mci_pdata at2440evb_mci_pdata = { +static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = { .gpio_detect = S3C2410_GPG(10), }; @@ -203,7 +203,7 @@ static struct s3c2410fb_mach_info at2440evb_fb_info __initdata = { }; static struct platform_device *at2440evb_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_wdt, &s3c_device_adc, &s3c_device_i2c0, @@ -216,8 +216,6 @@ static struct platform_device *at2440evb_devices[] __initdata = { static void __init at2440evb_map_io(void) { - s3c_device_sdi.dev.platform_data = &at2440evb_mci_pdata; - s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc)); s3c24xx_init_clocks(16934400); s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs)); @@ -226,6 +224,7 @@ static void __init at2440evb_map_io(void) static void __init at2440evb_init(void) { s3c24xx_fb_set_platdata(&at2440evb_fb_info); + s3c24xx_mci_set_platdata(&at2440evb_mci_pdata); s3c_nand_set_platdata(&at2440evb_nand_info); s3c_i2c0_set_platdata(NULL); diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c index 547d4fc9913..571b17683d9 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c2440/mach-mini2440.c @@ -288,7 +288,7 @@ static struct s3c2410_platform_nand mini2440_nand_info __initdata = { /* DM9000AEP 10/100 ethernet controller */ -static struct resource mini2440_dm9k_resource[] __initdata = { +static struct resource mini2440_dm9k_resource[] = { [0] = { .start = MACH_MINI2440_DM9K_BASE, .end = MACH_MINI2440_DM9K_BASE + 3, @@ -310,11 +310,11 @@ static struct resource mini2440_dm9k_resource[] __initdata = { * The DM9000 has no eeprom, and it's MAC address is set by * the bootloader before starting the kernel. */ -static struct dm9000_plat_data mini2440_dm9k_pdata __initdata = { +static struct dm9000_plat_data mini2440_dm9k_pdata = { .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), }; -static struct platform_device mini2440_device_eth __initdata = { +static struct platform_device mini2440_device_eth = { .name = "dm9000", .id = -1, .num_resources = ARRAY_SIZE(mini2440_dm9k_resource), @@ -341,7 +341,7 @@ static struct platform_device mini2440_device_eth __initdata = { * | | +----+ +----+ * ..... */ -static struct gpio_keys_button mini2440_buttons[] __initdata = { +static struct gpio_keys_button mini2440_buttons[] = { { .gpio = S3C2410_GPG(0), /* K1 */ .code = KEY_F1, @@ -384,12 +384,12 @@ static struct gpio_keys_button mini2440_buttons[] __initdata = { #endif }; -static struct gpio_keys_platform_data mini2440_button_data __initdata = { +static struct gpio_keys_platform_data mini2440_button_data = { .buttons = mini2440_buttons, .nbuttons = ARRAY_SIZE(mini2440_buttons), }; -static struct platform_device mini2440_button_device __initdata = { +static struct platform_device mini2440_button_device = { .name = "gpio-keys", .id = -1, .dev = { @@ -399,41 +399,41 @@ static struct platform_device mini2440_button_device __initdata = { /* LEDS */ -static struct s3c24xx_led_platdata mini2440_led1_pdata __initdata = { +static struct s3c24xx_led_platdata mini2440_led1_pdata = { .name = "led1", .gpio = S3C2410_GPB(5), .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .def_trigger = "heartbeat", }; -static struct s3c24xx_led_platdata mini2440_led2_pdata __initdata = { +static struct s3c24xx_led_platdata mini2440_led2_pdata = { .name = "led2", .gpio = S3C2410_GPB(6), .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .def_trigger = "nand-disk", }; -static struct s3c24xx_led_platdata mini2440_led3_pdata __initdata = { +static struct s3c24xx_led_platdata mini2440_led3_pdata = { .name = "led3", .gpio = S3C2410_GPB(7), .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .def_trigger = "mmc0", }; -static struct s3c24xx_led_platdata mini2440_led4_pdata __initdata = { +static struct s3c24xx_led_platdata mini2440_led4_pdata = { .name = "led4", .gpio = S3C2410_GPB(8), .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, .def_trigger = "", }; -static struct s3c24xx_led_platdata mini2440_led_backlight_pdata __initdata = { +static struct s3c24xx_led_platdata mini2440_led_backlight_pdata = { .name = "backlight", .gpio = S3C2410_GPG(4), .def_trigger = "backlight", }; -static struct platform_device mini2440_led1 __initdata = { +static struct platform_device mini2440_led1 = { .name = "s3c24xx_led", .id = 1, .dev = { @@ -441,7 +441,7 @@ static struct platform_device mini2440_led1 __initdata = { }, }; -static struct platform_device mini2440_led2 __initdata = { +static struct platform_device mini2440_led2 = { .name = "s3c24xx_led", .id = 2, .dev = { @@ -449,7 +449,7 @@ static struct platform_device mini2440_led2 __initdata = { }, }; -static struct platform_device mini2440_led3 __initdata = { +static struct platform_device mini2440_led3 = { .name = "s3c24xx_led", .id = 3, .dev = { @@ -457,7 +457,7 @@ static struct platform_device mini2440_led3 __initdata = { }, }; -static struct platform_device mini2440_led4 __initdata = { +static struct platform_device mini2440_led4 = { .name = "s3c24xx_led", .id = 4, .dev = { @@ -465,7 +465,7 @@ static struct platform_device mini2440_led4 __initdata = { }, }; -static struct platform_device mini2440_led_backlight __initdata = { +static struct platform_device mini2440_led_backlight = { .name = "s3c24xx_led", .id = 5, .dev = { @@ -475,14 +475,14 @@ static struct platform_device mini2440_led_backlight __initdata = { /* AUDIO */ -static struct s3c24xx_uda134x_platform_data mini2440_audio_pins __initdata = { +static struct s3c24xx_uda134x_platform_data mini2440_audio_pins = { .l3_clk = S3C2410_GPB(4), .l3_mode = S3C2410_GPB(2), .l3_data = S3C2410_GPB(3), .model = UDA134X_UDA1341 }; -static struct platform_device mini2440_audio __initdata = { +static struct platform_device mini2440_audio = { .name = "s3c24xx_uda134x", .id = 0, .dev = { @@ -506,9 +506,8 @@ static struct i2c_board_info mini2440_i2c_devs[] __initdata = { }; static struct platform_device *mini2440_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_wdt, -/* &s3c_device_adc,*/ /* ADC doesn't like living with touchscreen ! */ &s3c_device_i2c0, &s3c_device_rtc, &s3c_device_usbgadget, @@ -522,8 +521,6 @@ static struct platform_device *mini2440_devices[] __initdata = { &s3c_device_sdi, &s3c_device_iis, &mini2440_audio, -/* &s3c_device_timer[0],*/ /* buzzer pwm, no API for it */ - /* remaining devices are optional */ }; static void __init mini2440_map_io(void) @@ -531,8 +528,6 @@ static void __init mini2440_map_io(void) s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs)); - - s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg; } /* @@ -678,6 +673,7 @@ static void __init mini2440_init(void) } s3c24xx_udc_set_platdata(&mini2440_udc_cfg); + s3c24xx_mci_set_platdata(&mini2440_mmc_cfg); s3c_nand_set_platdata(&mini2440_nand_info); s3c_i2c0_set_platdata(NULL); diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c index d43edede590..86a243b3e37 100644 --- a/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/arch/arm/mach-s3c2440/mach-nexcoder.c @@ -106,7 +106,7 @@ static struct platform_device nexcoder_device_nor = { /* Standard Nexcoder devices */ static struct platform_device *nexcoder_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index a952a13afb1..1e836e506f8 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -176,7 +176,7 @@ static struct s3c2410_platform_nand __initdata rx3715_nand_info = { }; static struct platform_device *rx3715_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c index ec13e748ccc..df3e9a3be82 100644 --- a/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/arch/arm/mach-s3c2440/mach-smdk2440.c @@ -150,7 +150,7 @@ static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = { }; static struct platform_device *smdk2440_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c0, diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c index ea1aa1f5157..d9b692a1248 100644 --- a/arch/arm/mach-s3c2442/clock.c +++ b/arch/arm/mach-s3c2442/clock.c @@ -109,8 +109,10 @@ static struct clk s3c2442_clk_cam = { static struct clk s3c2442_clk_cam_upll = { .name = "camif-upll", .id = -1, - .set_rate = s3c2442_camif_upll_setrate, - .round_rate = s3c2442_camif_upll_round, + .ops = &(struct clk_ops) { + .set_rate = s3c2442_camif_upll_setrate, + .round_rate = s3c2442_camif_upll_round, + }, }; static int s3c2442_clk_add(struct sys_device *sysdev) diff --git a/arch/arm/mach-s3c2442/mach-gta02.c b/arch/arm/mach-s3c2442/mach-gta02.c index 0b4a3a03071..45799c608d8 100644 --- a/arch/arm/mach-s3c2442/mach-gta02.c +++ b/arch/arm/mach-s3c2442/mach-gta02.c @@ -544,7 +544,7 @@ static struct platform_device gta02_bl_dev = { /* USB */ -static struct s3c2410_hcd_info gta02_usb_info = { +static struct s3c2410_hcd_info gta02_usb_info __initdata = { .port[0] = { .flags = S3C_HCDFLG_USED, }, @@ -565,7 +565,7 @@ static void __init gta02_map_io(void) /* These are the guys that don't need to be children of PMU. */ static struct platform_device *gta02_devices[] __initdata = { - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_wdt, &s3c_device_sdi, &s3c_device_usbgadget, @@ -623,9 +623,8 @@ static void __init gta02_machine_init(void) INIT_DELAYED_WORK(>a02_charger_work, gta02_charger_worker); #endif - s3c_device_usb.dev.platform_data = >a02_usb_info; - s3c24xx_udc_set_platdata(>a02_udc_cfg); + s3c_ohci_set_platdata(>a02_usb_info); s3c_nand_set_platdata(>a02_nand_info); s3c_i2c0_set_platdata(NULL); diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 2785d69c95b..3eb8b935d64 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c @@ -187,7 +187,9 @@ static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent) static struct clk clk_epllref = { .name = "epllref", .id = -1, - .set_parent = s3c2443_setparent_epllref, + .ops = &(struct clk_ops) { + .set_parent = s3c2443_setparent_epllref, + }, }; static unsigned long s3c2443_getrate_mdivclk(struct clk *clk) @@ -205,7 +207,9 @@ static struct clk clk_mdivclk = { .name = "mdivclk", .parent = &clk_mpllref, .id = -1, - .get_rate = s3c2443_getrate_mdivclk, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_mdivclk, + }, }; static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent) @@ -232,7 +236,9 @@ static struct clk clk_msysclk = { .name = "msysclk", .parent = &clk_xtal, .id = -1, - .set_parent = s3c2443_setparent_msysclk, + .ops = &(struct clk_ops) { + .set_parent = s3c2443_setparent_msysclk, + }, }; /* armdiv @@ -273,7 +279,9 @@ static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent) static struct clk clk_arm = { .name = "armclk", .id = -1, - .set_parent = s3c2443_setparent_armclk, + .ops = &(struct clk_ops) { + .set_parent = s3c2443_setparent_armclk, + }, }; /* esysclk @@ -302,7 +310,9 @@ static struct clk clk_esysclk = { .name = "esysclk", .parent = &clk_epll, .id = -1, - .set_parent = s3c2443_setparent_esysclk, + .ops = &(struct clk_ops) { + .set_parent = s3c2443_setparent_esysclk, + }, }; /* uartclk @@ -341,9 +351,11 @@ static struct clk clk_uart = { .name = "uartclk", .id = -1, .parent = &clk_esysclk, - .get_rate = s3c2443_getrate_uart, - .set_rate = s3c2443_setrate_uart, - .round_rate = s3c2443_roundrate_clksrc16, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_uart, + .set_rate = s3c2443_setrate_uart, + .round_rate = s3c2443_roundrate_clksrc16, + }, }; /* hsspi @@ -384,9 +396,11 @@ static struct clk clk_hsspi = { .parent = &clk_esysclk, .ctrlbit = S3C2443_SCLKCON_HSSPICLK, .enable = s3c2443_clkcon_enable_s, - .get_rate = s3c2443_getrate_hsspi, - .set_rate = s3c2443_setrate_hsspi, - .round_rate = s3c2443_roundrate_clksrc4, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_hsspi, + .set_rate = s3c2443_setrate_hsspi, + .round_rate = s3c2443_roundrate_clksrc4, + }, }; /* usbhost @@ -426,9 +440,11 @@ static struct clk clk_usb_bus_host = { .parent = &clk_esysclk, .ctrlbit = S3C2443_SCLKCON_USBHOST, .enable = s3c2443_clkcon_enable_s, - .get_rate = s3c2443_getrate_usbhost, - .set_rate = s3c2443_setrate_usbhost, - .round_rate = s3c2443_roundrate_clksrc4, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_usbhost, + .set_rate = s3c2443_setrate_usbhost, + .round_rate = s3c2443_roundrate_clksrc4, + }, }; /* clk_hsmcc_div @@ -468,9 +484,11 @@ static struct clk clk_hsmmc_div = { .name = "hsmmc-div", .id = -1, .parent = &clk_esysclk, - .get_rate = s3c2443_getrate_hsmmc_div, - .set_rate = s3c2443_setrate_hsmmc_div, - .round_rate = s3c2443_roundrate_clksrc4, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_hsmmc_div, + .set_rate = s3c2443_setrate_hsmmc_div, + .round_rate = s3c2443_roundrate_clksrc4, + }, }; static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent) @@ -505,7 +523,9 @@ static struct clk clk_hsmmc = { .id = -1, .parent = &clk_hsmmc_div, .enable = s3c2443_enable_hsmmc, - .set_parent = s3c2443_setparent_hsmmc, + .ops = &(struct clk_ops) { + .set_parent = s3c2443_setparent_hsmmc, + }, }; /* i2s_eplldiv @@ -543,9 +563,11 @@ static struct clk clk_i2s_eplldiv = { .name = "i2s-eplldiv", .id = -1, .parent = &clk_esysclk, - .get_rate = s3c2443_getrate_i2s_eplldiv, - .set_rate = s3c2443_setrate_i2s_eplldiv, - .round_rate = s3c2443_roundrate_clksrc16, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_i2s_eplldiv, + .set_rate = s3c2443_setrate_i2s_eplldiv, + .round_rate = s3c2443_roundrate_clksrc16, + }, }; /* i2s-ref @@ -578,7 +600,9 @@ static struct clk clk_i2s = { .parent = &clk_i2s_eplldiv, .ctrlbit = S3C2443_SCLKCON_I2SCLK, .enable = s3c2443_clkcon_enable_s, - .set_parent = s3c2443_setparent_i2s, + .ops = &(struct clk_ops) { + .set_parent = s3c2443_setparent_i2s, + }, }; /* cam-if @@ -618,9 +642,11 @@ static struct clk clk_cam = { .parent = &clk_esysclk, .ctrlbit = S3C2443_SCLKCON_CAMCLK, .enable = s3c2443_clkcon_enable_s, - .get_rate = s3c2443_getrate_cam, - .set_rate = s3c2443_setrate_cam, - .round_rate = s3c2443_roundrate_clksrc16, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_cam, + .set_rate = s3c2443_setrate_cam, + .round_rate = s3c2443_roundrate_clksrc16, + }, }; /* display-if @@ -660,9 +686,11 @@ static struct clk clk_display = { .parent = &clk_esysclk, .ctrlbit = S3C2443_SCLKCON_DISPCLK, .enable = s3c2443_clkcon_enable_s, - .get_rate = s3c2443_getrate_display, - .set_rate = s3c2443_setrate_display, - .round_rate = s3c2443_roundrate_clksrc256, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_display, + .set_rate = s3c2443_setrate_display, + .round_rate = s3c2443_roundrate_clksrc256, + }, }; /* prediv @@ -685,7 +713,9 @@ static struct clk clk_prediv = { .name = "prediv", .id = -1, .parent = &clk_msysclk, - .get_rate = s3c2443_prediv_getrate, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_prediv_getrate, + }, }; /* standard clock definitions */ @@ -1074,14 +1104,7 @@ void __init s3c2443_init_clocks(int xtal) /* register clocks from clock array */ - clkp = init_clocks; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); /* We must be careful disabling the clocks we are not intending to * be using at boot time, as subsystems such as the LCD which do diff --git a/arch/arm/mach-s3c6400/include/mach/entry-macro.S b/arch/arm/mach-s3c6400/include/mach/entry-macro.S index fbd90d2cf35..33a8fe24088 100644 --- a/arch/arm/mach-s3c6400/include/mach/entry-macro.S +++ b/arch/arm/mach-s3c6400/include/mach/entry-macro.S @@ -12,33 +12,7 @@ * warranty of any kind, whether express or implied. */ -#include <asm/hardware/vic.h> #include <mach/map.h> #include <plat/irqs.h> - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - ldr \base, =S3C_VA_VIC0 - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - - @ check the vic0 - mov \irqnr, # S3C_IRQ_OFFSET + 31 - ldr \irqstat, [ \base, # VIC_IRQ_STATUS ] - teq \irqstat, #0 - - @ otherwise try vic1 - addeq \tmp, \base, #(S3C_VA_VIC1 - S3C_VA_VIC0) - addeq \irqnr, \irqnr, #32 - ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] - teqeq \irqstat, #0 - - clzne \irqstat, \irqstat - subne \irqnr, \irqnr, \irqstat - .endm +#include <asm/entry-macro-vic2.S> diff --git a/arch/arm/mach-s3c6400/include/mach/gpio-core.h b/arch/arm/mach-s3c6400/include/mach/gpio-core.h deleted file mode 100644 index d89aae68b0a..00000000000 --- a/arch/arm/mach-s3c6400/include/mach/gpio-core.h +++ /dev/null @@ -1,21 +0,0 @@ -/* arch/arm/mach-s3c6400/include/mach/gpio-core.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C64XX - GPIO core support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_GPIO_CORE_H -#define __ASM_ARCH_GPIO_CORE_H __FILE__ - -/* currently we just include the platform support */ -#include <plat/gpio-core.h> - -#endif /* __ASM_ARCH_GPIO_CORE_H */ diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h index 106ee13581e..801c1c0f3a9 100644 --- a/arch/arm/mach-s3c6400/include/mach/map.h +++ b/arch/arm/mach-s3c6400/include/mach/map.h @@ -17,6 +17,18 @@ #include <plat/map-base.h> +/* + * Post-mux Chip Select Regions Xm0CSn_ + * These may be used by SROM, NAND or CF depending on settings + */ + +#define S3C64XX_PA_XM0CSN0 (0x10000000) +#define S3C64XX_PA_XM0CSN1 (0x18000000) +#define S3C64XX_PA_XM0CSN2 (0x20000000) +#define S3C64XX_PA_XM0CSN3 (0x28000000) +#define S3C64XX_PA_XM0CSN4 (0x30000000) +#define S3C64XX_PA_XM0CSN5 (0x38000000) + /* HSMMC units */ #define S3C64XX_PA_HSMMC(x) (0x7C200000 + ((x) * 0x100000)) #define S3C64XX_PA_HSMMC0 S3C64XX_PA_HSMMC(0) @@ -38,16 +50,22 @@ #define S3C_VA_UART2 S3C_VA_UARTx(2) #define S3C_VA_UART3 S3C_VA_UARTx(3) +#define S3C64XX_PA_SROM (0x70000000) + #define S3C64XX_PA_NAND (0x70200000) #define S3C64XX_PA_FB (0x77100000) #define S3C64XX_PA_USB_HSOTG (0x7C000000) #define S3C64XX_PA_WATCHDOG (0x7E004000) +#define S3C64XX_PA_RTC (0x7E005000) +#define S3C64XX_PA_ADC (0x7E00B000) #define S3C64XX_PA_SYSCON (0x7E00F000) #define S3C64XX_PA_AC97 (0x7F001000) #define S3C64XX_PA_IIS0 (0x7F002000) #define S3C64XX_PA_IIS1 (0x7F003000) #define S3C64XX_PA_TIMER (0x7F006000) #define S3C64XX_PA_IIC0 (0x7F004000) +#define S3C64XX_PA_SPI0 (0x7F00B000) +#define S3C64XX_PA_SPI1 (0x7F00C000) #define S3C64XX_PA_PCM0 (0x7F009000) #define S3C64XX_PA_PCM1 (0x7F00A000) #define S3C64XX_PA_IISV4 (0x7F00D000) @@ -70,8 +88,8 @@ #define S3C64XX_VA_USB_HSPHY S3C_ADDR_CPU(0x00200000) /* place VICs close together */ -#define S3C_VA_VIC0 (S3C_VA_IRQ + 0x00) -#define S3C_VA_VIC1 (S3C_VA_IRQ + 0x10000) +#define VA_VIC0 (S3C_VA_IRQ + 0x00) +#define VA_VIC1 (S3C_VA_IRQ + 0x10000) /* compatibiltiy defines. */ #define S3C_PA_TIMER S3C64XX_PA_TIMER diff --git a/arch/arm/mach-s3c6400/include/mach/tick.h b/arch/arm/mach-s3c6400/include/mach/tick.h index d9c0dc7014e..ebe18a9469b 100644 --- a/arch/arm/mach-s3c6400/include/mach/tick.h +++ b/arch/arm/mach-s3c6400/include/mach/tick.h @@ -20,7 +20,7 @@ */ static inline u32 s3c24xx_ostimer_pending(void) { - u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS); + u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS); return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0)); } diff --git a/arch/arm/mach-s3c6410/mach-hmt.c b/arch/arm/mach-s3c6410/mach-hmt.c index cdd4b537855..284886c26a2 100644 --- a/arch/arm/mach-s3c6410/mach-hmt.c +++ b/arch/arm/mach-s3c6410/mach-hmt.c @@ -233,7 +233,7 @@ static struct platform_device *hmt_devices[] __initdata = { &s3c_device_i2c0, &s3c_device_nand, &s3c_device_fb, - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_timer[1], &hmt_backlight_device, &hmt_leds_device, diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c index 480d297c1de..eba345fadff 100644 --- a/arch/arm/mach-s3c6410/mach-smdk6410.c +++ b/arch/arm/mach-s3c6410/mach-smdk6410.c @@ -49,6 +49,7 @@ #include <plat/regs-modem.h> #include <plat/regs-gpio.h> #include <plat/regs-sys.h> +#include <plat/regs-srom.h> #include <plat/iic.h> #include <plat/fb.h> #include <plat/gpio-cfg.h> @@ -154,10 +155,20 @@ static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = { .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, }; +/* + * Configuring Ethernet on SMDK6410 + * + * Both CS8900A and LAN9115 chips share one chip select mediated by CFG6. + * The constant address below corresponds to nCS1 + * + * 1) Set CFGB2 p3 ON others off, no other CFGB selects "ethernet" + * 2) CFG6 needs to be switched to "LAN9115" side + */ + static struct resource smdk6410_smsc911x_resources[] = { [0] = { - .start = 0x18000000, - .end = 0x18000000 + SZ_64K - 1, + .start = S3C64XX_PA_XM0CSN1, + .end = S3C64XX_PA_XM0CSN1 + SZ_64K - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -211,6 +222,7 @@ static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = { .supply_name = "B_PWR_5V", .microvolts = 5000000, .init_data = &smdk6410_b_pwr_5v_data, + .gpio = -EINVAL, }; static struct platform_device smdk6410_b_pwr_5v = { @@ -234,7 +246,7 @@ static struct platform_device *smdk6410_devices[] __initdata = { &s3c_device_i2c0, &s3c_device_i2c1, &s3c_device_fb, - &s3c_device_usb, + &s3c_device_ohci, &s3c_device_usb_hsotg, #ifdef CONFIG_REGULATOR @@ -387,6 +399,7 @@ static int __init smdk6410_wm8350_init(struct wm8350 *wm8350) static struct wm8350_platform_data __initdata smdk6410_wm8350_pdata = { .init = smdk6410_wm8350_init, .irq_high = 1, + .irq_base = IRQ_BOARD_START, }; #endif @@ -429,10 +442,32 @@ static void __init smdk6410_map_io(void) static void __init smdk6410_machine_init(void) { + u32 cs1; + s3c_i2c0_set_platdata(NULL); s3c_i2c1_set_platdata(NULL); s3c_fb_set_platdata(&smdk6410_lcd_pdata); + /* configure nCS1 width to 16 bits */ + + cs1 = __raw_readl(S3C64XX_SROM_BW) & + ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT); + cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) | + (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) | + (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) << + S3C64XX_SROM_BW__NCS1__SHIFT; + __raw_writel(cs1, S3C64XX_SROM_BW); + + /* set timing for nCS1 suitable for ethernet chip */ + + __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) | + (6 << S3C64XX_SROM_BCX__TACP__SHIFT) | + (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) | + (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) | + (0xe << S3C64XX_SROM_BCX__TACC__SHIFT) | + (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | + (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); + gpio_request(S3C64XX_GPN(5), "LCD power"); gpio_request(S3C64XX_GPF(13), "LCD power"); gpio_request(S3C64XX_GPF(15), "LCD power"); diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig new file mode 100644 index 00000000000..3aa246244dc --- /dev/null +++ b/arch/arm/mach-s5p6440/Kconfig @@ -0,0 +1,23 @@ +# arch/arm/mach-s5p6440/Kconfig +# +# Copyright (c) 2009 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Licensed under GPLv2 + +if ARCH_S5P6440 + +config CPU_S5P6440 + bool + select CPU_S5P6440_INIT + select CPU_S5P6440_CLOCK + help + Enable S5P6440 CPU support + +config MACH_SMDK6440 + bool "SMDK6440" + select CPU_S5P6440 + help + Machine support for the Samsung SMDK6440 + +endif diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile new file mode 100644 index 00000000000..a79b13011ed --- /dev/null +++ b/arch/arm/mach-s5p6440/Makefile @@ -0,0 +1,19 @@ +# arch/arm/mach-s5p6440/Makefile +# +# Copyright (c) 2009 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Licensed under GPLv2 + +obj-y := +obj-m := +obj-n := +obj- := + +# Core support for S5P6440 system + +obj-$(CONFIG_CPU_S5P6440) += cpu.o s5p6440-gpio.o + +# machine support + +obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o diff --git a/arch/arm/mach-s5p6440/Makefile.boot b/arch/arm/mach-s5p6440/Makefile.boot new file mode 100644 index 00000000000..ff90aa13bd6 --- /dev/null +++ b/arch/arm/mach-s5p6440/Makefile.boot @@ -0,0 +1,2 @@ + zreladdr-y := 0x20008000 +params_phys-y := 0x20000100 diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c new file mode 100644 index 00000000000..1794131aeac --- /dev/null +++ b/arch/arm/mach-s5p6440/cpu.c @@ -0,0 +1,114 @@ +/* linux/arch/arm/mach-s5p6440/cpu.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/sysdev.h> +#include <linux/serial_core.h> +#include <linux/platform_device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/proc-fns.h> + +#include <mach/hardware.h> +#include <mach/map.h> +#include <asm/irq.h> + +#include <plat/regs-serial.h> +#include <mach/regs-clock.h> + +#include <plat/cpu.h> +#include <plat/devs.h> +#include <plat/clock.h> +#include <plat/s5p6440.h> + +static void s5p6440_idle(void) +{ + unsigned long val; + + if (!need_resched()) { + val = __raw_readl(S5P_PWR_CFG); + val &= ~(0x3<<5); + val |= (0x1<<5); + __raw_writel(val, S5P_PWR_CFG); + + cpu_do_idle(); + } + local_irq_enable(); +} + +/* s5p6440_map_io + * + * register the standard cpu IO areas +*/ + +void __init s5p6440_map_io(void) +{ + /* initialize any device information early */ +} + +void __init s5p6440_init_clocks(int xtal) +{ + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + s5p6440_register_clocks(); + s5p6440_setup_clocks(); +} + +void __init s5p6440_init_irq(void) +{ + /* S5P6440 supports only 2 VIC */ + u32 vic[2]; + + /* + * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)] + * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22] + */ + vic[0] = 0xff800ae7; + vic[1] = 0xffbf23e5; + + s5p_init_irq(vic, ARRAY_SIZE(vic)); +} + +static struct sysdev_class s5p6440_sysclass = { + .name = "s5p6440-core", +}; + +static struct sys_device s5p6440_sysdev = { + .cls = &s5p6440_sysclass, +}; + +static int __init s5p6440_core_init(void) +{ + return sysdev_class_register(&s5p6440_sysclass); +} + +core_initcall(s5p6440_core_init); + +int __init s5p6440_init(void) +{ + printk(KERN_INFO "S5P6440: Initializing architecture\n"); + + /* set idle function */ + pm_idle = s5p6440_idle; + + return sysdev_register(&s5p6440_sysdev); +} diff --git a/arch/arm/mach-s5p6440/include/mach/debug-macro.S b/arch/arm/mach-s5p6440/include/mach/debug-macro.S new file mode 100644 index 00000000000..f3a5d1635be --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/debug-macro.S @@ -0,0 +1,37 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/debug-macro.S + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/* pull in the relevant register and map files. */ + +#include <mach/map.h> +#include <plat/regs-serial.h> + + /* note, for the boot process to work we have to keep the UART + * virtual address aligned to an 1MiB boundary for the L1 + * mapping the head code makes. We keep the UART virtual address + * aligned and add in the offset when we load the value here. + */ + + .macro addruart, rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 + ldreq \rx, = S5P_PA_UART + ldrne \rx, = (S5P_VA_UART + S5P_PA_UART & 0xfffff) +#if CONFIG_DEBUG_S3C_UART != 0 + add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART) +#endif + .endm + +/* include the reset of the code which will do the work, we're only + * compiling for a single cpu processor type so the default of s3c2440 + * will be fine with us. + */ + +#include <plat/debug-macro.S> diff --git a/arch/arm/mach-s5p6440/include/mach/entry-macro.S b/arch/arm/mach-s5p6440/include/mach/entry-macro.S new file mode 100644 index 00000000000..e65f1b96726 --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/entry-macro.S @@ -0,0 +1,16 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/entry-macro.S + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Low-level IRQ helper macros for the Samsung S5P6440 + * + * This program is free software; you can 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 <mach/map.h> +#include <plat/irqs.h> + +#include <asm/entry-macro-vic2.S> diff --git a/arch/arm/mach-s5p6440/include/mach/gpio.h b/arch/arm/mach-s5p6440/include/mach/gpio.h new file mode 100644 index 00000000000..21783834f2a --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/gpio.h @@ -0,0 +1,80 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/gpio.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - 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 version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H __FILE__ + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep +#define gpio_to_irq __gpio_to_irq + +/* GPIO bank sizes */ +#define S5P6440_GPIO_A_NR (6) +#define S5P6440_GPIO_B_NR (7) +#define S5P6440_GPIO_C_NR (8) +#define S5P6440_GPIO_F_NR (2) +#define S5P6440_GPIO_G_NR (7) +#define S5P6440_GPIO_H_NR (10) +#define S5P6440_GPIO_I_NR (16) +#define S5P6440_GPIO_J_NR (12) +#define S5P6440_GPIO_N_NR (16) +#define S5P6440_GPIO_P_NR (8) +#define S5P6440_GPIO_R_NR (15) + +/* GPIO bank numbers */ + +/* CONFIG_S3C_GPIO_SPACE allows the user to select extra + * space for debugging purposes so that any accidental + * change from one gpio bank to another can be caught. +*/ +#define S5P6440_GPIO_NEXT(__gpio) \ + ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) + +enum s5p_gpio_number { + S5P6440_GPIO_A_START = 0, + S5P6440_GPIO_B_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_A), + S5P6440_GPIO_C_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_B), + S5P6440_GPIO_F_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_C), + S5P6440_GPIO_G_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_F), + S5P6440_GPIO_H_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_G), + S5P6440_GPIO_I_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_H), + S5P6440_GPIO_J_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_I), + S5P6440_GPIO_N_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_J), + S5P6440_GPIO_P_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_N), + S5P6440_GPIO_R_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_P), +}; + +/* S5P6440 GPIO number definitions. */ +#define S5P6440_GPA(_nr) (S5P6440_GPIO_A_START + (_nr)) +#define S5P6440_GPB(_nr) (S5P6440_GPIO_B_START + (_nr)) +#define S5P6440_GPC(_nr) (S5P6440_GPIO_C_START + (_nr)) +#define S5P6440_GPF(_nr) (S5P6440_GPIO_F_START + (_nr)) +#define S5P6440_GPG(_nr) (S5P6440_GPIO_G_START + (_nr)) +#define S5P6440_GPH(_nr) (S5P6440_GPIO_H_START + (_nr)) +#define S5P6440_GPI(_nr) (S5P6440_GPIO_I_START + (_nr)) +#define S5P6440_GPJ(_nr) (S5P6440_GPIO_J_START + (_nr)) +#define S5P6440_GPN(_nr) (S5P6440_GPIO_N_START + (_nr)) +#define S5P6440_GPP(_nr) (S5P6440_GPIO_P_START + (_nr)) +#define S5P6440_GPR(_nr) (S5P6440_GPIO_R_START + (_nr)) + +/* the end of the S5P6440 specific gpios */ +#define S5P6440_GPIO_END (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1) +#define S3C_GPIO_END S5P6440_GPIO_END + +/* define the number of gpios we need to the one after the GPR() range */ +#define ARCH_NR_GPIOS (S5P6440_GPR(S5P6440_GPIO_R_NR) + \ + CONFIG_SAMSUNG_GPIO_EXTRA + 1) + +#include <asm-generic/gpio.h> + +#endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/hardware.h b/arch/arm/mach-s5p6440/include/mach/hardware.h new file mode 100644 index 00000000000..be8b26e875d --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/hardware.h @@ -0,0 +1,18 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/hardware.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - Hardware support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H __FILE__ + +/* currently nothing here, placeholder */ + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/irqs.h b/arch/arm/mach-s5p6440/include/mach/irqs.h new file mode 100644 index 00000000000..a4b9b40d18f --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/irqs.h @@ -0,0 +1,111 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/irqs.h + * + * Copyright 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - IRQ definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_S5P_IRQS_H +#define __ASM_ARCH_S5P_IRQS_H __FILE__ + +#include <plat/irqs.h> + +/* VIC0 */ + +#define IRQ_EINT0_3 S5P_IRQ_VIC0(0) +#define IRQ_EINT4_11 S5P_IRQ_VIC0(1) +#define IRQ_RTC_TIC S5P_IRQ_VIC0(2) +#define IRQ_IIC1 S5P_IRQ_VIC0(5) +#define IRQ_I2SV40 S5P_IRQ_VIC0(6) +#define IRQ_GPS S5P_IRQ_VIC0(7) +#define IRQ_POST0 S5P_IRQ_VIC0(9) +#define IRQ_2D S5P_IRQ_VIC0(11) +#define IRQ_TIMER0_VIC S5P_IRQ_VIC0(23) +#define IRQ_TIMER1_VIC S5P_IRQ_VIC0(24) +#define IRQ_TIMER2_VIC S5P_IRQ_VIC0(25) +#define IRQ_WDT S5P_IRQ_VIC0(26) +#define IRQ_TIMER3_VIC S5P_IRQ_VIC0(27) +#define IRQ_TIMER4_VIC S5P_IRQ_VIC0(28) +#define IRQ_DISPCON0 S5P_IRQ_VIC0(29) +#define IRQ_DISPCON1 S5P_IRQ_VIC0(30) +#define IRQ_DISPCON2 S5P_IRQ_VIC0(31) + +/* VIC1 */ + +#define IRQ_EINT12_15 S5P_IRQ_VIC1(0) +#define IRQ_PCM0 S5P_IRQ_VIC1(2) +#define IRQ_UART0 S5P_IRQ_VIC1(5) +#define IRQ_UART1 S5P_IRQ_VIC1(6) +#define IRQ_UART2 S5P_IRQ_VIC1(7) +#define IRQ_UART3 S5P_IRQ_VIC1(8) +#define IRQ_DMA0 S5P_IRQ_VIC1(9) +#define IRQ_NFC S5P_IRQ_VIC1(13) +#define IRQ_SPI0 S5P_IRQ_VIC1(16) +#define IRQ_SPI1 S5P_IRQ_VIC1(17) +#define IRQ_IIC S5P_IRQ_VIC1(18) +#define IRQ_DISPCON3 S5P_IRQ_VIC1(19) +#define IRQ_FIMGVG S5P_IRQ_VIC1(20) +#define IRQ_EINT_GROUPS S5P_IRQ_VIC1(21) +#define IRQ_PMUIRQ S5P_IRQ_VIC1(23) +#define IRQ_HSMMC0 S5P_IRQ_VIC1(24) +#define IRQ_HSMMC1 S5P_IRQ_VIC1(25) +#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */ +#define IRQ_OTG S5P_IRQ_VIC1(26) +#define IRQ_DSI S5P_IRQ_VIC1(27) +#define IRQ_RTC_ALARM S5P_IRQ_VIC1(28) +#define IRQ_TSI S5P_IRQ_VIC1(29) +#define IRQ_PENDN S5P_IRQ_VIC1(30) +#define IRQ_TC IRQ_PENDN +#define IRQ_ADC S5P_IRQ_VIC1(31) + +/* + * Since the IRQ_EINT(x) are a linear mapping on s5p6440 we just defined + * them as an IRQ_EINT(x) macro from S5P_IRQ_EINT_BASE which we place + * after the pair of VICs. + */ + +#define S5P_IRQ_EINT_BASE (S5P_IRQ_VIC1(31) + 6) + +#define S5P_EINT(x) ((x) + S5P_IRQ_EINT_BASE) +#define IRQ_EINT(x) S5P_EINT(x) + +/* + * Next the external interrupt groups. These are similar to the IRQ_EINT(x) + * that they are sourced from the GPIO pins but with a different scheme for + * priority and source indication. + * + * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO + * interrupts, but for historical reasons they are kept apart from these + * next interrupts. + * + * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the + * machine specific support files. + */ + +/* Actually, #6 and #7 are missing in the EINT_GROUP1 */ +#define IRQ_EINT_GROUP1_NR (15) +#define IRQ_EINT_GROUP2_NR (8) +#define IRQ_EINT_GROUP5_NR (7) +#define IRQ_EINT_GROUP6_NR (10) +/* Actually, #0, #1 and #2 are missing in the EINT_GROUP8 */ +#define IRQ_EINT_GROUP8_NR (11) + +#define IRQ_EINT_GROUP_BASE S5P_EINT(16) +#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0) +#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR) +#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR) +#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR) +#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR) + +#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x)) + +/* Set the default NR_IRQS */ + +#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1) + +#endif /* __ASM_ARCH_S5P_IRQS_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h new file mode 100644 index 00000000000..4a73e73c942 --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/map.h @@ -0,0 +1,107 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/map.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - Memory map definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_MAP_H +#define __ASM_ARCH_MAP_H __FILE__ + +#include <plat/map-base.h> + +/* Chip ID */ +#define S5P6440_PA_CHIPID (0xE0000000) +#define S5P_PA_CHIPID S5P6440_PA_CHIPID +#define S5P_VA_CHIPID S3C_ADDR(0x00700000) + +/* SYSCON */ +#define S5P6440_PA_SYSCON (0xE0100000) +#define S5P_PA_SYSCON S5P6440_PA_SYSCON +#define S5P_VA_SYSCON S3C_VA_SYS + +#define S5P6440_PA_CLK (S5P6440_PA_SYSCON + 0x0) +#define S5P_PA_CLK S5P6440_PA_CLK +#define S5P_VA_CLK (S5P_VA_SYSCON + 0x0) + +/* GPIO */ +#define S5P6440_PA_GPIO (0xE0308000) +#define S5P_PA_GPIO S5P6440_PA_GPIO +#define S5P_VA_GPIO S3C_ADDR(0x00500000) + +/* VIC0 */ +#define S5P6440_PA_VIC0 (0xE4000000) +#define S5P_PA_VIC0 S5P6440_PA_VIC0 +#define S5P_VA_VIC0 (S3C_VA_IRQ + 0x0) +#define VA_VIC0 S5P_VA_VIC0 + +/* VIC1 */ +#define S5P6440_PA_VIC1 (0xE4100000) +#define S5P_PA_VIC1 S5P6440_PA_VIC1 +#define S5P_VA_VIC1 (S3C_VA_IRQ + 0x10000) +#define VA_VIC1 S5P_VA_VIC1 + +/* Timer */ +#define S5P6440_PA_TIMER (0xEA000000) +#define S5P_PA_TIMER S5P6440_PA_TIMER +#define S5P_VA_TIMER S3C_VA_TIMER + +/* RTC */ +#define S5P6440_PA_RTC (0xEA100000) +#define S5P_PA_RTC S5P6440_PA_RTC +#define S5P_VA_RTC S3C_ADDR(0x00600000) + +/* WDT */ +#define S5P6440_PA_WDT (0xEA200000) +#define S5P_PA_WDT S5P6440_PA_WDT +#define S5p_VA_WDT S3C_VA_WATCHDOG + +/* UART */ +#define S5P6440_PA_UART (0xEC000000) +#define S5P_PA_UART S5P6440_PA_UART +#define S5P_VA_UART S3C_VA_UART + +/* HS USB OtG */ +#define S5P6440_PA_HSOTG (0xED100000) + +/* HSMMC */ +#define S5P6440_PA_HSMMC0 (0xED800000) +#define S5P6440_PA_HSMMC1 (0xED900000) +#define S5P6440_PA_HSMMC2 (0xEDA00000) + +#define S5P_PA_UART0 (S5P_PA_UART + 0x0) +#define S5P_PA_UART1 (S5P_PA_UART + 0x400) +#define S5P_PA_UART2 (S5P_PA_UART + 0x800) +#define S5P_PA_UART3 (S5P_PA_UART + 0xC00) +#define S5P_UART_OFFSET (0x400) + +#define S5P_VA_UARTx(x) (S5P_VA_UART + (S5P_PA_UART & 0xfffff) \ + + ((x) * S5P_UART_OFFSET)) + +#define S5P_VA_UART0 S5P_VA_UARTx(0) +#define S5P_VA_UART1 S5P_VA_UARTx(1) +#define S5P_VA_UART2 S5P_VA_UARTx(2) +#define S5P_VA_UART3 S5P_VA_UARTx(3) +#define S5P_SZ_UART SZ_256 + +/* I2C */ +#define S5P6440_PA_IIC0 (0xEC104000) +#define S5P_PA_IIC0 S5P6440_PA_IIC0 +#define S5p_VA_IIC0 S3C_ADDR(0x00700000) + +/* SDRAM */ +#define S5P6440_PA_SDRAM (0x20000000) +#define S5P_PA_SDRAM S5P6440_PA_SDRAM + +/* compatibiltiy defines. */ +#define S3C_PA_UART S5P_PA_UART +#define S3C_UART_OFFSET S5P_UART_OFFSET +#define S3C_PA_TIMER S5P_PA_TIMER +#define S3C_PA_IIC S5P_PA_IIC0 + +#endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/memory.h b/arch/arm/mach-s5p6440/include/mach/memory.h new file mode 100644 index 00000000000..d62910c71b5 --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/memory.h @@ -0,0 +1,19 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/memory.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - Memory definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +#define PHYS_OFFSET UL(0x20000000) +#define CONSISTENT_DMA_SIZE SZ_8M + +#endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h b/arch/arm/mach-s5p6440/include/mach/pwm-clock.h new file mode 100644 index 00000000000..c4bb7c55547 --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/pwm-clock.h @@ -0,0 +1,62 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h + * + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * Copyright 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - pwm clock and timer support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/** + * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk + * @cfg: The timer TCFG1 register bits shifted down to 0. + * + * Return true if the given configuration from TCFG1 is a TCLK instead + * any of the TDIV clocks. + */ +static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) +{ + return tcfg == S3C2410_TCFG1_MUX_TCLK; +} + +/** + * tcfg_to_divisor() - convert tcfg1 setting to a divisor + * @tcfg1: The tcfg1 setting, shifted down. + * + * Get the divisor value for the given tcfg1 setting. We assume the + * caller has already checked to see if this is not a TCLK source. + */ +static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) +{ + return 1 << (1 + tcfg1); +} + +/** + * pwm_tdiv_has_div1() - does the tdiv setting have a /1 + * + * Return true if we have a /1 in the tdiv setting. + */ +static inline unsigned int pwm_tdiv_has_div1(void) +{ + return 0; +} + +/** + * pwm_tdiv_div_bits() - calculate TCFG1 divisor value. + * @div: The divisor to calculate the bit information for. + * + * Turn a divisor into the necessary bit field for TCFG1. + */ +static inline unsigned long pwm_tdiv_div_bits(unsigned int div) +{ + return ilog2(div) - 1; +} + +#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK diff --git a/arch/arm/mach-s5p6440/include/mach/regs-clock.h b/arch/arm/mach-s5p6440/include/mach/regs-clock.h new file mode 100644 index 00000000000..b7af28342bc --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/regs-clock.h @@ -0,0 +1,130 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/regs-clock.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - Clock register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_REGS_CLOCK_H +#define __ASM_ARCH_REGS_CLOCK_H __FILE__ + +#include <mach/map.h> + +#define S5P_CLKREG(x) (S5P_VA_CLK + (x)) + +#define S5P_APLL_LOCK S5P_CLKREG(0x00) +#define S5P_MPLL_LOCK S5P_CLKREG(0x04) +#define S5P_EPLL_LOCK S5P_CLKREG(0x08) +#define S5P_APLL_CON S5P_CLKREG(0x0C) +#define S5P_MPLL_CON S5P_CLKREG(0x10) +#define S5P_EPLL_CON S5P_CLKREG(0x14) +#define S5P_EPLL_CON_K S5P_CLKREG(0x18) +#define S5P_CLK_SRC0 S5P_CLKREG(0x1C) +#define S5P_CLK_DIV0 S5P_CLKREG(0x20) +#define S5P_CLK_DIV1 S5P_CLKREG(0x24) +#define S5P_CLK_DIV2 S5P_CLKREG(0x28) +#define S5P_CLK_OUT S5P_CLKREG(0x2C) +#define S5P_CLK_GATE_HCLK0 S5P_CLKREG(0x30) +#define S5P_CLK_GATE_PCLK S5P_CLKREG(0x34) +#define S5P_CLK_GATE_SCLK0 S5P_CLKREG(0x38) +#define S5P_CLK_GATE_MEM0 S5P_CLKREG(0x3C) +#define S5P_CLK_DIV3 S5P_CLKREG(0x40) +#define S5P_CLK_GATE_HCLK1 S5P_CLKREG(0x44) +#define S5P_CLK_GATE_SCLK1 S5P_CLKREG(0x48) +#define S5P_AHB_CON0 S5P_CLKREG(0x100) +#define S5P_CLK_SRC1 S5P_CLKREG(0x10C) +#define S5P_SWRESET S5P_CLKREG(0x114) +#define S5P_SYS_ID S5P_CLKREG(0x118) +#define S5P_SYS_OTHERS S5P_CLKREG(0x11C) +#define S5P_MEM_CFG_STAT S5P_CLKREG(0x12C) +#define S5P_PWR_CFG S5P_CLKREG(0x804) +#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0x808) +#define S5P_NORMAL_CFG S5P_CLKREG(0x810) +#define S5P_STOP_CFG S5P_CLKREG(0x814) +#define S5P_SLEEP_CFG S5P_CLKREG(0x818) +#define S5P_OSC_FREQ S5P_CLKREG(0x820) +#define S5P_OSC_STABLE S5P_CLKREG(0x824) +#define S5P_PWR_STABLE S5P_CLKREG(0x828) +#define S5P_MTC_STABLE S5P_CLKREG(0x830) +#define S5P_OTHERS S5P_CLKREG(0x900) +#define S5P_RST_STAT S5P_CLKREG(0x904) +#define S5P_WAKEUP_STAT S5P_CLKREG(0x908) +#define S5P_SLPEN S5P_CLKREG(0x930) +#define S5P_INFORM0 S5P_CLKREG(0xA00) +#define S5P_INFORM1 S5P_CLKREG(0xA04) +#define S5P_INFORM2 S5P_CLKREG(0xA08) +#define S5P_INFORM3 S5P_CLKREG(0xA0C) + +/* CLKDIV0 */ +#define S5P_CLKDIV0_PCLK_MASK (0xf << 12) +#define S5P_CLKDIV0_PCLK_SHIFT (12) +#define S5P_CLKDIV0_HCLK_MASK (0xf << 8) +#define S5P_CLKDIV0_HCLK_SHIFT (8) +#define S5P_CLKDIV0_MPLL_MASK (0x1 << 4) +#define S5P_CLKDIV0_ARM_MASK (0xf << 0) +#define S5P_CLKDIV0_ARM_SHIFT (0) + +/* CLKDIV3 */ +#define S5P_CLKDIV3_PCLK_LOW_MASK (0xf << 12) +#define S5P_CLKDIV3_PCLK_LOW_SHIFT (12) +#define S5P_CLKDIV3_HCLK_LOW_MASK (0xf << 8) +#define S5P_CLKDIV3_HCLK_LOW_SHIFT (8) + +/* HCLK0 GATE Registers */ +#define S5P_CLKCON_HCLK0_USB (1<<20) +#define S5P_CLKCON_HCLK0_HSMMC2 (1<<19) +#define S5P_CLKCON_HCLK0_HSMMC1 (1<<18) +#define S5P_CLKCON_HCLK0_HSMMC0 (1<<17) +#define S5P_CLKCON_HCLK0_POST0 (1<<5) + +/* HCLK1 GATE Registers */ +#define S5P_CLKCON_HCLK1_DISPCON (1<<1) + +/* PCLK GATE Registers */ +#define S5P_CLKCON_PCLK_IIS2 (1<<26) +#define S5P_CLKCON_PCLK_SPI1 (1<<22) +#define S5P_CLKCON_PCLK_SPI0 (1<<21) +#define S5P_CLKCON_PCLK_GPIO (1<<18) +#define S5P_CLKCON_PCLK_IIC0 (1<<17) +#define S5P_CLKCON_PCLK_TSADC (1<<12) +#define S5P_CLKCON_PCLK_PWM (1<<7) +#define S5P_CLKCON_PCLK_RTC (1<<6) +#define S5P_CLKCON_PCLK_WDT (1<<5) +#define S5P_CLKCON_PCLK_UART3 (1<<4) +#define S5P_CLKCON_PCLK_UART2 (1<<3) +#define S5P_CLKCON_PCLK_UART1 (1<<2) +#define S5P_CLKCON_PCLK_UART0 (1<<1) + +/* SCLK0 GATE Registers */ +#define S5P_CLKCON_SCLK0_MMC2_48 (1<<29) +#define S5P_CLKCON_SCLK0_MMC1_48 (1<<28) +#define S5P_CLKCON_SCLK0_MMC0_48 (1<<27) +#define S5P_CLKCON_SCLK0_MMC2 (1<<26) +#define S5P_CLKCON_SCLK0_MMC1 (1<<25) +#define S5P_CLKCON_SCLK0_MMC0 (1<<24) +#define S5P_CLKCON_SCLK0_SPI1_48 (1<<23) +#define S5P_CLKCON_SCLK0_SPI0_48 (1<<22) +#define S5P_CLKCON_SCLK0_SPI1 (1<<21) +#define S5P_CLKCON_SCLK0_SPI0 (1<<20) +#define S5P_CLKCON_SCLK0_UART (1<<5) + +/* SCLK1 GATE Registers */ + +/* MEM0 GATE Registers */ +#define S5P_CLKCON_MEM0_HCLK_NFCON (1<<2) + +/*OTHERS Resgister */ +#define S5P_OTHERS_USB_SIG_MASK (1<<16) +#define S5P_OTHERS_HCLK_LOW_SEL_MPLL (1<<6) + +/* Compatibility defines */ +#define ARM_CLK_DIV S5P_CLK_DIV0 +#define ARM_DIV_RATIO_SHIFT 0 +#define ARM_DIV_MASK (0xf << ARM_DIV_RATIO_SHIFT) + +#endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/regs-gpio.h b/arch/arm/mach-s5p6440/include/mach/regs-gpio.h new file mode 100644 index 00000000000..82ff753913d --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/regs-gpio.h @@ -0,0 +1,54 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/regs-gpio.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - GPIO register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_REGS_GPIO_H +#define __ASM_ARCH_REGS_GPIO_H __FILE__ + +#include <mach/map.h> + +/* Base addresses for each of the banks */ +#define S5P6440_GPA_BASE (S5P_VA_GPIO + 0x0000) +#define S5P6440_GPB_BASE (S5P_VA_GPIO + 0x0020) +#define S5P6440_GPC_BASE (S5P_VA_GPIO + 0x0040) +#define S5P6440_GPF_BASE (S5P_VA_GPIO + 0x00A0) +#define S5P6440_GPG_BASE (S5P_VA_GPIO + 0x00C0) +#define S5P6440_GPH_BASE (S5P_VA_GPIO + 0x00E0) +#define S5P6440_GPI_BASE (S5P_VA_GPIO + 0x0100) +#define S5P6440_GPJ_BASE (S5P_VA_GPIO + 0x0120) +#define S5P6440_GPN_BASE (S5P_VA_GPIO + 0x0830) +#define S5P6440_GPP_BASE (S5P_VA_GPIO + 0x0160) +#define S5P6440_GPR_BASE (S5P_VA_GPIO + 0x0290) +#define S5P6440_EINT0CON0 (S5P_VA_GPIO + 0x900) +#define S5P6440_EINT0FLTCON0 (S5P_VA_GPIO + 0x910) +#define S5P6440_EINT0FLTCON1 (S5P_VA_GPIO + 0x914) +#define S5P6440_EINT0MASK (S5P_VA_GPIO + 0x920) +#define S5P6440_EINT0PEND (S5P_VA_GPIO + 0x924) + +/* for LCD */ +#define S5P6440_SPCON_LCD_SEL_RGB (1 << 0) +#define S5P6440_SPCON_LCD_SEL_MASK (3 << 0) + +/* These set of macros are not really useful for the + * GPF/GPI/GPJ/GPN/GPP, + * useful for others set of GPIO's (4 bit) + */ +#define S5P6440_GPIO_CONMASK(__gpio) (0xf << ((__gpio) * 4)) +#define S5P6440_GPIO_INPUT(__gpio) (0x0 << ((__gpio) * 4)) +#define S5P6440_GPIO_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) + +/* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit) + * */ +#define S5P6440_GPIO2_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) +#define S5P6440_GPIO2_INPUT(__gpio) (0x0 << ((__gpio) * 2)) +#define S5P6440_GPIO2_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) + +#endif /* __ASM_ARCH_REGS_GPIO_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/regs-irq.h b/arch/arm/mach-s5p6440/include/mach/regs-irq.h new file mode 100644 index 00000000000..a961f4beeb0 --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/regs-irq.h @@ -0,0 +1,19 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/regs-irq.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - IRQ register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_REGS_IRQ_H +#define __ASM_ARCH_REGS_IRQ_H __FILE__ + +#include <asm/hardware/vic.h> +#include <mach/map.h> + +#endif /* __ASM_ARCH_REGS_IRQ_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/system.h b/arch/arm/mach-s5p6440/include/mach/system.h new file mode 100644 index 00000000000..d2dd817da66 --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/system.h @@ -0,0 +1,26 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/system.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - system support header + * + * This program is free software; you can 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_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H __FILE__ + +static void arch_idle(void) +{ + /* nothing here yet */ +} + +static void arch_reset(char mode, const char *cmd) +{ + /* nothing here yet */ +} + +#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/tick.h b/arch/arm/mach-s5p6440/include/mach/tick.h new file mode 100644 index 00000000000..0815aeb4f2c --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/tick.h @@ -0,0 +1,24 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/tick.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - Timer tick support definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_TICK_H +#define __ASM_ARCH_TICK_H __FILE__ + +static inline u32 s3c24xx_ostimer_pending(void) +{ + u32 pend = __raw_readl(S5P_VA_VIC0 + VIC_RAW_STATUS); + return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0))); +} + +#define TICK_MAX (0xffffffff) + +#endif /* __ASM_ARCH_TICK_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/uncompress.h b/arch/arm/mach-s5p6440/include/mach/uncompress.h new file mode 100644 index 00000000000..7c1f600d65c --- /dev/null +++ b/arch/arm/mach-s5p6440/include/mach/uncompress.h @@ -0,0 +1,24 @@ +/* linux/arch/arm/mach-s5p6440/include/mach/uncompress.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - uncompress code + * + * This program is free software; you can 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_UNCOMPRESS_H +#define __ASM_ARCH_UNCOMPRESS_H + +#include <mach/map.h> +#include <plat/uncompress.h> + +static void arch_detect_cpu(void) +{ + /* we do not need to do any cpu detection here at the moment. */ +} + +#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-s5p6440/mach-smdk6440.c b/arch/arm/mach-s5p6440/mach-smdk6440.c new file mode 100644 index 00000000000..760ea5424a7 --- /dev/null +++ b/arch/arm/mach-s5p6440/mach-smdk6440.c @@ -0,0 +1,111 @@ +/* linux/arch/arm/mach-s5p6440/mach-smdk6440.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/serial_core.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/clk.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/hardware.h> +#include <mach/map.h> + +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <plat/regs-serial.h> + +#include <plat/s5p6440.h> +#include <plat/clock.h> +#include <mach/regs-clock.h> +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/pll.h> + +#define S5P6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ + S3C2410_UCON_RXILEVEL | \ + S3C2410_UCON_TXIRQMODE | \ + S3C2410_UCON_RXIRQMODE | \ + S3C2410_UCON_RXFIFO_TOI | \ + S3C2443_UCON_RXERR_IRQEN) + +#define S5P6440_ULCON_DEFAULT S3C2410_LCON_CS8 + +#define S5P6440_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ + S3C2440_UFCON_TXTRIG16 | \ + S3C2410_UFCON_RXTRIG8) + +static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = S5P6440_UCON_DEFAULT, + .ulcon = S5P6440_ULCON_DEFAULT, + .ufcon = S5P6440_UFCON_DEFAULT, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = S5P6440_UCON_DEFAULT, + .ulcon = S5P6440_ULCON_DEFAULT, + .ufcon = S5P6440_UFCON_DEFAULT, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = S5P6440_UCON_DEFAULT, + .ulcon = S5P6440_ULCON_DEFAULT, + .ufcon = S5P6440_UFCON_DEFAULT, + }, + [3] = { + .hwport = 3, + .flags = 0, + .ucon = S5P6440_UCON_DEFAULT, + .ulcon = S5P6440_ULCON_DEFAULT, + .ufcon = S5P6440_UFCON_DEFAULT, + }, +}; + +static struct platform_device *smdk6440_devices[] __initdata = { +}; + +static void __init smdk6440_map_io(void) +{ + s5p_init_io(NULL, 0, S5P_SYS_ID); + s3c24xx_init_clocks(12000000); + s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs)); +} + +static void __init smdk6440_machine_init(void) +{ + platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices)); +} + +MACHINE_START(SMDK6440, "SMDK6440") + /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ + .phys_io = S5P_PA_UART & 0xfff00000, + .io_pg_offst = (((u32)S5P_VA_UART) >> 18) & 0xfffc, + .boot_params = S5P_PA_SDRAM + 0x100, + + .init_irq = s5p6440_init_irq, + .map_io = smdk6440_map_io, + .init_machine = smdk6440_machine_init, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s5p6440/s5p6440-gpio.c b/arch/arm/mach-s5p6440/s5p6440-gpio.c new file mode 100644 index 00000000000..742264c29f2 --- /dev/null +++ b/arch/arm/mach-s5p6440/s5p6440-gpio.c @@ -0,0 +1,322 @@ +/* arch/arm/mach-s5p6440/s5p6440-gpio.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - GPIOlib support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <mach/map.h> +#include <mach/gpio.h> +#include <mach/regs-gpio.h> +#include <plat/gpio-core.h> +#include <plat/gpio-cfg.h> +#include <plat/gpio-cfg-helpers.h> + +/* GPIO bank summary: +* +* Bank GPIOs Style SlpCon ExtInt Group +* A 6 4Bit Yes 1 +* B 7 4Bit Yes 1 +* C 8 4Bit Yes 2 +* F 2 2Bit Yes 4 [1] +* G 7 4Bit Yes 5 +* H 10 4Bit[2] Yes 6 +* I 16 2Bit Yes None +* J 12 2Bit Yes None +* N 16 2Bit No IRQ_EINT +* P 8 2Bit Yes 8 +* R 15 4Bit[2] Yes 8 +* +* [1] BANKF pins 14,15 do not form part of the external interrupt sources +* [2] BANK has two control registers, GPxCON0 and GPxCON1 +*/ + +static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); + void __iomem *base = ourchip->base; + void __iomem *regcon = base; + unsigned long con; + + switch (offset) { + case 6: + offset += 1; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + regcon -= 4; + break; + default: + offset -= 7; + break; + } + + con = __raw_readl(regcon); + con &= ~(0xf << con_4bit_shift(offset)); + __raw_writel(con, regcon); + + return 0; +} + +static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); + void __iomem *base = ourchip->base; + void __iomem *regcon = base; + unsigned long con; + unsigned long dat; + unsigned con_offset = offset; + + switch (con_offset) { + case 6: + con_offset += 1; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + regcon -= 4; + break; + default: + con_offset -= 7; + break; + } + + con = __raw_readl(regcon); + con &= ~(0xf << con_4bit_shift(con_offset)); + con |= 0x1 << con_4bit_shift(con_offset); + + dat = __raw_readl(base + GPIODAT_OFF); + if (value) + dat |= 1 << offset; + else + dat &= ~(1 << offset); + + __raw_writel(con, regcon); + __raw_writel(dat, base + GPIODAT_OFF); + + return 0; +} + +int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int cfg) +{ + void __iomem *reg = chip->base; + unsigned int shift; + u32 con; + + switch (off) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + shift = (off & 7) * 4; + reg -= 4; + break; + case 6: + shift = ((off + 1) & 7) * 4; + reg -= 4; + default: + shift = ((off + 1) & 7) * 4; + break; + } + + if (s3c_gpio_is_cfg_special(cfg)) { + cfg &= 0xf; + cfg <<= shift; + } + + con = __raw_readl(reg); + con &= ~(0xf << shift); + con |= cfg; + __raw_writel(con, reg); + + return 0; +} + +static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = { + { + .cfg_eint = 0, + }, { + .cfg_eint = 7, + }, { + .cfg_eint = 3, + .set_config = s5p6440_gpio_setcfg_4bit_rbank, + }, { + .cfg_eint = 0, + .set_config = s3c_gpio_setcfg_s3c24xx, + }, { + .cfg_eint = 2, + .set_config = s3c_gpio_setcfg_s3c24xx, + }, { + .cfg_eint = 3, + .set_config = s3c_gpio_setcfg_s3c24xx, + }, +}; + +static struct s3c_gpio_chip s5p6440_gpio_4bit[] = { + { + .base = S5P6440_GPA_BASE, + .config = &s5p6440_gpio_cfgs[1], + .chip = { + .base = S5P6440_GPA(0), + .ngpio = S5P6440_GPIO_A_NR, + .label = "GPA", + }, + }, { + .base = S5P6440_GPB_BASE, + .config = &s5p6440_gpio_cfgs[1], + .chip = { + .base = S5P6440_GPB(0), + .ngpio = S5P6440_GPIO_B_NR, + .label = "GPB", + }, + }, { + .base = S5P6440_GPC_BASE, + .config = &s5p6440_gpio_cfgs[1], + .chip = { + .base = S5P6440_GPC(0), + .ngpio = S5P6440_GPIO_C_NR, + .label = "GPC", + }, + }, { + .base = S5P6440_GPG_BASE, + .config = &s5p6440_gpio_cfgs[1], + .chip = { + .base = S5P6440_GPG(0), + .ngpio = S5P6440_GPIO_G_NR, + .label = "GPG", + }, + }, +}; + +static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = { + { + .base = S5P6440_GPH_BASE + 0x4, + .config = &s5p6440_gpio_cfgs[1], + .chip = { + .base = S5P6440_GPH(0), + .ngpio = S5P6440_GPIO_H_NR, + .label = "GPH", + }, + }, +}; + +static struct s3c_gpio_chip gpio_rbank_4bit2[] = { + { + .base = S5P6440_GPR_BASE + 0x4, + .config = &s5p6440_gpio_cfgs[2], + .chip = { + .base = S5P6440_GPR(0), + .ngpio = S5P6440_GPIO_R_NR, + .label = "GPR", + }, + }, +}; + +static struct s3c_gpio_chip s5p6440_gpio_2bit[] = { + { + .base = S5P6440_GPF_BASE, + .config = &s5p6440_gpio_cfgs[5], + .chip = { + .base = S5P6440_GPF(0), + .ngpio = S5P6440_GPIO_F_NR, + .label = "GPF", + }, + }, { + .base = S5P6440_GPI_BASE, + .config = &s5p6440_gpio_cfgs[3], + .chip = { + .base = S5P6440_GPI(0), + .ngpio = S5P6440_GPIO_I_NR, + .label = "GPI", + }, + }, { + .base = S5P6440_GPJ_BASE, + .config = &s5p6440_gpio_cfgs[3], + .chip = { + .base = S5P6440_GPJ(0), + .ngpio = S5P6440_GPIO_J_NR, + .label = "GPJ", + }, + }, { + .base = S5P6440_GPN_BASE, + .config = &s5p6440_gpio_cfgs[4], + .chip = { + .base = S5P6440_GPN(0), + .ngpio = S5P6440_GPIO_N_NR, + .label = "GPN", + }, + }, { + .base = S5P6440_GPP_BASE, + .config = &s5p6440_gpio_cfgs[5], + .chip = { + .base = S5P6440_GPP(0), + .ngpio = S5P6440_GPIO_P_NR, + .label = "GPP", + }, + }, +}; + +void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips) +{ + for (; nr_chips > 0; nr_chips--, chipcfg++) { + if (!chipcfg->set_config) + chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit; + if (!chipcfg->set_pull) + chipcfg->set_pull = s3c_gpio_setpull_updown; + if (!chipcfg->get_pull) + chipcfg->get_pull = s3c_gpio_getpull_updown; + } +} + +static void __init s5p6440_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip, + int nr_chips) +{ + for (; nr_chips > 0; nr_chips--, chip++) { + chip->chip.direction_input = s5p6440_gpiolib_rbank_4bit2_input; + chip->chip.direction_output = + s5p6440_gpiolib_rbank_4bit2_output; + s3c_gpiolib_add(chip); + } +} + +static int __init s5p6440_gpiolib_init(void) +{ + struct s3c_gpio_chip *chips = s5p6440_gpio_2bit; + int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit); + + s5p6440_gpiolib_set_cfg(s5p6440_gpio_cfgs, + ARRAY_SIZE(s5p6440_gpio_cfgs)); + + for (; nr_chips > 0; nr_chips--, chips++) + s3c_gpiolib_add(chips); + + samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit, + ARRAY_SIZE(s5p6440_gpio_4bit)); + + samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2, + ARRAY_SIZE(s5p6440_gpio_4bit2)); + + s5p6440_gpio_add_rbank_4bit2(gpio_rbank_4bit2, + ARRAY_SIZE(gpio_rbank_4bit2)); + + return 0; +} +arch_initcall(s5p6440_gpiolib_init); diff --git a/arch/arm/mach-s5pc100/include/mach/gpio-core.h b/arch/arm/mach-s5pc100/include/mach/gpio-core.h deleted file mode 100644 index ad28d8ec8a7..00000000000 --- a/arch/arm/mach-s5pc100/include/mach/gpio-core.h +++ /dev/null @@ -1,21 +0,0 @@ -/* arch/arm/mach-s5pc100/include/mach/gpio-core.h - * - * Copyright 2009 Samsung Electronics Co. - * Byungho Min <bhmin@samsung.com> - * - * S5PC100 - GPIO core support - * - * Based on mach-s3c6400/include/mach/gpio-core.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_GPIO_CORE_H -#define __ASM_ARCH_GPIO_CORE_H __FILE__ - -/* currently we just include the platform support */ -#include <plat/gpio-core.h> - -#endif /* __ASM_ARCH_GPIO_CORE_H */ diff --git a/arch/arm/mach-s5pc100/include/mach/tick.h b/arch/arm/mach-s5pc100/include/mach/tick.h index d3de0f3591a..f338c9eec71 100644 --- a/arch/arm/mach-s5pc100/include/mach/tick.h +++ b/arch/arm/mach-s5pc100/include/mach/tick.h @@ -21,7 +21,7 @@ static inline u32 s3c24xx_ostimer_pending(void) { u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS); - return pend & 1 << (IRQ_TIMER4 - S5PC1XX_IRQ_VIC0(0)); + return pend & 1 << (IRQ_TIMER4_VIC - S5PC1XX_IRQ_VIC0(0)); } #define TICK_MAX (0xffffffff) diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h index 94064006685..ce228bdc66d 100644 --- a/arch/arm/mach-w90x900/include/mach/system.h +++ b/arch/arm/mach-w90x900/include/mach/system.h @@ -15,7 +15,15 @@ * */ +#include <linux/io.h> #include <asm/proc-fns.h> +#include <mach/map.h> +#include <mach/regs-timer.h> + +#define WTCR (TMR_BA + 0x1C) +#define WTCLK (1 << 10) +#define WTE (1 << 7) +#define WTRE (1 << 1) static void arch_idle(void) { @@ -23,6 +31,11 @@ static void arch_idle(void) static void arch_reset(char mode, const char *cmd) { - cpu_reset(0); + if (mode == 's') { + /* Jump into ROM at address 0 */ + cpu_reset(0); + } else { + __raw_writel(WTE | WTRE | WTCLK, WTCR); + } } diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c index 4128af870b4..b80f769bc13 100644 --- a/arch/arm/mach-w90x900/time.c +++ b/arch/arm/mach-w90x900/time.c @@ -42,7 +42,10 @@ #define TICKS_PER_SEC 100 #define PRESCALE 0x63 /* Divider = prescale + 1 */ -unsigned int timer0_load; +#define TDR_SHIFT 24 +#define TDR_MASK ((1 << TDR_SHIFT) - 1) + +static unsigned int timer0_load; static void nuc900_clockevent_setmode(enum clock_event_mode mode, struct clock_event_device *clk) @@ -88,7 +91,7 @@ static int nuc900_clockevent_setnextevent(unsigned long evt, static struct clock_event_device nuc900_clockevent_device = { .name = "nuc900-timer0", .shift = 32, - .features = CLOCK_EVT_MODE_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_mode = nuc900_clockevent_setmode, .set_next_event = nuc900_clockevent_setnextevent, .rating = 300, @@ -112,8 +115,23 @@ static struct irqaction nuc900_timer0_irq = { .handler = nuc900_timer0_interrupt, }; -static void __init nuc900_clockevents_init(unsigned int rate) +static void __init nuc900_clockevents_init(void) { + unsigned int rate; + struct clk *clk = clk_get(NULL, "timer0"); + + BUG_ON(IS_ERR(clk)); + + __raw_writel(0x00, REG_TCSR0); + + clk_enable(clk); + rate = clk_get_rate(clk) / (PRESCALE + 1); + + timer0_load = (rate / TICKS_PER_SEC); + + __raw_writel(RESETINT, REG_TISR); + setup_irq(IRQ_TIMER0, &nuc900_timer0_irq); + nuc900_clockevent_device.mult = div_sc(rate, NSEC_PER_SEC, nuc900_clockevent_device.shift); nuc900_clockevent_device.max_delta_ns = clockevent_delta2ns(0xffffffff, @@ -127,26 +145,35 @@ static void __init nuc900_clockevents_init(unsigned int rate) static cycle_t nuc900_get_cycles(struct clocksource *cs) { - return ~__raw_readl(REG_TDR1); + return (~__raw_readl(REG_TDR1)) & TDR_MASK; } static struct clocksource clocksource_nuc900 = { .name = "nuc900-timer1", .rating = 200, .read = nuc900_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, + .mask = CLOCKSOURCE_MASK(TDR_SHIFT), + .shift = 10, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init nuc900_clocksource_init(unsigned int rate) +static void __init nuc900_clocksource_init(void) { unsigned int val; + unsigned int rate; + struct clk *clk = clk_get(NULL, "timer1"); + + BUG_ON(IS_ERR(clk)); + + __raw_writel(0x00, REG_TCSR1); + + clk_enable(clk); + rate = clk_get_rate(clk) / (PRESCALE + 1); __raw_writel(0xffffffff, REG_TICR1); val = __raw_readl(REG_TCSR1); - val |= (COUNTEN | PERIOD); + val |= (COUNTEN | PERIOD | PRESCALE); __raw_writel(val, REG_TCSR1); clocksource_nuc900.mult = @@ -156,25 +183,8 @@ static void __init nuc900_clocksource_init(unsigned int rate) static void __init nuc900_timer_init(void) { - struct clk *ck_ext = clk_get(NULL, "ext"); - unsigned int rate; - - BUG_ON(IS_ERR(ck_ext)); - - rate = clk_get_rate(ck_ext); - clk_put(ck_ext); - rate = rate / (PRESCALE + 0x01); - - /* set a known state */ - __raw_writel(0x00, REG_TCSR0); - __raw_writel(0x00, REG_TCSR1); - __raw_writel(RESETINT, REG_TISR); - timer0_load = (rate / TICKS_PER_SEC); - - setup_irq(IRQ_TIMER0, &nuc900_timer0_irq); - - nuc900_clocksource_init(rate); - nuc900_clockevents_init(rate); + nuc900_clocksource_init(); + nuc900_clockevents_init(); } struct sys_timer nuc900_timer = { diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 827e238e5d4..e8d34a80851 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -27,6 +27,9 @@ obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o +AFLAGS_abort-ev6.o :=-Wa,-march=armv6k +AFLAGS_abort-ev7.o :=-Wa,-march=armv7-a + obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o @@ -39,6 +42,9 @@ obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o +AFLAGS_cache-v6.o :=-Wa,-march=armv6 +AFLAGS_cache-v7.o :=-Wa,-march=armv7-a + obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o @@ -58,6 +64,9 @@ obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o +AFLAGS_tlb-v6.o :=-Wa,-march=armv6 +AFLAGS_tlb-v7.o :=-Wa,-march=armv7-a + obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o @@ -84,6 +93,9 @@ obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o obj-$(CONFIG_CPU_V6) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o +AFLAGS_proc-v6.o :=-Wa,-march=armv6 +AFLAGS_proc-v7.o :=-Wa,-march=armv7-a + obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c index 5d180cb0bd9..c3154928bcc 100644 --- a/arch/arm/mm/cache-xsc3l2.c +++ b/arch/arm/mm/cache-xsc3l2.c @@ -221,15 +221,14 @@ static int __init xsc3_l2_init(void) if (!cpu_is_xsc3() || !xsc3_l2_present()) return 0; - if (!(get_cr() & CR_L2)) { + if (get_cr() & CR_L2) { pr_info("XScale3 L2 cache enabled.\n"); - adjust_cr(CR_L2, CR_L2); xsc3_l2_inv_all(); - } - outer_cache.inv_range = xsc3_l2_inv_range; - outer_cache.clean_range = xsc3_l2_clean_range; - outer_cache.flush_range = xsc3_l2_flush_range; + outer_cache.inv_range = xsc3_l2_inv_range; + outer_cache.clean_range = xsc3_l2_clean_range; + outer_cache.flush_range = xsc3_l2_flush_range; + } return 0; } diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 52c40d15567..a04ffbbbe25 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -616,7 +616,7 @@ void __init mem_init(void) "%dK data, %dK init, %luK highmem)\n", nr_free_pages() << (PAGE_SHIFT-10), codesize >> 10, datasize >> 10, initsize >> 10, - (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); + totalhigh_pages << (PAGE_SHIFT-10)); if (PAGE_SIZE >= 16384 && num_physpages <= 128) { extern int sysctl_overcommit_memory; diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 96456f54879..8e4f6dca899 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -407,6 +407,13 @@ __xsc3_setup: adr r5, xsc3_crval ldmia r5, {r5, r6} + +#ifdef CONFIG_CACHE_XSC3L2 + mrc p15, 1, r0, c0, c0, 1 @ get L2 present information + ands r0, r0, #0xf8 + orrne r6, r6, #(1 << 26) @ enable L2 if present +#endif + mrc p15, 0, r0, c1, c0, 0 @ get control register bic r0, r0, r5 @ ..V. ..R. .... ..A. orr r0, r0, r6 @ ..VI Z..S .... .C.M (mmu) diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index a26a605b73b..0cb1848bd87 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S @@ -40,7 +40,6 @@ ENTRY(v7wbi_flush_user_tlb_range) asid r3, r3 @ mask ASID orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA mov r1, r1, lsl #PAGE_SHIFT - vma_vm_flags r2, r2 @ get vma->vm_flags 1: #ifdef CONFIG_SMP mcr p15, 0, r0, c8, c3, 1 @ TLB invalidate U MVA (shareable) diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h index 810c47f56e7..9af494f0ab3 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h @@ -58,19 +58,19 @@ #define MX25_PAD_A18__A18 IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A18__GPIO_2_4 IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A18__FEC_COL IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTL) +#define MX25_PAD_A18__FEC_COL IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTRL) #define MX25_PAD_A19__A19 IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTL) +#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTRL) #define MX25_PAD_A19__GPIO_2_5 IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A20__A20 IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A20__GPIO_2_6 IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTL) +#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTRL) #define MX25_PAD_A21__A21 IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A21__GPIO_2_7 IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTL) +#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTRL) #define MX25_PAD_A22__A22 IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A22__GPIO_2_8 IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL) @@ -80,11 +80,11 @@ #define MX25_PAD_A24__A24 IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A24__GPIO_2_10 IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTL) +#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTRL) #define MX25_PAD_A25__A25 IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_A25__GPIO_2_11 IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTL) +#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTRL) #define MX25_PAD_EB0__EB0 IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_EB0__AUD4_TXD IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL) @@ -112,7 +112,7 @@ #define MX25_PAD_CS5__UART5_RTS IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL) #define MX25_PAD_CS5__GPIO_3_21 IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_NF_CE0__GPIO_3_22 IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_ECB__ECB IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL) @@ -229,28 +229,28 @@ #define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_LD8__LD8 IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTL) +#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_LD9__LD9 IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTL) +#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTRL) #define MX25_PAD_LD10__LD10 IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTL) +#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTRL) #define MX25_PAD_LD11__LD11 IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTL) +#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTRL) #define MX25_PAD_LD12__LD12 IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTL) +#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTRL) #define MX25_PAD_LD13__LD13 IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTL) +#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_LD14__LD14 IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTL) +#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_LD15__LD15 IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTL) +#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTRL) #define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_HSYNC__GPIO_1_22 IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL) @@ -265,7 +265,7 @@ #define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTL) +#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTRL) #define MX25_PAD_PWM__PWM IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_PWM__GPIO_1_26 IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL) @@ -354,19 +354,19 @@ #define MX25_PAD_UART2_TXD__GPIO_4_27 IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTL) +#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTRL) #define MX25_PAD_UART2_RTS__GPIO_4_28 IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTL) +#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTRL) #define MX25_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_UART2_CTS__GPIO_4_29 IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) -#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTL) +#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_CMD__GPIO_2_23 IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) -#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTL) +#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_CLK__GPIO_2_24 IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) @@ -377,11 +377,11 @@ #define MX25_PAD_SD1_DATA1__GPIO_2_26 IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) -#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTL) +#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA2__GPIO_2_27 IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) -#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTL) +#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL) #define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL) #define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE) @@ -410,7 +410,7 @@ #define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) #define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL) #define MX25_PAD_FEC_MDC__GPIO_3_5 IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL) @@ -418,23 +418,23 @@ #define MX25_PAD_FEC_MDIO__AUD4_RXD IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL) #define MX25_PAD_FEC_MDIO__GPIO_3_6 IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_TDATA0__GPIO_3_7 IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_TDATA1__AUD4_TXFS IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL) #define MX25_PAD_FEC_TDATA1__GPIO_3_8 IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTL) +#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTRL) #define MX25_PAD_FEC_TX_EN__GPIO_3_9 IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) +#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL) #define MX25_PAD_FEC_RDATA0__GPIO_3_10 IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) +#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL) #define MX25_PAD_FEC_RDATA1__GPIO_3_11 IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) +#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL) #define MX25_PAD_FEC_RX_DV__CAN2_RX IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP) #define MX25_PAD_FEC_RX_DV__GPIO_3_12 IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL) diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h index 91e73814480..854e2dc5848 100644 --- a/arch/arm/plat-mxc/include/mach/mx25.h +++ b/arch/arm/plat-mxc/include/mach/mx25.h @@ -41,4 +41,8 @@ #define UART1_BASE_ADDR 0x43f90000 #define UART2_BASE_ADDR 0x43f94000 +#define MX25_FEC_BASE_ADDR 0x50038000 + +#define MX25_INT_FEC 57 + #endif /* __MACH_MX25_H__ */ diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 89cafc93724..d9f8c844c38 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -36,10 +36,6 @@ static struct clk_functions *arch_clock; * Standard clock functions defined in include/linux/clk.h *-------------------------------------------------------------------------*/ -/* This functions is moved to arch/arm/common/clkdev.c. For OMAP4 since - * clock framework is not up , it is defined here to avoid rework in - * every driver. Also dummy prcm reset function is added */ - int clk_enable(struct clk *clk) { unsigned long flags; @@ -305,7 +301,6 @@ void clk_enable_init_clocks(void) clk_enable(clkp); } } -EXPORT_SYMBOL(clk_enable_init_clocks); /* * Low level helpers @@ -334,7 +329,16 @@ void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) arch_clock->clk_init_cpufreq_table(table); spin_unlock_irqrestore(&clockfw_lock, flags); } -EXPORT_SYMBOL(clk_init_cpufreq_table); + +void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) +{ + unsigned long flags; + + spin_lock_irqsave(&clockfw_lock, flags); + if (arch_clock->clk_exit_cpufreq_table) + arch_clock->clk_exit_cpufreq_table(table); + spin_unlock_irqrestore(&clockfw_lock, flags); +} #endif /*-------------------------------------------------------------------------*/ diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index f8ddbdd8b07..6d3d3336005 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c @@ -134,6 +134,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) static int omap_cpu_exit(struct cpufreq_policy *policy) { + clk_exit_cpufreq_table(&freq_table); clk_put(mpu_clk); return 0; } diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 04846811d0a..d17620c50c2 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -192,6 +192,7 @@ struct gpio_bank { u32 saved_risingdetect; #endif u32 level_mask; + u32 toggle_mask; spinlock_t lock; struct gpio_chip chip; struct clk *dbck; @@ -749,6 +750,44 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, } #endif +/* + * This only applies to chips that can't do both rising and falling edge + * detection at once. For all other chips, this function is a noop. + */ +static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) +{ + void __iomem *reg = bank->base; + u32 l = 0; + + switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 + case METHOD_MPUIO: + reg += OMAP_MPUIO_GPIO_INT_EDGE; + break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_INT_CONTROL; + break; +#endif +#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) + case METHOD_GPIO_7XX: + reg += OMAP7XX_GPIO_INT_CONTROL; + break; +#endif + default: + return; + } + + l = __raw_readl(reg); + if ((l >> gpio) & 1) + l &= ~(1 << gpio); + else + l |= 1 << gpio; + + __raw_writel(l, reg); +} + static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) { void __iomem *reg = bank->base; @@ -759,6 +798,8 @@ 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 & IRQ_TYPE_EDGE_BOTH) + bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; else if (trigger & IRQ_TYPE_EDGE_FALLING) @@ -771,6 +812,8 @@ 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 & IRQ_TYPE_EDGE_BOTH) + bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; else if (trigger & IRQ_TYPE_EDGE_FALLING) @@ -803,6 +846,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) case METHOD_GPIO_7XX: reg += OMAP7XX_GPIO_INT_CONTROL; l = __raw_readl(reg); + if (trigger & IRQ_TYPE_EDGE_BOTH) + bank->toggle_mask |= 1 << gpio; if (trigger & IRQ_TYPE_EDGE_RISING) l |= 1 << gpio; else if (trigger & IRQ_TYPE_EDGE_FALLING) @@ -1072,7 +1117,7 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena */ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) { - unsigned long flags; + unsigned long uninitialized_var(flags); switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX @@ -1217,7 +1262,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *isr_reg = NULL; u32 isr; - unsigned int gpio_irq; + unsigned int gpio_irq, gpio_index; struct gpio_bank *bank; u32 retrigger = 0; int unmasked = 0; @@ -1284,9 +1329,23 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) gpio_irq = bank->virtual_irq_start; for (; isr != 0; isr >>= 1, gpio_irq++) { + gpio_index = get_gpio_index(irq_to_gpio(gpio_irq)); + if (!(isr & 1)) continue; +#ifdef CONFIG_ARCH_OMAP1 + /* + * Some chips can't respond to both rising and falling + * at the same time. If this irq was requested with + * both flags, we need to flip the ICR data for the IRQ + * to respond to the IRQ for the opposite direction. + * This will be indicated in the bank toggle_mask. + */ + if (bank->toggle_mask & (1 << gpio_index)) + _toggle_gpio_edge_triggering(bank, gpio_index); +#endif + generic_handle_irq(gpio_irq); } } diff --git a/arch/arm/plat-omap/include/plat/board.h b/arch/arm/plat-omap/include/plat/board.h index 376ce18216f..5cd622039da 100644 --- a/arch/arm/plat-omap/include/plat/board.h +++ b/arch/arm/plat-omap/include/plat/board.h @@ -99,7 +99,6 @@ struct fb_info; struct omap_backlight_config { int default_intensity; int (*set_power)(struct device *dev, int state); - int (*check_fb)(struct fb_info *fb); }; struct omap_fbmem_config { diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index 309b6d1dccd..94fe2a0ce40 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -119,6 +119,7 @@ struct clk_functions { void (*clk_disable_unused)(struct clk *clk); #ifdef CONFIG_CPU_FREQ void (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **); + void (*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **); #endif }; @@ -135,6 +136,7 @@ extern unsigned long followparent_recalc(struct clk *clk); extern void clk_enable_init_clocks(void); #ifdef CONFIG_CPU_FREQ extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); +extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); #endif extern const struct clkops clkops_null; diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h index 2ae88437863..a745d62fad0 100644 --- a/arch/arm/plat-omap/include/plat/control.h +++ b/arch/arm/plat-omap/include/plat/control.h @@ -147,7 +147,7 @@ #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) #define OMAP343X_CONTROL_DEBOBS(i) (OMAP2_CONTROL_GENERAL + 0x01B0 \ - + ((i) >> 1) * 4 + (!(i) & 1) * 2) + + ((i) >> 1) * 4 + (!((i) & 1)) * 2) #define OMAP343X_CONTROL_PROG_IO0 (OMAP2_CONTROL_GENERAL + 0x01D4) #define OMAP343X_CONTROL_PROG_IO1 (OMAP2_CONTROL_GENERAL + 0x01D8) #define OMAP343X_CONTROL_DSS_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E0) diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index 7e5319f907d..a3e7b471bcb 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -122,16 +122,21 @@ #define OMAP243X_SMS_VIRT (OMAP243X_SMS_PHYS + OMAP2_L3_IO_OFFSET) #define OMAP243X_SMS_SIZE SZ_1M -/* DSP */ -#define DSP_MEM_24XX_PHYS OMAP2420_DSP_MEM_BASE /* 0x58000000 */ -#define DSP_MEM_24XX_VIRT 0xe0000000 -#define DSP_MEM_24XX_SIZE 0x28000 -#define DSP_IPI_24XX_PHYS OMAP2420_DSP_IPI_BASE /* 0x59000000 */ -#define DSP_IPI_24XX_VIRT 0xe1000000 -#define DSP_IPI_24XX_SIZE SZ_4K -#define DSP_MMU_24XX_PHYS OMAP2420_DSP_MMU_BASE /* 0x5a000000 */ -#define DSP_MMU_24XX_VIRT 0xe2000000 -#define DSP_MMU_24XX_SIZE SZ_4K +/* 2420 IVA */ +#define DSP_MEM_2420_PHYS OMAP2420_DSP_MEM_BASE + /* 0x58000000 --> 0xfc100000 */ +#define DSP_MEM_2420_VIRT 0xfc100000 +#define DSP_MEM_2420_SIZE 0x28000 +#define DSP_IPI_2420_PHYS OMAP2420_DSP_IPI_BASE + /* 0x59000000 --> 0xfc128000 */ +#define DSP_IPI_2420_VIRT 0xfc128000 +#define DSP_IPI_2420_SIZE SZ_4K +#define DSP_MMU_2420_PHYS OMAP2420_DSP_MMU_BASE + /* 0x5a000000 --> 0xfc129000 */ +#define DSP_MMU_2420_VIRT 0xfc129000 +#define DSP_MMU_2420_SIZE SZ_4K + +/* 2430 IVA2.1 - currently unmapped */ /* * ---------------------------------------------------------------------------- @@ -182,16 +187,7 @@ #define OMAP343X_SDRC_VIRT (OMAP343X_SDRC_PHYS + OMAP2_L3_IO_OFFSET) #define OMAP343X_SDRC_SIZE SZ_1M -/* DSP */ -#define DSP_MEM_34XX_PHYS OMAP34XX_DSP_MEM_BASE /* 0x58000000 */ -#define DSP_MEM_34XX_VIRT 0xe0000000 -#define DSP_MEM_34XX_SIZE 0x28000 -#define DSP_IPI_34XX_PHYS OMAP34XX_DSP_IPI_BASE /* 0x59000000 */ -#define DSP_IPI_34XX_VIRT 0xe1000000 -#define DSP_IPI_34XX_SIZE SZ_4K -#define DSP_MMU_34XX_PHYS OMAP34XX_DSP_MMU_BASE /* 0x5a000000 */ -#define DSP_MMU_34XX_VIRT 0xe2000000 -#define DSP_MMU_34XX_SIZE SZ_4K +/* 3430 IVA - currently unmapped */ /* * ---------------------------------------------------------------------------- diff --git a/arch/arm/plat-omap/include/plat/mux.h b/arch/arm/plat-omap/include/plat/mux.h index 8f069cc8035..692c90e89ac 100644 --- a/arch/arm/plat-omap/include/plat/mux.h +++ b/arch/arm/plat-omap/include/plat/mux.h @@ -183,6 +183,14 @@ enum omap7xx_index { /* I2C */ I2C_7XX_SCL, I2C_7XX_SDA, + + /* SPI */ + SPI_7XX_1, + SPI_7XX_2, + SPI_7XX_3, + SPI_7XX_4, + SPI_7XX_5, + SPI_7XX_6, }; enum omap1xxx_index { diff --git a/arch/arm/plat-omap/include/plat/omap7xx.h b/arch/arm/plat-omap/include/plat/omap7xx.h index 53f52414b0e..48e4757e1e3 100644 --- a/arch/arm/plat-omap/include/plat/omap7xx.h +++ b/arch/arm/plat-omap/include/plat/omap7xx.h @@ -46,6 +46,9 @@ #define OMAP7XX_DSPREG_SIZE SZ_128K #define OMAP7XX_DSPREG_START 0xE1000000 +#define OMAP7XX_SPI1_BASE 0xfffc0800 +#define OMAP7XX_SPI2_BASE 0xfffc1000 + /* * ---------------------------------------------------------------------------- * OMAP7XX specific configuration registers diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c index 11f5d7961c7..0cfd54f519c 100644 --- a/arch/arm/plat-omap/io.c +++ b/arch/arm/plat-omap/io.c @@ -66,12 +66,12 @@ void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type) return XLATE(p, L4_24XX_PHYS, L4_24XX_VIRT); } if (cpu_is_omap2420()) { - if (BETWEEN(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_SIZE)) - return XLATE(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_VIRT); - if (BETWEEN(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE)) - return XLATE(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE); - if (BETWEEN(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_SIZE)) - return XLATE(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_VIRT); + if (BETWEEN(p, DSP_MEM_2420_PHYS, DSP_MEM_2420_SIZE)) + return XLATE(p, DSP_MEM_2420_PHYS, DSP_MEM_2420_VIRT); + if (BETWEEN(p, DSP_IPI_2420_PHYS, DSP_IPI_2420_SIZE)) + return XLATE(p, DSP_IPI_2420_PHYS, DSP_IPI_2420_SIZE); + if (BETWEEN(p, DSP_MMU_2420_PHYS, DSP_MMU_2420_SIZE)) + return XLATE(p, DSP_MMU_2420_PHYS, DSP_MMU_2420_VIRT); } if (cpu_is_omap2430()) { if (BETWEEN(p, L4_WK_243X_PHYS, L4_WK_243X_SIZE)) diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index c0ff1e39d89..463d6386aff 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -827,7 +827,7 @@ EXPORT_SYMBOL_GPL(iommu_get); **/ void iommu_put(struct iommu *obj) { - if (!obj && IS_ERR(obj)) + if (!obj || IS_ERR(obj)) return; mutex_lock(&obj->iommu_lock); diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 2cc1cc328ba..f75767278fc 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -436,7 +436,7 @@ int omap_mcbsp_request(unsigned int id) dev_err(mcbsp->dev, "Unable to request TX IRQ %d " "for McBSP%d\n", mcbsp->tx_irq, mcbsp->id); - return err; + goto error; } init_completion(&mcbsp->rx_irq_completion); @@ -446,12 +446,26 @@ int omap_mcbsp_request(unsigned int id) dev_err(mcbsp->dev, "Unable to request RX IRQ %d " "for McBSP%d\n", mcbsp->rx_irq, mcbsp->id); - free_irq(mcbsp->tx_irq, (void *)mcbsp); - return err; + goto tx_irq; } } return 0; +tx_irq: + free_irq(mcbsp->tx_irq, (void *)mcbsp); +error: + if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) + mcbsp->pdata->ops->free(id); + + /* Do procedure specific to omap34xx arch, if applicable */ + omap34xx_mcbsp_free(mcbsp); + + clk_disable(mcbsp->fclk); + clk_disable(mcbsp->iclk); + + mcbsp->free = 1; + + return err; } EXPORT_SYMBOL(omap_mcbsp_request); diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c index a9eabdcfa16..51dc5c8106c 100644 --- a/arch/arm/plat-pxa/pwm.c +++ b/arch/arm/plat-pxa/pwm.c @@ -204,14 +204,14 @@ static int __devinit pwm_probe(struct platform_device *pdev) goto err_free_clk; } - r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); + r = request_mem_region(r->start, resource_size(r), pdev->name); if (r == NULL) { dev_err(&pdev->dev, "failed to request memory resource\n"); ret = -EBUSY; goto err_free_clk; } - pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); + pwm->mmio_base = ioremap(r->start, resource_size(r)); if (pwm->mmio_base == NULL) { dev_err(&pdev->dev, "failed to ioremap() registers\n"); ret = -ENODEV; @@ -241,7 +241,7 @@ static int __devinit pwm_probe(struct platform_device *pdev) return 0; err_free_mem: - release_mem_region(r->start, r->end - r->start + 1); + release_mem_region(r->start, resource_size(r)); err_free_clk: clk_put(pwm->clk); err_free: @@ -271,7 +271,7 @@ static int __devexit pwm_remove(struct platform_device *pdev) iounmap(pwm->mmio_base); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, r->end - r->start + 1); + release_mem_region(r->start, resource_size(r)); clk_put(pwm->clk); kfree(pwm); diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 9e9d0286e48..2367908c4f6 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -59,50 +59,6 @@ config S3C_BOOT_UART_FORCE_FIFO Say Y here to force the UART FIFOs on during the kernel uncompressor -comment "Power management" - -config S3C2410_PM_DEBUG - bool "S3C2410 PM Suspend debug" - depends on PM - help - Say Y here if you want verbose debugging from the PM Suspend and - Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> - for more information. - -config S3C_PM_DEBUG_LED_SMDK - bool "SMDK LED suspend/resume debugging" - depends on PM && (MACH_SMDK6410) - help - Say Y here to enable the use of the SMDK LEDs on the baseboard - for debugging of the state of the suspend and resume process. - - Note, this currently only works for S3C64XX based SMDK boards. - -config S3C2410_PM_CHECK - bool "S3C2410 PM Suspend Memory CRC" - depends on PM && CRC32 - help - Enable the PM code's memory area checksum over sleep. This option - will generate CRCs of all blocks of memory, and store them before - going to sleep. The blocks are then checked on resume for any - errors. - - Note, this can take several seconds depending on memory size - and CPU speed. - - See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> - -config S3C2410_PM_CHECK_CHUNKSIZE - int "S3C2410 PM Suspend CRC Chunksize (KiB)" - depends on PM && S3C2410_PM_CHECK - default 64 - help - Set the chunksize in Kilobytes of the CRC for checking memory - corruption over suspend and resume. A smaller value will mean that - the CRC data block will take more memory, but wil identify any - faults with better precision. - - See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> config S3C_LOWLEVEL_UART_PORT int "S3C UART to use for low-level messages" @@ -130,39 +86,6 @@ config S3C_GPIO_TRACK Internal configuration option to enable the s3c specific gpio chip tracking if the platform requires it. -config S3C_GPIO_PULL_UPDOWN - bool - help - Internal configuration to enable the correct GPIO pull helper - -config S3C_GPIO_PULL_DOWN - bool - help - Internal configuration to enable the correct GPIO pull helper - -config S3C_GPIO_PULL_UP - bool - help - Internal configuration to enable the correct GPIO pull helper - -config S3C_GPIO_CFG_S3C24XX - bool - help - Internal configuration to enable S3C24XX style GPIO configuration - functions. - -config S3C_GPIO_CFG_S3C64XX - bool - help - Internal configuration to enable S3C64XX style GPIO configuration - functions. - -config S5P_GPIO_CFG_S5PC1XX - bool - help - Internal configuration to enable S5PC1XX style GPIO configuration - functions. - # DMA config S3C_DMA @@ -170,46 +93,4 @@ config S3C_DMA help Internal configuration for S3C DMA core -# device definitions to compile in - -config S3C_DEV_HSMMC - bool - help - Compile in platform device definitions for HSMMC code - -config S3C_DEV_HSMMC1 - bool - help - Compile in platform device definitions for HSMMC channel 1 - -config S3C_DEV_HSMMC2 - bool - help - Compile in platform device definitions for HSMMC channel 2 - -config S3C_DEV_I2C1 - bool - help - Compile in platform device definitions for I2C channel 1 - -config S3C_DEV_FB - bool - help - Compile in platform device definition for framebuffer - -config S3C_DEV_USB_HOST - bool - help - Compile in platform device definition for USB host. - -config S3C_DEV_USB_HSOTG - bool - help - Compile in platform device definition for USB high-speed OtG - -config S3C_DEV_NAND - bool - help - Compile in platform device definition for NAND controller - endif diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index 50444da9842..89dbdb0adeb 100644 --- a/arch/arm/plat-s3c/Makefile +++ b/arch/arm/plat-s3c/Makefile @@ -11,12 +11,8 @@ obj- := # Core support for all Samsung SoCs -obj-y += init.o +obj-y += init.o obj-y += time.o -obj-y += clock.o -obj-y += pwm-clock.o -obj-y += gpio.o -obj-y += gpio-config.o # DMA support @@ -25,21 +21,3 @@ obj-$(CONFIG_S3C_DMA) += dma.o # PM support obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += pm-gpio.o -obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o - -# PWM support - -obj-$(CONFIG_HAVE_PWM) += pwm.o - -# devices - -obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o -obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o -obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o -obj-y += dev-i2c0.o -obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o -obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o -obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o -obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o -obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h index d1131ca11e9..676db946567 100644 --- a/arch/arm/plat-s3c/include/plat/cpu.h +++ b/arch/arm/plat-s3c/include/plat/cpu.h @@ -48,9 +48,12 @@ extern void s3c_init_cpu(unsigned long idcode, extern void s3c24xx_init_irq(void); extern void s3c64xx_init_irq(u32 vic0, u32 vic1); +extern void s5p_init_irq(u32 *vic, u32 num_vic); extern void s3c24xx_init_io(struct map_desc *mach_desc, int size); extern void s3c64xx_init_io(struct map_desc *mach_desc, int size); +extern void s5p_init_io(struct map_desc *mach_desc, + int size, void __iomem *cpuid_addr); extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no); diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h index c1c20b02391..c6f9b731049 100644 --- a/arch/arm/plat-s3c/include/plat/devs.h +++ b/arch/arm/plat-s3c/include/plat/devs.h @@ -18,6 +18,7 @@ struct s3c24xx_uart_resources { extern struct s3c24xx_uart_resources s3c2410_uart_resources[]; extern struct s3c24xx_uart_resources s3c64xx_uart_resources[]; +extern struct s3c24xx_uart_resources s5p_uart_resources[]; extern struct platform_device *s3c24xx_uart_devs[]; extern struct platform_device *s3c24xx_uart_src[]; @@ -28,12 +29,15 @@ extern struct platform_device s3c64xx_device_iis0; extern struct platform_device s3c64xx_device_iis1; extern struct platform_device s3c64xx_device_iisv4; +extern struct platform_device s3c64xx_device_spi0; +extern struct platform_device s3c64xx_device_spi1; + extern struct platform_device s3c64xx_device_pcm0; extern struct platform_device s3c64xx_device_pcm1; extern struct platform_device s3c_device_ts; extern struct platform_device s3c_device_fb; -extern struct platform_device s3c_device_usb; +extern struct platform_device s3c_device_ohci; extern struct platform_device s3c_device_lcd; extern struct platform_device s3c_device_wdt; extern struct platform_device s3c_device_i2c0; diff --git a/arch/arm/plat-s3c/include/plat/pm.h b/arch/arm/plat-s3c/include/plat/pm.h index 7a797192fcf..2543bd227f2 100644 --- a/arch/arm/plat-s3c/include/plat/pm.h +++ b/arch/arm/plat-s3c/include/plat/pm.h @@ -111,7 +111,7 @@ extern int s3c24xx_irq_resume(struct sys_device *dev); /* PM debug functions */ -#ifdef CONFIG_S3C2410_PM_DEBUG +#ifdef CONFIG_SAMSUNG_PM_DEBUG /** * s3c_pm_dbg() - low level debug function for use in suspend/resume. * @msg: The message to print. @@ -141,7 +141,7 @@ static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { } /* suspend memory checking */ -#ifdef CONFIG_S3C2410_PM_CHECK +#ifdef CONFIG_SAMSUNG_PM_CHECK extern void s3c_pm_check_prepare(void); extern void s3c_pm_check_restore(void); extern void s3c_pm_check_cleanup(void); diff --git a/arch/arm/plat-s3c/include/plat/regs-serial.h b/arch/arm/plat-s3c/include/plat/regs-serial.h index 85d8904e7f2..60d6604185e 100644 --- a/arch/arm/plat-s3c/include/plat/regs-serial.h +++ b/arch/arm/plat-s3c/include/plat/regs-serial.h @@ -194,6 +194,36 @@ #define S3C64XX_UINTSP 0x34 #define S3C64XX_UINTM 0x38 +/* Following are specific to S5PV210 and S5P6442 */ +#define S5PV210_UCON_CLKMASK (1<<10) +#define S5PV210_UCON_PCLK (0<<10) +#define S5PV210_UCON_UCLK (1<<10) + +#define S5PV210_UFCON_TXTRIG0 (0<<8) +#define S5PV210_UFCON_TXTRIG4 (1<<8) +#define S5PV210_UFCON_TXTRIG8 (2<<8) +#define S5PV210_UFCON_TXTRIG16 (3<<8) +#define S5PV210_UFCON_TXTRIG32 (4<<8) +#define S5PV210_UFCON_TXTRIG64 (5<<8) +#define S5PV210_UFCON_TXTRIG128 (6<<8) +#define S5PV210_UFCON_TXTRIG256 (7<<8) + +#define S5PV210_UFCON_RXTRIG1 (0<<4) +#define S5PV210_UFCON_RXTRIG4 (1<<4) +#define S5PV210_UFCON_RXTRIG8 (2<<4) +#define S5PV210_UFCON_RXTRIG16 (3<<4) +#define S5PV210_UFCON_RXTRIG32 (4<<4) +#define S5PV210_UFCON_RXTRIG64 (5<<4) +#define S5PV210_UFCON_RXTRIG128 (6<<4) +#define S5PV210_UFCON_RXTRIG256 (7<<4) + +#define S5PV210_UFSTAT_TXFULL (1<<24) +#define S5PV210_UFSTAT_RXFULL (1<<8) +#define S5PV210_UFSTAT_TXMASK (255<<16) +#define S5PV210_UFSTAT_TXSHIFT (16) +#define S5PV210_UFSTAT_RXMASK (255<<0) +#define S5PV210_UFSTAT_RXSHIFT (0) + #ifndef __ASSEMBLY__ /* struct s3c24xx_uart_clksrc diff --git a/arch/arm/plat-s3c/include/plat/usb-control.h b/arch/arm/plat-s3c/include/plat/usb-control.h index 822c87fe948..a6a57bf796b 100644 --- a/arch/arm/plat-s3c/include/plat/usb-control.h +++ b/arch/arm/plat-s3c/include/plat/usb-control.h @@ -38,4 +38,6 @@ static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int port } } +extern void s3c_ohci_set_platdata(struct s3c2410_hcd_info *info); + #endif /*__ASM_ARCH_USBCONTROL_H */ diff --git a/arch/arm/plat-s3c/pm.c b/arch/arm/plat-s3c/pm.c index 767470601e5..e5eef126791 100644 --- a/arch/arm/plat-s3c/pm.c +++ b/arch/arm/plat-s3c/pm.c @@ -41,7 +41,7 @@ unsigned long s3c_pm_flags; * resume before the console layer is available. */ -#ifdef CONFIG_S3C2410_PM_DEBUG +#ifdef CONFIG_SAMSUNG_PM_DEBUG extern void printascii(const char *); void s3c_pm_dbg(const char *fmt, ...) @@ -65,13 +65,13 @@ static inline void s3c_pm_debug_init(void) #else #define s3c_pm_debug_init() do { } while(0) -#endif /* CONFIG_S3C2410_PM_DEBUG */ +#endif /* CONFIG_SAMSUNG_PM_DEBUG */ /* Save the UART configurations if we are configured for debug. */ unsigned char pm_uart_udivslot; -#ifdef CONFIG_S3C2410_PM_DEBUG +#ifdef CONFIG_SAMSUNG_PM_DEBUG struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS]; diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 342647eb91d..a806f359ceb 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -117,13 +117,6 @@ config S3C2410_DMA_DEBUG Enable debugging output for the DMA code. This option sends info to the kernel log, at priority KERN_DEBUG. -config S3C24XX_ADC - bool "ADC common driver support" - help - Core support for the ADC block found in the S3C24XX SoC systems - for drivers such as the touchscreen and hwmon to use to share - this resource. - # SPI default pin configuration code config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 5dee8c12e8b..e0100266d03 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_PM) += sleep.o obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o obj-$(CONFIG_S3C2410_DMA) += dma.o -obj-$(CONFIG_S3C24XX_ADC) += adc.o obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o diff --git a/arch/arm/plat-s3c24xx/clock-dclk.c b/arch/arm/plat-s3c24xx/clock-dclk.c index ac061a1bcb3..cf97caafe56 100644 --- a/arch/arm/plat-s3c24xx/clock-dclk.c +++ b/arch/arm/plat-s3c24xx/clock-dclk.c @@ -161,14 +161,18 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) /* external clock definitions */ +static struct clk_ops dclk_ops = { + .set_parent = s3c24xx_dclk_setparent, + .set_rate = s3c24xx_set_dclk_rate, + .round_rate = s3c24xx_round_dclk_rate, +}; + struct clk s3c24xx_dclk0 = { .name = "dclk0", .id = -1, .ctrlbit = S3C2410_DCLKCON_DCLK0EN, .enable = s3c24xx_dclk_enable, - .set_parent = s3c24xx_dclk_setparent, - .set_rate = s3c24xx_set_dclk_rate, - .round_rate = s3c24xx_round_dclk_rate, + .ops = &dclk_ops, }; struct clk s3c24xx_dclk1 = { @@ -176,19 +180,21 @@ struct clk s3c24xx_dclk1 = { .id = -1, .ctrlbit = S3C2410_DCLKCON_DCLK1EN, .enable = s3c24xx_dclk_enable, - .set_parent = s3c24xx_dclk_setparent, - .set_rate = s3c24xx_set_dclk_rate, - .round_rate = s3c24xx_round_dclk_rate, + .ops = &dclk_ops, +}; + +static struct clk_ops clkout_ops = { + .set_parent = s3c24xx_clkout_setparent, }; struct clk s3c24xx_clkout0 = { .name = "clkout0", .id = -1, - .set_parent = s3c24xx_clkout_setparent, + .ops = &clkout_ops, }; struct clk s3c24xx_clkout1 = { .name = "clkout1", .id = -1, - .set_parent = s3c24xx_clkout_setparent, + .ops = &clkout_ops, }; diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 7f686a31e67..986d4e5408f 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -32,6 +32,7 @@ #include <plat/regs-serial.h> #include <plat/udc.h> +#include <plat/mci.h> #include <plat/devs.h> #include <plat/cpu.h> @@ -112,34 +113,6 @@ struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = { }, }; -/* yart devices */ - -static struct platform_device s3c24xx_uart_device0 = { - .id = 0, -}; - -static struct platform_device s3c24xx_uart_device1 = { - .id = 1, -}; - -static struct platform_device s3c24xx_uart_device2 = { - .id = 2, -}; - -static struct platform_device s3c24xx_uart_device3 = { - .id = 3, -}; - -struct platform_device *s3c24xx_uart_src[4] = { - &s3c24xx_uart_device0, - &s3c24xx_uart_device1, - &s3c24xx_uart_device2, - &s3c24xx_uart_device3, -}; - -struct platform_device *s3c24xx_uart_devs[4] = { -}; - /* LCD Controller */ static struct resource s3c_lcd_resource[] = { @@ -379,6 +352,18 @@ struct platform_device s3c_device_sdi = { EXPORT_SYMBOL(s3c_device_sdi); +void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) +{ + struct s3c24xx_mci_pdata *npd; + + npd = kmemdup(pdata, sizeof(struct s3c24xx_mci_pdata), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory to copy pdata", __func__); + + s3c_device_sdi.dev.platform_data = npd; +} + + /* SPI (0) */ static struct resource s3c_spi0_resource[] = { diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 6d7a961d326..4f0f11a6a67 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -20,7 +20,7 @@ #include <linux/io.h> #include <linux/gpio.h> -#include <mach/gpio-core.h> +#include <plat/gpio-core.h> #include <mach/hardware.h> #include <asm/irq.h> #include <plat/pm.h> diff --git a/arch/arm/plat-s3c24xx/include/plat/mci.h b/arch/arm/plat-s3c24xx/include/plat/mci.h index 36aaa10fad0..2ac2b21ec49 100644 --- a/arch/arm/plat-s3c24xx/include/plat/mci.h +++ b/arch/arm/plat-s3c24xx/include/plat/mci.h @@ -40,4 +40,13 @@ struct s3c24xx_mci_pdata { unsigned short vdd); }; +/** + * s3c24xx_mci_set_platdata - set platform data for mmc/sdi device + * @pdata: The platform data + * + * Copy the platform data supplied by @pdata so that this can be marked + * __initdata. + */ +extern void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata); + #endif /* _ARCH_NCI_H */ diff --git a/arch/arm/plat-s3c24xx/s3c244x-clock.c b/arch/arm/plat-s3c24xx/s3c244x-clock.c index 79371091aa3..f8d96130d1d 100644 --- a/arch/arm/plat-s3c24xx/s3c244x-clock.c +++ b/arch/arm/plat-s3c24xx/s3c244x-clock.c @@ -68,7 +68,9 @@ static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent) static struct clk clk_arm = { .name = "armclk", .id = -1, - .set_parent = s3c2440_setparent_armclk, + .ops = &(struct clk_ops) { + .set_parent = s3c2440_setparent_armclk, + }, }; static int s3c244x_clk_add(struct sys_device *sysdev) diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig index e6da87a5885..37b4519fb83 100644 --- a/arch/arm/plat-s3c64xx/Kconfig +++ b/arch/arm/plat-s3c64xx/Kconfig @@ -13,12 +13,16 @@ config PLAT_S3C64XX select ARM_VIC select NO_IOPORT select ARCH_REQUIRE_GPIOLIB + select SAMSUNG_CLKSRC + select SAMSUNG_IRQ_VIC_TIMER + select SAMSUNG_IRQ_UART select S3C_GPIO_TRACK select S3C_GPIO_PULL_UPDOWN select S3C_GPIO_CFG_S3C24XX select S3C_GPIO_CFG_S3C64XX select S3C_DEV_NAND select USB_ARCH_HAS_OHCI + select SAMSUNG_GPIOLIB_4BIT help Base platform code for any Samsung S3C64XX device diff --git a/arch/arm/plat-s3c64xx/Makefile b/arch/arm/plat-s3c64xx/Makefile index b85b4359e93..80255a5e178 100644 --- a/arch/arm/plat-s3c64xx/Makefile +++ b/arch/arm/plat-s3c64xx/Makefile @@ -13,6 +13,7 @@ obj- := # Core files obj-y += dev-uart.o +obj-y += dev-rtc.o obj-y += cpu.o obj-y += irq.o obj-y += irq-eint.o @@ -35,6 +36,10 @@ obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_S3C64XX_DMA) += dma.o +# ADC support + +obj-$(CONFIG_S3C_ADC) += dev-adc.o + # Device setup obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o @@ -42,3 +47,4 @@ obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o +obj-$(CONFIG_SPI_S3C64XX) += dev-spi.o diff --git a/arch/arm/plat-s3c64xx/clock.c b/arch/arm/plat-s3c64xx/clock.c index 7a36e899360..2989c3a2e94 100644 --- a/arch/arm/plat-s3c64xx/clock.c +++ b/arch/arm/plat-s3c64xx/clock.c @@ -141,6 +141,18 @@ static struct clk init_clocks_disable[] = { .enable = s3c64xx_pclk_ctrl, .ctrlbit = S3C_CLKCON_PCLK_SPI1, }, { + .name = "spi_48m", + .id = 0, + .parent = &clk_48m, + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_SPI0_48, + }, { + .name = "spi_48m", + .id = 1, + .parent = &clk_48m, + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_SPI1_48, + }, { .name = "48m", .id = 0, .parent = &clk_48m, @@ -274,15 +286,7 @@ void __init s3c64xx_register_clocks(void) int ptr; s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - - clkp = init_clocks; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); clkp = init_clocks_disable; for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { diff --git a/arch/arm/plat-s3c64xx/cpu.c b/arch/arm/plat-s3c64xx/cpu.c index 49796d2db86..bc7ca1812e3 100644 --- a/arch/arm/plat-s3c64xx/cpu.c +++ b/arch/arm/plat-s3c64xx/cpu.c @@ -73,17 +73,22 @@ static struct map_desc s3c_iodesc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE, }, { + .virtual = (unsigned long)S3C_VA_MEM, + .pfn = __phys_to_pfn(S3C64XX_PA_SROM), + .length = SZ_4K, + .type = MT_DEVICE, + }, { .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS), .pfn = __phys_to_pfn(S3C_PA_UART), .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S3C_VA_VIC0, + .virtual = (unsigned long)VA_VIC0, .pfn = __phys_to_pfn(S3C64XX_PA_VIC0), .length = SZ_16K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S3C_VA_VIC1, + .virtual = (unsigned long)VA_VIC1, .pfn = __phys_to_pfn(S3C64XX_PA_VIC1), .length = SZ_16K, .type = MT_DEVICE, diff --git a/arch/arm/plat-s3c64xx/dev-adc.c b/arch/arm/plat-s3c64xx/dev-adc.c new file mode 100644 index 00000000000..fafef9b6bcf --- /dev/null +++ b/arch/arm/plat-s3c64xx/dev-adc.c @@ -0,0 +1,46 @@ +/* linux/arch/arm/plat-s3c64xx/dev-adc.c + * + * Copyright 2010 Maurus Cuelenaere + * + * S3C64xx series device definition for ADC device + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include <plat/adc.h> +#include <plat/devs.h> +#include <plat/cpu.h> + +static struct resource s3c_adc_resource[] = { + [0] = { + .start = S3C64XX_PA_ADC, + .end = S3C64XX_PA_ADC + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TC, + .end = IRQ_TC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_ADC, + .end = IRQ_ADC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_adc = { + .name = "s3c64xx-adc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_adc_resource), + .resource = s3c_adc_resource, +}; diff --git a/arch/arm/plat-s3c64xx/dev-audio.c b/arch/arm/plat-s3c64xx/dev-audio.c index a21a88fbb7e..f6b7bfb519d 100644 --- a/arch/arm/plat-s3c64xx/dev-audio.c +++ b/arch/arm/plat-s3c64xx/dev-audio.c @@ -3,7 +3,6 @@ * Copyright 2009 Wolfson Microelectronics * Mark Brown <broonie@opensource.wolfsonmicro.com> * - * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -20,16 +19,69 @@ #include <plat/devs.h> #include <plat/audio.h> +#include <plat/gpio-bank-c.h> #include <plat/gpio-bank-d.h> #include <plat/gpio-bank-e.h> +#include <plat/gpio-bank-h.h> #include <plat/gpio-cfg.h> +static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); + s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); + s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK); + s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI); + s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0); + break; + case 1: + s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK); + s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK); + s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK); + s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI); + s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0); + default: + printk(KERN_DEBUG "Invalid I2S Controller number!"); + return -EINVAL; + } + + return 0; +} + +static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev) +{ + s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0); + s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1); + s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2); + s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK); + s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK); + s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK); + s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI); + + return 0; +} + static struct resource s3c64xx_iis0_resource[] = { [0] = { .start = S3C64XX_PA_IIS0, .end = S3C64XX_PA_IIS0 + 0x100 - 1, .flags = IORESOURCE_MEM, }, + [1] = { + .start = DMACH_I2S0_OUT, + .end = DMACH_I2S0_OUT, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S0_IN, + .end = DMACH_I2S0_IN, + .flags = IORESOURCE_DMA, + }, +}; + +static struct s3c_audio_pdata s3c_i2s0_pdata = { + .cfg_gpio = s3c64xx_i2sv3_cfg_gpio, }; struct platform_device s3c64xx_device_iis0 = { @@ -37,6 +89,9 @@ struct platform_device s3c64xx_device_iis0 = { .id = 0, .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), .resource = s3c64xx_iis0_resource, + .dev = { + .platform_data = &s3c_i2s0_pdata, + }, }; EXPORT_SYMBOL(s3c64xx_device_iis0); @@ -46,6 +101,20 @@ static struct resource s3c64xx_iis1_resource[] = { .end = S3C64XX_PA_IIS1 + 0x100 - 1, .flags = IORESOURCE_MEM, }, + [1] = { + .start = DMACH_I2S1_OUT, + .end = DMACH_I2S1_OUT, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S1_IN, + .end = DMACH_I2S1_IN, + .flags = IORESOURCE_DMA, + }, +}; + +static struct s3c_audio_pdata s3c_i2s1_pdata = { + .cfg_gpio = s3c64xx_i2sv3_cfg_gpio, }; struct platform_device s3c64xx_device_iis1 = { @@ -53,6 +122,9 @@ struct platform_device s3c64xx_device_iis1 = { .id = 1, .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), .resource = s3c64xx_iis1_resource, + .dev = { + .platform_data = &s3c_i2s1_pdata, + }, }; EXPORT_SYMBOL(s3c64xx_device_iis1); @@ -62,6 +134,20 @@ static struct resource s3c64xx_iisv4_resource[] = { .end = S3C64XX_PA_IISV4 + 0x100 - 1, .flags = IORESOURCE_MEM, }, + [1] = { + .start = DMACH_HSI_I2SV40_TX, + .end = DMACH_HSI_I2SV40_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_HSI_I2SV40_RX, + .end = DMACH_HSI_I2SV40_RX, + .flags = IORESOURCE_DMA, + }, +}; + +static struct s3c_audio_pdata s3c_i2sv4_pdata = { + .cfg_gpio = s3c64xx_i2sv4_cfg_gpio, }; struct platform_device s3c64xx_device_iisv4 = { @@ -69,6 +155,9 @@ struct platform_device s3c64xx_device_iisv4 = { .id = -1, .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource), .resource = s3c64xx_iisv4_resource, + .dev = { + .platform_data = &s3c_i2sv4_pdata, + }, }; EXPORT_SYMBOL(s3c64xx_device_iisv4); diff --git a/arch/arm/plat-s3c64xx/dev-rtc.c b/arch/arm/plat-s3c64xx/dev-rtc.c new file mode 100644 index 00000000000..b9e7a05f012 --- /dev/null +++ b/arch/arm/plat-s3c64xx/dev-rtc.c @@ -0,0 +1,43 @@ +/* linux/arch/arm/plat-s3c64xx/dev-rtc.c + * + * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> + +#include <mach/irqs.h> +#include <mach/map.h> + +#include <plat/devs.h> + +static struct resource s3c_rtc_resource[] = { + [0] = { + .start = S3C64XX_PA_RTC, + .end = S3C64XX_PA_RTC + 0xff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC_ALARM, + .end = IRQ_RTC_ALARM, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTC_TIC, + .end = IRQ_RTC_TIC, + .flags = IORESOURCE_IRQ + } +}; + +struct platform_device s3c_device_rtc = { + .name = "s3c64xx-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_rtc_resource), + .resource = s3c_rtc_resource, +}; +EXPORT_SYMBOL(s3c_device_rtc); diff --git a/arch/arm/plat-s3c64xx/dev-spi.c b/arch/arm/plat-s3c64xx/dev-spi.c new file mode 100644 index 00000000000..ca10388d7ed --- /dev/null +++ b/arch/arm/plat-s3c64xx/dev-spi.c @@ -0,0 +1,183 @@ +/* linux/arch/arm/plat-s3c64xx/dev-spi.c + * + * Copyright (C) 2009 Samsung Electronics Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> + +#include <mach/dma.h> +#include <mach/map.h> +#include <mach/gpio.h> + +#include <plat/spi-clocks.h> + +#include <plat/s3c64xx-spi.h> +#include <plat/gpio-bank-c.h> +#include <plat/gpio-cfg.h> +#include <plat/irqs.h> + +static char *spi_src_clks[] = { + [S3C64XX_SPI_SRCCLK_PCLK] = "pclk", + [S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus", + [S3C64XX_SPI_SRCCLK_48M] = "spi_48m", +}; + +/* SPI Controller platform_devices */ + +/* Since we emulate multi-cs capability, we do not touch the GPC-3,7. + * The emulated CS is toggled by board specific mechanism, as it can + * be either some immediate GPIO or some signal out of some other + * chip in between ... or some yet another way. + * We simply do not assume anything about CS. + */ +static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin(S3C64XX_GPC(0), S3C64XX_GPC0_SPI_MISO0); + s3c_gpio_cfgpin(S3C64XX_GPC(1), S3C64XX_GPC1_SPI_CLKO); + s3c_gpio_cfgpin(S3C64XX_GPC(2), S3C64XX_GPC2_SPI_MOSIO); + s3c_gpio_setpull(S3C64XX_GPC(0), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S3C64XX_GPC(1), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S3C64XX_GPC(2), S3C_GPIO_PULL_UP); + break; + + case 1: + s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_SPI_MISO1); + s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_SPI_CLK1); + s3c_gpio_cfgpin(S3C64XX_GPC(6), S3C64XX_GPC6_SPI_MOSI1); + s3c_gpio_setpull(S3C64XX_GPC(4), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S3C64XX_GPC(5), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S3C64XX_GPC(6), S3C_GPIO_PULL_UP); + break; + + default: + dev_err(&pdev->dev, "Invalid SPI Controller number!"); + return -EINVAL; + } + + return 0; +} + +static struct resource s3c64xx_spi0_resource[] = { + [0] = { + .start = S3C64XX_PA_SPI0, + .end = S3C64XX_PA_SPI0 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_SPI0_TX, + .end = DMACH_SPI0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_SPI0_RX, + .end = DMACH_SPI0_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = IRQ_SPI0, + .end = IRQ_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c64xx_spi_info s3c64xx_spi0_pdata = { + .cfg_gpio = s3c64xx_spi_cfg_gpio, + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 13, +}; + +static u64 spi_dmamask = DMA_BIT_MASK(32); + +struct platform_device s3c64xx_device_spi0 = { + .name = "s3c64xx-spi", + .id = 0, + .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), + .resource = s3c64xx_spi0_resource, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c64xx_spi0_pdata, + }, +}; +EXPORT_SYMBOL(s3c64xx_device_spi0); + +static struct resource s3c64xx_spi1_resource[] = { + [0] = { + .start = S3C64XX_PA_SPI1, + .end = S3C64XX_PA_SPI1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_SPI1_TX, + .end = DMACH_SPI1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_SPI1_RX, + .end = DMACH_SPI1_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = IRQ_SPI1, + .end = IRQ_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c64xx_spi_info s3c64xx_spi1_pdata = { + .cfg_gpio = s3c64xx_spi_cfg_gpio, + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 13, +}; + +struct platform_device s3c64xx_device_spi1 = { + .name = "s3c64xx-spi", + .id = 1, + .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource), + .resource = s3c64xx_spi1_resource, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s3c64xx_spi1_pdata, + }, +}; +EXPORT_SYMBOL(s3c64xx_device_spi1); + +void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) +{ + struct s3c64xx_spi_info *pd; + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0 + || src_clk_nr > S3C64XX_SPI_SRCCLK_48M) { + printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__); + return; + } + + switch (cntrlr) { + case 0: + pd = &s3c64xx_spi0_pdata; + break; + case 1: + pd = &s3c64xx_spi1_pdata; + break; + default: + printk(KERN_ERR "%s: Invalid SPI controller(%d)\n", + __func__, cntrlr); + return; + } + + pd->num_cs = num_cs; + pd->src_clk_nr = src_clk_nr; + pd->src_clk_name = spi_src_clks[src_clk_nr]; +} diff --git a/arch/arm/plat-s3c64xx/dev-uart.c b/arch/arm/plat-s3c64xx/dev-uart.c index 62c11a6fc7b..f797f748b99 100644 --- a/arch/arm/plat-s3c64xx/dev-uart.c +++ b/arch/arm/plat-s3c64xx/dev-uart.c @@ -145,32 +145,3 @@ struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = { .nr_resources = ARRAY_SIZE(s3c64xx_uart3_resource), }, }; - -/* uart devices */ - -static struct platform_device s3c24xx_uart_device0 = { - .id = 0, -}; - -static struct platform_device s3c24xx_uart_device1 = { - .id = 1, -}; - -static struct platform_device s3c24xx_uart_device2 = { - .id = 2, -}; - -static struct platform_device s3c24xx_uart_device3 = { - .id = 3, -}; - -struct platform_device *s3c24xx_uart_src[4] = { - &s3c24xx_uart_device0, - &s3c24xx_uart_device1, - &s3c24xx_uart_device2, - &s3c24xx_uart_device3, -}; - -struct platform_device *s3c24xx_uart_devs[4] = { -}; - diff --git a/arch/arm/plat-s3c64xx/gpiolib.c b/arch/arm/plat-s3c64xx/gpiolib.c index 77856045727..b6e3f55321f 100644 --- a/arch/arm/plat-s3c64xx/gpiolib.c +++ b/arch/arm/plat-s3c64xx/gpiolib.c @@ -18,8 +18,8 @@ #include <mach/map.h> #include <mach/gpio.h> -#include <mach/gpio-core.h> +#include <plat/gpio-core.h> #include <plat/gpio-cfg.h> #include <plat/gpio-cfg-helpers.h> #include <plat/regs-gpio.h> @@ -49,150 +49,6 @@ * [2] BANK has two control registers, GPxCON0 and GPxCON1 */ -#define OFF_GPCON (0x00) -#define OFF_GPDAT (0x04) - -#define con_4bit_shift(__off) ((__off) * 4) - -#if 1 -#define gpio_dbg(x...) do { } while(0) -#else -#define gpio_dbg(x...) printk(KERN_DEBUG x) -#endif - -/* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where - * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the - * following example: - * - * base + 0x00: Control register, 4 bits per gpio - * gpio n: 4 bits starting at (4*n) - * 0000 = input, 0001 = output, others mean special-function - * base + 0x04: Data register, 1 bit per gpio - * bit n: data bit n - * - * Note, since the data register is one bit per gpio and is at base + 0x4 - * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of - * the output. -*/ - -static int s3c64xx_gpiolib_4bit_input(struct gpio_chip *chip, unsigned offset) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long con; - - con = __raw_readl(base + OFF_GPCON); - con &= ~(0xf << con_4bit_shift(offset)); - __raw_writel(con, base + OFF_GPCON); - - gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); - - return 0; -} - -static int s3c64xx_gpiolib_4bit_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - unsigned long con; - unsigned long dat; - - con = __raw_readl(base + OFF_GPCON); - con &= ~(0xf << con_4bit_shift(offset)); - con |= 0x1 << con_4bit_shift(offset); - - dat = __raw_readl(base + OFF_GPDAT); - if (value) - dat |= 1 << offset; - else - dat &= ~(1 << offset); - - __raw_writel(dat, base + OFF_GPDAT); - __raw_writel(con, base + OFF_GPCON); - __raw_writel(dat, base + OFF_GPDAT); - - gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); - - return 0; -} - -/* The next set of routines are for the case where the GPIO configuration - * registers are 4 bits per GPIO but there is more than one register (the - * bank has more than 8 GPIOs. - * - * This case is the similar to the 4 bit case, but the registers are as - * follows: - * - * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs) - * gpio n: 4 bits starting at (4*n) - * 0000 = input, 0001 = output, others mean special-function - * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs) - * gpio n: 4 bits starting at (4*n) - * 0000 = input, 0001 = output, others mean special-function - * base + 0x08: Data register, 1 bit per gpio - * bit n: data bit n - * - * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we - * store the 'base + 0x4' address so that these routines see the data - * register at ourchip->base + 0x04. -*/ - -static int s3c64xx_gpiolib_4bit2_input(struct gpio_chip *chip, unsigned offset) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - void __iomem *regcon = base; - unsigned long con; - - if (offset > 7) - offset -= 8; - else - regcon -= 4; - - con = __raw_readl(regcon); - con &= ~(0xf << con_4bit_shift(offset)); - __raw_writel(con, regcon); - - gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); - - return 0; - -} - -static int s3c64xx_gpiolib_4bit2_output(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); - void __iomem *base = ourchip->base; - void __iomem *regcon = base; - unsigned long con; - unsigned long dat; - - if (offset > 7) - offset -= 8; - else - regcon -= 4; - - con = __raw_readl(regcon); - con &= ~(0xf << con_4bit_shift(offset)); - con |= 0x1 << con_4bit_shift(offset); - - dat = __raw_readl(base + OFF_GPDAT); - if (value) - dat |= 1 << offset; - else - dat &= ~(1 << offset); - - __raw_writel(dat, base + OFF_GPDAT); - __raw_writel(con, regcon); - __raw_writel(dat, base + OFF_GPDAT); - - gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); - - return 0; -} - static struct s3c_gpio_cfg gpio_4bit_cfg_noint = { .set_config = s3c_gpio_setcfg_s3c64xx_4bit, .set_pull = s3c_gpio_setpull_updown, @@ -399,20 +255,6 @@ static struct s3c_gpio_chip gpio_2bit[] = { }, }; -static __init void s3c64xx_gpiolib_add_4bit(struct s3c_gpio_chip *chip) -{ - chip->chip.direction_input = s3c64xx_gpiolib_4bit_input; - chip->chip.direction_output = s3c64xx_gpiolib_4bit_output; - chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); -} - -static __init void s3c64xx_gpiolib_add_4bit2(struct s3c_gpio_chip *chip) -{ - chip->chip.direction_input = s3c64xx_gpiolib_4bit2_input; - chip->chip.direction_output = s3c64xx_gpiolib_4bit2_output; - chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); -} - static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip) { chip->pm = __gpio_pm(&s3c_gpio_pm_2bit); @@ -432,10 +274,10 @@ static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips, static __init int s3c64xx_gpiolib_init(void) { s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit), - s3c64xx_gpiolib_add_4bit); + samsung_gpiolib_add_4bit); s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2), - s3c64xx_gpiolib_add_4bit2); + samsung_gpiolib_add_4bit2); s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit), s3c64xx_gpiolib_add_2bit); diff --git a/arch/arm/plat-s3c64xx/include/plat/irqs.h b/arch/arm/plat-s3c64xx/include/plat/irqs.h index 7956fd3bb19..a22758194e6 100644 --- a/arch/arm/plat-s3c64xx/include/plat/irqs.h +++ b/arch/arm/plat-s3c64xx/include/plat/irqs.h @@ -24,8 +24,8 @@ #define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET) -#define S3C_VIC0_BASE S3C_IRQ(0) -#define S3C_VIC1_BASE S3C_IRQ(32) +#define IRQ_VIC0_BASE S3C_IRQ(0) +#define IRQ_VIC1_BASE S3C_IRQ(32) /* UART interrupts, each UART has 4 intterupts per channel so * use the space between the ISA and S3C main interrupts. Note, these @@ -59,8 +59,8 @@ /* VIC based IRQs */ -#define S3C64XX_IRQ_VIC0(x) (S3C_VIC0_BASE + (x)) -#define S3C64XX_IRQ_VIC1(x) (S3C_VIC1_BASE + (x)) +#define S3C64XX_IRQ_VIC0(x) (IRQ_VIC0_BASE + (x)) +#define S3C64XX_IRQ_VIC1(x) (IRQ_VIC1_BASE + (x)) /* VIC0 */ @@ -198,7 +198,11 @@ * interrupt controllers). */ #define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1) +#ifdef CONFIG_SMDK6410_WM1190_EV1 +#define IRQ_BOARD_NR 64 +#else #define IRQ_BOARD_NR 16 +#endif #define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR) diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h index ff46e7fa957..3ef62741e5d 100644 --- a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h +++ b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h @@ -35,14 +35,6 @@ #define S3C_MEM0_GATE S3C_CLKREG(0x3C) /* CLKDIV0 */ -#define S3C6400_CLKDIV0_MFC_MASK (0xf << 28) -#define S3C6400_CLKDIV0_MFC_SHIFT (28) -#define S3C6400_CLKDIV0_JPEG_MASK (0xf << 24) -#define S3C6400_CLKDIV0_JPEG_SHIFT (24) -#define S3C6400_CLKDIV0_CAM_MASK (0xf << 20) -#define S3C6400_CLKDIV0_CAM_SHIFT (20) -#define S3C6400_CLKDIV0_SECURITY_MASK (0x3 << 18) -#define S3C6400_CLKDIV0_SECURITY_SHIFT (18) #define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12) #define S3C6400_CLKDIV0_PCLK_SHIFT (12) #define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9) @@ -51,42 +43,11 @@ #define S3C6400_CLKDIV0_HCLK_SHIFT (8) #define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4) #define S3C6400_CLKDIV0_MPLL_SHIFT (4) + #define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0) #define S3C6410_CLKDIV0_ARM_MASK (0xf << 0) #define S3C6400_CLKDIV0_ARM_SHIFT (0) -/* CLKDIV1 */ -#define S3C6410_CLKDIV1_FIMC_MASK (0xf << 24) -#define S3C6410_CLKDIV1_FIMC_SHIFT (24) -#define S3C6400_CLKDIV1_UHOST_MASK (0xf << 20) -#define S3C6400_CLKDIV1_UHOST_SHIFT (20) -#define S3C6400_CLKDIV1_SCALER_MASK (0xf << 16) -#define S3C6400_CLKDIV1_SCALER_SHIFT (16) -#define S3C6400_CLKDIV1_LCD_MASK (0xf << 12) -#define S3C6400_CLKDIV1_LCD_SHIFT (12) -#define S3C6400_CLKDIV1_MMC2_MASK (0xf << 8) -#define S3C6400_CLKDIV1_MMC2_SHIFT (8) -#define S3C6400_CLKDIV1_MMC1_MASK (0xf << 4) -#define S3C6400_CLKDIV1_MMC1_SHIFT (4) -#define S3C6400_CLKDIV1_MMC0_MASK (0xf << 0) -#define S3C6400_CLKDIV1_MMC0_SHIFT (0) - -/* CLKDIV2 */ -#define S3C6410_CLKDIV2_AUDIO2_MASK (0xf << 24) -#define S3C6410_CLKDIV2_AUDIO2_SHIFT (24) -#define S3C6400_CLKDIV2_IRDA_MASK (0xf << 20) -#define S3C6400_CLKDIV2_IRDA_SHIFT (20) -#define S3C6400_CLKDIV2_UART_MASK (0xf << 16) -#define S3C6400_CLKDIV2_UART_SHIFT (16) -#define S3C6400_CLKDIV2_AUDIO1_MASK (0xf << 12) -#define S3C6400_CLKDIV2_AUDIO1_SHIFT (12) -#define S3C6400_CLKDIV2_AUDIO0_MASK (0xf << 8) -#define S3C6400_CLKDIV2_AUDIO0_SHIFT (8) -#define S3C6400_CLKDIV2_SPI1_MASK (0xf << 4) -#define S3C6400_CLKDIV2_SPI1_SHIFT (4) -#define S3C6400_CLKDIV2_SPI0_MASK (0xf << 0) -#define S3C6400_CLKDIV2_SPI0_SHIFT (0) - /* HCLK GATE Registers */ #define S3C_CLKCON_HCLK_3DSE (1<<31) #define S3C_CLKCON_HCLK_UHOST (1<<29) @@ -192,34 +153,4 @@ #define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2) #define S3C6400_CLKSRC_MFC (1 << 4) -#define S3C6410_CLKSRC_TV27_MASK (0x1 << 31) -#define S3C6410_CLKSRC_TV27_SHIFT (31) -#define S3C6410_CLKSRC_DAC27_MASK (0x1 << 30) -#define S3C6410_CLKSRC_DAC27_SHIFT (30) -#define S3C6400_CLKSRC_SCALER_MASK (0x3 << 28) -#define S3C6400_CLKSRC_SCALER_SHIFT (28) -#define S3C6400_CLKSRC_LCD_MASK (0x3 << 26) -#define S3C6400_CLKSRC_LCD_SHIFT (26) -#define S3C6400_CLKSRC_IRDA_MASK (0x3 << 24) -#define S3C6400_CLKSRC_IRDA_SHIFT (24) -#define S3C6400_CLKSRC_MMC2_MASK (0x3 << 22) -#define S3C6400_CLKSRC_MMC2_SHIFT (22) -#define S3C6400_CLKSRC_MMC1_MASK (0x3 << 20) -#define S3C6400_CLKSRC_MMC1_SHIFT (20) -#define S3C6400_CLKSRC_MMC0_MASK (0x3 << 18) -#define S3C6400_CLKSRC_MMC0_SHIFT (18) -#define S3C6400_CLKSRC_SPI1_MASK (0x3 << 16) -#define S3C6400_CLKSRC_SPI1_SHIFT (16) -#define S3C6400_CLKSRC_SPI0_MASK (0x3 << 14) -#define S3C6400_CLKSRC_SPI0_SHIFT (14) -#define S3C6400_CLKSRC_UART_MASK (0x1 << 13) -#define S3C6400_CLKSRC_UART_SHIFT (13) -#define S3C6400_CLKSRC_AUDIO1_MASK (0x7 << 10) -#define S3C6400_CLKSRC_AUDIO1_SHIFT (10) -#define S3C6400_CLKSRC_AUDIO0_MASK (0x7 << 7) -#define S3C6400_CLKSRC_AUDIO0_SHIFT (7) -#define S3C6400_CLKSRC_UHOST_MASK (0x3 << 5) -#define S3C6400_CLKSRC_UHOST_SHIFT (5) - - #endif /* _PLAT_REGS_CLOCK_H */ diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-srom.h b/arch/arm/plat-s3c64xx/include/plat/regs-srom.h new file mode 100644 index 00000000000..756731b3629 --- /dev/null +++ b/arch/arm/plat-s3c64xx/include/plat/regs-srom.h @@ -0,0 +1,59 @@ +/* arch/arm/plat-s3c64xx/include/plat/regs-srom.h + * + * Copyright 2009 Andy Green <andy@warmcat.com> + * + * S3C64XX SROM definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __PLAT_REGS_SROM_H +#define __PLAT_REGS_SROM_H __FILE__ + +#define S3C64XX_SROMREG(x) (S3C_VA_MEM + (x)) + +#define S3C64XX_SROM_BW S3C64XX_SROMREG(0) +#define S3C64XX_SROM_BC0 S3C64XX_SROMREG(4) +#define S3C64XX_SROM_BC1 S3C64XX_SROMREG(8) +#define S3C64XX_SROM_BC2 S3C64XX_SROMREG(0xc) +#define S3C64XX_SROM_BC3 S3C64XX_SROMREG(0x10) +#define S3C64XX_SROM_BC4 S3C64XX_SROMREG(0x14) +#define S3C64XX_SROM_BC5 S3C64XX_SROMREG(0x18) + +/* + * one register BW holds 5 x 4-bit packed settings for NCS0 - NCS4 + */ + +#define S3C64XX_SROM_BW__DATAWIDTH__SHIFT 0 +#define S3C64XX_SROM_BW__WAITENABLE__SHIFT 2 +#define S3C64XX_SROM_BW__BYTEENABLE__SHIFT 3 +#define S3C64XX_SROM_BW__CS_MASK 0xf + +#define S3C64XX_SROM_BW__NCS0__SHIFT 0 +#define S3C64XX_SROM_BW__NCS1__SHIFT 4 +#define S3C64XX_SROM_BW__NCS2__SHIFT 8 +#define S3C64XX_SROM_BW__NCS3__SHIFT 0xc +#define S3C64XX_SROM_BW__NCS4__SHIFT 0x10 + +/* + * applies to same to BCS0 - BCS4 + */ + +#define S3C64XX_SROM_BCX__PMC__SHIFT 0 +#define S3C64XX_SROM_BCX__PMC__MASK 3 +#define S3C64XX_SROM_BCX__TACP__SHIFT 4 +#define S3C64XX_SROM_BCX__TACP__MASK 0xf +#define S3C64XX_SROM_BCX__TCAH__SHIFT 8 +#define S3C64XX_SROM_BCX__TCAH__MASK 0xf +#define S3C64XX_SROM_BCX__TCOH__SHIFT 12 +#define S3C64XX_SROM_BCX__TCOH__MASK 0xf +#define S3C64XX_SROM_BCX__TACC__SHIFT 16 +#define S3C64XX_SROM_BCX__TACC__MASK 0x1f +#define S3C64XX_SROM_BCX__TCOS__SHIFT 24 +#define S3C64XX_SROM_BCX__TCOS__MASK 0xf +#define S3C64XX_SROM_BCX__TACS__SHIFT 28 +#define S3C64XX_SROM_BCX__TACS__MASK 0xf + +#endif /* _PLAT_REGS_SROM_H */ diff --git a/arch/arm/plat-s3c64xx/include/plat/spi-clocks.h b/arch/arm/plat-s3c64xx/include/plat/spi-clocks.h new file mode 100644 index 00000000000..524bdae3f62 --- /dev/null +++ b/arch/arm/plat-s3c64xx/include/plat/spi-clocks.h @@ -0,0 +1,18 @@ +/* linux/arch/arm/plat-s3c64xx/include/plat/spi-clocks.h + * + * Copyright (C) 2009 Samsung Electronics Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __S3C64XX_PLAT_SPI_CLKS_H +#define __S3C64XX_PLAT_SPI_CLKS_H __FILE__ + +#define S3C64XX_SPI_SRCCLK_PCLK 0 +#define S3C64XX_SPI_SRCCLK_SPIBUS 1 +#define S3C64XX_SPI_SRCCLK_48M 2 + +#endif /* __S3C64XX_PLAT_SPI_CLKS_H */ diff --git a/arch/arm/plat-s3c64xx/irq.c b/arch/arm/plat-s3c64xx/irq.c index 8dc5b6da978..67a145d440f 100644 --- a/arch/arm/plat-s3c64xx/irq.c +++ b/arch/arm/plat-s3c64xx/irq.c @@ -21,88 +21,11 @@ #include <asm/hardware/vic.h> #include <mach/map.h> -#include <plat/regs-serial.h> -#include <plat/regs-timer.h> +#include <plat/irq-vic-timer.h> +#include <plat/irq-uart.h> #include <plat/cpu.h> -/* Timer interrupt handling */ - -static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq) -{ - generic_handle_irq(sub_irq); -} - -static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER0); -} - -static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER1); -} - -static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER2); -} - -static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER3); -} - -static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER4); -} - -/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ - -static void s3c_irq_timer_mask(unsigned int irq) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - - reg &= 0x1f; /* mask out pending interrupts */ - reg &= ~(1 << (irq - IRQ_TIMER0)); - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static void s3c_irq_timer_unmask(unsigned int irq) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - - reg &= 0x1f; /* mask out pending interrupts */ - reg |= 1 << (irq - IRQ_TIMER0); - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static void s3c_irq_timer_ack(unsigned int irq) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - - reg &= 0x1f; - reg |= (1 << 5) << (irq - IRQ_TIMER0); - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static struct irq_chip s3c_irq_timer = { - .name = "s3c-timer", - .mask = s3c_irq_timer_mask, - .unmask = s3c_irq_timer_unmask, - .ack = s3c_irq_timer_ack, -}; - -struct uart_irq { - void __iomem *regs; - unsigned int base_irq; - unsigned int parent_irq; -}; - -/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] - * are consecutive when looking up the interrupt in the demux routines. - */ -static struct uart_irq uart_irqs[] = { +static struct s3c_uart_irq uart_irqs[] = { [0] = { .regs = S3C_VA_UART0, .base_irq = IRQ_S3CUART_BASE0, @@ -125,132 +48,22 @@ static struct uart_irq uart_irqs[] = { }, }; -static inline void __iomem *s3c_irq_uart_base(unsigned int irq) -{ - struct uart_irq *uirq = get_irq_chip_data(irq); - return uirq->regs; -} - -static inline unsigned int s3c_irq_uart_bit(unsigned int irq) -{ - return irq & 3; -} - -/* UART interrupt registers, not worth adding to seperate include header */ - -static void s3c_irq_uart_mask(unsigned int irq) -{ - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg |= (1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); -} - -static void s3c_irq_uart_maskack(unsigned int irq) -{ - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg |= (1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); - __raw_writel(1 << bit, regs + S3C64XX_UINTP); -} - -static void s3c_irq_uart_unmask(unsigned int irq) -{ - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg &= ~(1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); -} - -static void s3c_irq_uart_ack(unsigned int irq) -{ - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); - - __raw_writel(1 << bit, regs + S3C64XX_UINTP); -} - -static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) -{ - struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0]; - u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); - int base = uirq->base_irq; - - if (pend & (1 << 0)) - generic_handle_irq(base); - if (pend & (1 << 1)) - generic_handle_irq(base + 1); - if (pend & (1 << 2)) - generic_handle_irq(base + 2); - if (pend & (1 << 3)) - generic_handle_irq(base + 3); -} - -static struct irq_chip s3c_irq_uart = { - .name = "s3c-uart", - .mask = s3c_irq_uart_mask, - .unmask = s3c_irq_uart_unmask, - .mask_ack = s3c_irq_uart_maskack, - .ack = s3c_irq_uart_ack, -}; - -static void __init s3c64xx_uart_irq(struct uart_irq *uirq) -{ - void __iomem *reg_base = uirq->regs; - unsigned int irq; - int offs; - - /* mask all interrupts at the start. */ - __raw_writel(0xf, reg_base + S3C64XX_UINTM); - - for (offs = 0; offs < 3; offs++) { - irq = uirq->base_irq + offs; - - set_irq_chip(irq, &s3c_irq_uart); - set_irq_chip_data(irq, uirq); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } - - set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); -} void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) { - int uart, irq; - printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); /* initialise the pair of VICs */ - vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid, 0); - vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid, 0); + vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, 0); + vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0); /* add the timer sub-irqs */ - set_irq_chained_handler(IRQ_TIMER0_VIC, s3c_irq_demux_timer0); - set_irq_chained_handler(IRQ_TIMER1_VIC, s3c_irq_demux_timer1); - set_irq_chained_handler(IRQ_TIMER2_VIC, s3c_irq_demux_timer2); - set_irq_chained_handler(IRQ_TIMER3_VIC, s3c_irq_demux_timer3); - set_irq_chained_handler(IRQ_TIMER4_VIC, s3c_irq_demux_timer4); - - for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) { - set_irq_chip(irq, &s3c_irq_timer); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } + s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0); + s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1); + s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2); + s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3); + s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4); - for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++) - s3c64xx_uart_irq(&uart_irqs[uart]); + s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); } - - diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c index 6ffa21eb1b9..cb2bf4bff05 100644 --- a/arch/arm/plat-s3c64xx/s3c6400-clock.c +++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c @@ -29,6 +29,7 @@ #include <plat/regs-clock.h> #include <plat/clock.h> +#include <plat/clock-clksrc.h> #include <plat/cpu.h> #include <plat/pll.h> @@ -46,22 +47,7 @@ static struct clk clk_ext_xtal_mux = { #define clk_fin_epll clk_ext_xtal_mux #define clk_fout_mpll clk_mpll - -struct clk_sources { - unsigned int nr_sources; - struct clk **sources; -}; - -struct clksrc_clk { - struct clk clk; - unsigned int mask; - unsigned int shift; - - struct clk_sources *sources; - - unsigned int divider_shift; - void __iomem *reg_divider; -}; +#define clk_fout_epll clk_epll static struct clk clk_fout_apll = { .name = "fout_apll", @@ -73,7 +59,7 @@ static struct clk *clk_src_apll_list[] = { [1] = &clk_fout_apll, }; -static struct clk_sources clk_src_apll = { +static struct clksrc_sources clk_src_apll = { .sources = clk_src_apll_list, .nr_sources = ARRAY_SIZE(clk_src_apll_list), }; @@ -83,22 +69,16 @@ static struct clksrc_clk clk_mout_apll = { .name = "mout_apll", .id = -1, }, - .shift = S3C6400_CLKSRC_APLL_MOUT_SHIFT, - .mask = S3C6400_CLKSRC_APLL_MOUT, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 0, .size = 1 }, .sources = &clk_src_apll, }; -static struct clk clk_fout_epll = { - .name = "fout_epll", - .id = -1, -}; - static struct clk *clk_src_epll_list[] = { [0] = &clk_fin_epll, [1] = &clk_fout_epll, }; -static struct clk_sources clk_src_epll = { +static struct clksrc_sources clk_src_epll = { .sources = clk_src_epll_list, .nr_sources = ARRAY_SIZE(clk_src_epll_list), }; @@ -108,8 +88,7 @@ static struct clksrc_clk clk_mout_epll = { .name = "mout_epll", .id = -1, }, - .shift = S3C6400_CLKSRC_EPLL_MOUT_SHIFT, - .mask = S3C6400_CLKSRC_EPLL_MOUT, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 2, .size = 1 }, .sources = &clk_src_epll, }; @@ -118,7 +97,7 @@ static struct clk *clk_src_mpll_list[] = { [1] = &clk_fout_mpll, }; -static struct clk_sources clk_src_mpll = { +static struct clksrc_sources clk_src_mpll = { .sources = clk_src_mpll_list, .nr_sources = ARRAY_SIZE(clk_src_mpll_list), }; @@ -128,8 +107,7 @@ static struct clksrc_clk clk_mout_mpll = { .name = "mout_mpll", .id = -1, }, - .shift = S3C6400_CLKSRC_MPLL_MOUT_SHIFT, - .mask = S3C6400_CLKSRC_MPLL_MOUT, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 1, .size = 1 }, .sources = &clk_src_mpll, }; @@ -187,9 +165,11 @@ static struct clk clk_arm = { .name = "armclk", .id = -1, .parent = &clk_mout_apll.clk, - .get_rate = s3c64xx_clk_arm_get_rate, - .set_rate = s3c64xx_clk_arm_set_rate, - .round_rate = s3c64xx_clk_arm_round_rate, + .ops = &(struct clk_ops) { + .get_rate = s3c64xx_clk_arm_get_rate, + .set_rate = s3c64xx_clk_arm_set_rate, + .round_rate = s3c64xx_clk_arm_round_rate, + }, }; static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk) @@ -204,11 +184,15 @@ static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk) return rate; } +static struct clk_ops clk_dout_ops = { + .get_rate = s3c64xx_clk_doutmpll_get_rate, +}; + static struct clk clk_dout_mpll = { .name = "dout_mpll", .id = -1, .parent = &clk_mout_mpll.clk, - .get_rate = s3c64xx_clk_doutmpll_get_rate, + .ops = &clk_dout_ops, }; static struct clk *clkset_spi_mmc_list[] = { @@ -218,7 +202,7 @@ static struct clk *clkset_spi_mmc_list[] = { &clk_27m, }; -static struct clk_sources clkset_spi_mmc = { +static struct clksrc_sources clkset_spi_mmc = { .sources = clkset_spi_mmc_list, .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list), }; @@ -230,7 +214,7 @@ static struct clk *clkset_irda_list[] = { &clk_27m, }; -static struct clk_sources clkset_irda = { +static struct clksrc_sources clkset_irda = { .sources = clkset_irda_list, .nr_sources = ARRAY_SIZE(clkset_irda_list), }; @@ -242,7 +226,7 @@ static struct clk *clkset_uart_list[] = { NULL }; -static struct clk_sources clkset_uart = { +static struct clksrc_sources clkset_uart = { .sources = clkset_uart_list, .nr_sources = ARRAY_SIZE(clkset_uart_list), }; @@ -254,12 +238,11 @@ static struct clk *clkset_uhost_list[] = { &clk_fin_epll, }; -static struct clk_sources clkset_uhost = { +static struct clksrc_sources clkset_uhost = { .sources = clkset_uhost_list, .nr_sources = ARRAY_SIZE(clkset_uhost_list), }; - /* The peripheral clocks are all controlled via clocksource followed * by an optional divider and gate stage. We currently roll this into * one clock which hides the intermediate clock from the mux. @@ -270,221 +253,7 @@ static struct clk_sources clkset_uhost = { * have a common parent divisor so are not included here. */ -static inline struct clksrc_clk *to_clksrc(struct clk *clk) -{ - return container_of(clk, struct clksrc_clk, clk); -} - -static unsigned long s3c64xx_getrate_clksrc(struct clk *clk) -{ - struct clksrc_clk *sclk = to_clksrc(clk); - unsigned long rate = clk_get_rate(clk->parent); - u32 clkdiv = __raw_readl(sclk->reg_divider); - - clkdiv >>= sclk->divider_shift; - clkdiv &= 0xf; - clkdiv++; - - rate /= clkdiv; - return rate; -} - -static int s3c64xx_setrate_clksrc(struct clk *clk, unsigned long rate) -{ - struct clksrc_clk *sclk = to_clksrc(clk); - void __iomem *reg = sclk->reg_divider; - unsigned int div; - u32 val; - - rate = clk_round_rate(clk, rate); - div = clk_get_rate(clk->parent) / rate; - if (div > 16) - return -EINVAL; - - val = __raw_readl(reg); - val &= ~(0xf << sclk->divider_shift); - val |= (div - 1) << sclk->divider_shift; - __raw_writel(val, reg); - - return 0; -} - -static int s3c64xx_setparent_clksrc(struct clk *clk, struct clk *parent) -{ - struct clksrc_clk *sclk = to_clksrc(clk); - struct clk_sources *srcs = sclk->sources; - u32 clksrc = __raw_readl(S3C_CLK_SRC); - int src_nr = -1; - int ptr; - - for (ptr = 0; ptr < srcs->nr_sources; ptr++) - if (srcs->sources[ptr] == parent) { - src_nr = ptr; - break; - } - - if (src_nr >= 0) { - clksrc &= ~sclk->mask; - clksrc |= src_nr << sclk->shift; - - __raw_writel(clksrc, S3C_CLK_SRC); - - clk->parent = parent; - return 0; - } - - return -EINVAL; -} - -static unsigned long s3c64xx_roundrate_clksrc(struct clk *clk, - unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - int div; - - if (rate > parent_rate) - rate = parent_rate; - else { - div = parent_rate / rate; - - if (div == 0) - div = 1; - if (div > 16) - div = 16; - - rate = parent_rate / div; - } - - return rate; -} - -static struct clksrc_clk clk_mmc0 = { - .clk = { - .name = "mmc_bus", - .id = 0, - .ctrlbit = S3C_CLKCON_SCLK_MMC0, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_MMC0_SHIFT, - .mask = S3C6400_CLKSRC_MMC0_MASK, - .sources = &clkset_spi_mmc, - .divider_shift = S3C6400_CLKDIV1_MMC0_SHIFT, - .reg_divider = S3C_CLK_DIV1, -}; - -static struct clksrc_clk clk_mmc1 = { - .clk = { - .name = "mmc_bus", - .id = 1, - .ctrlbit = S3C_CLKCON_SCLK_MMC1, - .enable = s3c64xx_sclk_ctrl, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .set_parent = s3c64xx_setparent_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_MMC1_SHIFT, - .mask = S3C6400_CLKSRC_MMC1_MASK, - .sources = &clkset_spi_mmc, - .divider_shift = S3C6400_CLKDIV1_MMC1_SHIFT, - .reg_divider = S3C_CLK_DIV1, -}; - -static struct clksrc_clk clk_mmc2 = { - .clk = { - .name = "mmc_bus", - .id = 2, - .ctrlbit = S3C_CLKCON_SCLK_MMC2, - .enable = s3c64xx_sclk_ctrl, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .set_parent = s3c64xx_setparent_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_MMC2_SHIFT, - .mask = S3C6400_CLKSRC_MMC2_MASK, - .sources = &clkset_spi_mmc, - .divider_shift = S3C6400_CLKDIV1_MMC2_SHIFT, - .reg_divider = S3C_CLK_DIV1, -}; - -static struct clksrc_clk clk_usbhost = { - .clk = { - .name = "usb-bus-host", - .id = -1, - .ctrlbit = S3C_CLKCON_SCLK_UHOST, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_UHOST_SHIFT, - .mask = S3C6400_CLKSRC_UHOST_MASK, - .sources = &clkset_uhost, - .divider_shift = S3C6400_CLKDIV1_UHOST_SHIFT, - .reg_divider = S3C_CLK_DIV1, -}; - -static struct clksrc_clk clk_uart_uclk1 = { - .clk = { - .name = "uclk1", - .id = -1, - .ctrlbit = S3C_CLKCON_SCLK_UART, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_UART_SHIFT, - .mask = S3C6400_CLKSRC_UART_MASK, - .sources = &clkset_uart, - .divider_shift = S3C6400_CLKDIV2_UART_SHIFT, - .reg_divider = S3C_CLK_DIV2, -}; - -/* Where does UCLK0 come from? */ - -static struct clksrc_clk clk_spi0 = { - .clk = { - .name = "spi-bus", - .id = 0, - .ctrlbit = S3C_CLKCON_SCLK_SPI0, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_SPI0_SHIFT, - .mask = S3C6400_CLKSRC_SPI0_MASK, - .sources = &clkset_spi_mmc, - .divider_shift = S3C6400_CLKDIV2_SPI0_SHIFT, - .reg_divider = S3C_CLK_DIV2, -}; - -static struct clksrc_clk clk_spi1 = { - .clk = { - .name = "spi-bus", - .id = 1, - .ctrlbit = S3C_CLKCON_SCLK_SPI1, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_SPI1_SHIFT, - .mask = S3C6400_CLKSRC_SPI1_MASK, - .sources = &clkset_spi_mmc, - .divider_shift = S3C6400_CLKDIV2_SPI1_SHIFT, - .reg_divider = S3C_CLK_DIV2, -}; +/* clocks that feed other parts of the clock source tree */ static struct clk clk_iis_cd0 = { .name = "iis_cdclk0", @@ -509,29 +278,11 @@ static struct clk *clkset_audio0_list[] = { [4] = &clk_pcm_cd, }; -static struct clk_sources clkset_audio0 = { +static struct clksrc_sources clkset_audio0 = { .sources = clkset_audio0_list, .nr_sources = ARRAY_SIZE(clkset_audio0_list), }; -static struct clksrc_clk clk_audio0 = { - .clk = { - .name = "audio-bus", - .id = 0, - .ctrlbit = S3C_CLKCON_SCLK_AUDIO0, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_AUDIO0_SHIFT, - .mask = S3C6400_CLKSRC_AUDIO0_MASK, - .sources = &clkset_audio0, - .divider_shift = S3C6400_CLKDIV2_AUDIO0_SHIFT, - .reg_divider = S3C_CLK_DIV2, -}; - static struct clk *clkset_audio1_list[] = { [0] = &clk_mout_epll.clk, [1] = &clk_dout_mpll, @@ -540,72 +291,133 @@ static struct clk *clkset_audio1_list[] = { [4] = &clk_pcm_cd, }; -static struct clk_sources clkset_audio1 = { +static struct clksrc_sources clkset_audio1 = { .sources = clkset_audio1_list, .nr_sources = ARRAY_SIZE(clkset_audio1_list), }; -static struct clksrc_clk clk_audio1 = { - .clk = { - .name = "audio-bus", - .id = 1, - .ctrlbit = S3C_CLKCON_SCLK_AUDIO1, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_AUDIO1_SHIFT, - .mask = S3C6400_CLKSRC_AUDIO1_MASK, - .sources = &clkset_audio1, - .divider_shift = S3C6400_CLKDIV2_AUDIO1_SHIFT, - .reg_divider = S3C_CLK_DIV2, -}; - -static struct clksrc_clk clk_irda = { - .clk = { - .name = "irda-bus", - .id = 0, - .ctrlbit = S3C_CLKCON_SCLK_IRDA, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, - }, - .shift = S3C6400_CLKSRC_IRDA_SHIFT, - .mask = S3C6400_CLKSRC_IRDA_MASK, - .sources = &clkset_irda, - .divider_shift = S3C6400_CLKDIV2_IRDA_SHIFT, - .reg_divider = S3C_CLK_DIV2, -}; - static struct clk *clkset_camif_list[] = { &clk_h2, }; -static struct clk_sources clkset_camif = { +static struct clksrc_sources clkset_camif = { .sources = clkset_camif_list, .nr_sources = ARRAY_SIZE(clkset_camif_list), }; -static struct clksrc_clk clk_camif = { - .clk = { - .name = "camera", - .id = -1, - .ctrlbit = S3C_CLKCON_SCLK_CAM, - .enable = s3c64xx_sclk_ctrl, - .set_parent = s3c64xx_setparent_clksrc, - .get_rate = s3c64xx_getrate_clksrc, - .set_rate = s3c64xx_setrate_clksrc, - .round_rate = s3c64xx_roundrate_clksrc, +static struct clksrc_clk clksrcs[] = { + { + .clk = { + .name = "mmc_bus", + .id = 0, + .ctrlbit = S3C_CLKCON_SCLK_MMC0, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 }, + .sources = &clkset_spi_mmc, + }, { + .clk = { + .name = "mmc_bus", + .id = 1, + .ctrlbit = S3C_CLKCON_SCLK_MMC1, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 }, + .sources = &clkset_spi_mmc, + }, { + .clk = { + .name = "mmc_bus", + .id = 2, + .ctrlbit = S3C_CLKCON_SCLK_MMC2, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 }, + .sources = &clkset_spi_mmc, + }, { + .clk = { + .name = "usb-bus-host", + .id = -1, + .ctrlbit = S3C_CLKCON_SCLK_UHOST, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 5, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 }, + .sources = &clkset_uhost, + }, { + .clk = { + .name = "uclk1", + .id = -1, + .ctrlbit = S3C_CLKCON_SCLK_UART, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 }, + .sources = &clkset_uart, + }, { +/* Where does UCLK0 come from? */ + .clk = { + .name = "spi-bus", + .id = 0, + .ctrlbit = S3C_CLKCON_SCLK_SPI0, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 }, + .sources = &clkset_spi_mmc, + }, { + .clk = { + .name = "spi-bus", + .id = 1, + .ctrlbit = S3C_CLKCON_SCLK_SPI1, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 }, + .sources = &clkset_spi_mmc, + }, { + .clk = { + .name = "audio-bus", + .id = 0, + .ctrlbit = S3C_CLKCON_SCLK_AUDIO0, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 7, .size = 3 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4 }, + .sources = &clkset_audio0, + }, { + .clk = { + .name = "audio-bus", + .id = 1, + .ctrlbit = S3C_CLKCON_SCLK_AUDIO1, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4 }, + .sources = &clkset_audio1, + }, { + .clk = { + .name = "irda-bus", + .id = 0, + .ctrlbit = S3C_CLKCON_SCLK_IRDA, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 24, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4 }, + .sources = &clkset_irda, + }, { + .clk = { + .name = "camera", + .id = -1, + .ctrlbit = S3C_CLKCON_SCLK_CAM, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_div = { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4 }, + .reg_src = { .reg = NULL, .shift = 0, .size = 0 }, + .sources = &clkset_camif, }, - .shift = 0, - .mask = 0, - .sources = &clkset_camif, - .divider_shift = S3C6400_CLKDIV0_CAM_SHIFT, - .reg_divider = S3C_CLK_DIV0, }; /* Clock initialisation code */ @@ -614,39 +426,7 @@ static struct clksrc_clk *init_parents[] = { &clk_mout_apll, &clk_mout_epll, &clk_mout_mpll, - &clk_mmc0, - &clk_mmc1, - &clk_mmc2, - &clk_usbhost, - &clk_uart_uclk1, - &clk_spi0, - &clk_spi1, - &clk_audio0, - &clk_audio1, - &clk_irda, - &clk_camif, -}; - -static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk) -{ - struct clk_sources *srcs = clk->sources; - u32 clksrc = __raw_readl(S3C_CLK_SRC); - - clksrc &= clk->mask; - clksrc >>= clk->shift; - - if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) { - printk(KERN_ERR "%s: bad source %d\n", - clk->clk.name, clksrc); - return; - } - - clk->clk.parent = srcs->sources[clksrc]; - - printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n", - clk->clk.name, clk->clk.parent->name, clksrc, - clk_get_rate(&clk->clk)); -} +}; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) @@ -706,7 +486,10 @@ void __init_or_cpufreq s3c6400_setup_clocks(void) clk_f.rate = fclk; for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) - s3c6400_set_clksrc(init_parents[ptr]); + s3c_set_clksrc(init_parents[ptr], true); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_set_clksrc(&clksrcs[ptr], true); } static struct clk *clks[] __initdata = { @@ -715,20 +498,8 @@ static struct clk *clks[] __initdata = { &clk_iis_cd1, &clk_pcm_cd, &clk_mout_epll.clk, - &clk_fout_epll, &clk_mout_mpll.clk, &clk_dout_mpll, - &clk_mmc0.clk, - &clk_mmc1.clk, - &clk_mmc2.clk, - &clk_usbhost.clk, - &clk_uart_uclk1.clk, - &clk_spi0.clk, - &clk_spi1.clk, - &clk_audio0.clk, - &clk_audio1.clk, - &clk_irda.clk, - &clk_camif.clk, &clk_arm, }; @@ -761,6 +532,5 @@ void __init s3c6400_register_clocks(unsigned armclk_divlimit) } } - clk_mpll.parent = &clk_mout_mpll.clk; - clk_epll.parent = &clk_mout_epll.clk; + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); } diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig new file mode 100644 index 00000000000..e7c31e7060e --- /dev/null +++ b/arch/arm/plat-s5p/Kconfig @@ -0,0 +1,42 @@ +# arch/arm/plat-s5p/Kconfig +# +# Copyright (c) 2009 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Licensed under GPLv2 + +config PLAT_S5P + bool + depends on ARCH_S5P6440 + default y + select PLAT_S3C + select ARM_VIC + select NO_IOPORT + select ARCH_REQUIRE_GPIOLIB + select S3C_GPIO_TRACK + select SAMSUNG_GPIOLIB_4BIT + select S3C_GPIO_CFG_S3C64XX + select S3C_GPIO_PULL_UPDOWN + select S3C_GPIO_CFG_S3C24XX + select PLAT_SAMSUNG + select SAMSUNG_CLKSRC + select SAMSUNG_IRQ_VIC_TIMER + select SAMSUNG_IRQ_UART + help + Base platform code for Samsung's S5P series SoC. + +if (PLAT_S5P && ARCH_S5P6440) + +# Configuration options shared by all S5P64XX implementations + +config CPU_S5P6440_INIT + bool + help + Initialisation code for the S5P6440. + +config CPU_S5P6440_CLOCK + bool + help + Clock support code for the S5P6440. + +endif diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile new file mode 100644 index 00000000000..92b64745054 --- /dev/null +++ b/arch/arm/plat-s5p/Makefile @@ -0,0 +1,24 @@ +# arch/arm/plat-s5p/Makefile +# +# Copyright (c) 2009 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Licensed under GPLv2 + +obj-y := +obj-m := +obj-n := dummy.o +obj- := + +# Core files + +obj-y += dev-uart.o +obj-y += cpu.o +obj-y += clock.o +obj-y += irq.o +obj-y += setup-i2c0.o + +# CPU support + +obj-$(CONFIG_CPU_S5P6440_INIT) += s5p6440-init.o +obj-$(CONFIG_CPU_S5P6440_CLOCK) += s5p6440-clock.o diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c new file mode 100644 index 00000000000..3d3c0f1934f --- /dev/null +++ b/arch/arm/plat-s5p/clock.c @@ -0,0 +1,136 @@ +/* linux/arch/arm/plat-s5p/clock.c + * + * Copyright 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Common clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/sysdev.h> +#include <linux/io.h> +#include <asm/div64.h> + +#include <plat/clock.h> +#include <plat/clock-clksrc.h> +#include <plat/s5p-clock.h> + +/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call + * clk_ext_xtal_mux. +*/ +struct clk clk_ext_xtal_mux = { + .name = "ext_xtal", + .id = -1, +}; + +/* 48MHz USB Phy clock output */ +struct clk clk_48m = { + .name = "clk_48m", + .id = -1, + .rate = 48000000, +}; + +/* APLL clock output + * No need .ctrlbit, this is always on +*/ +struct clk clk_fout_apll = { + .name = "fout_apll", + .id = -1, +}; + +/* MPLL clock output + * No need .ctrlbit, this is always on +*/ +struct clk clk_fout_mpll = { + .name = "fout_mpll", + .id = -1, +}; + +/* EPLL clock output */ +struct clk clk_fout_epll = { + .name = "fout_epll", + .id = -1, + .ctrlbit = (1 << 31), +}; + +/* ARM clock */ +struct clk clk_arm = { + .name = "armclk", + .id = -1, + .rate = 0, + .ctrlbit = 0, +}; + +/* Possible clock sources for APLL Mux */ +static struct clk *clk_src_apll_list[] = { + [0] = &clk_fin_apll, + [1] = &clk_fout_apll, +}; + +struct clksrc_sources clk_src_apll = { + .sources = clk_src_apll_list, + .nr_sources = ARRAY_SIZE(clk_src_apll_list), +}; + +/* Possible clock sources for MPLL Mux */ +static struct clk *clk_src_mpll_list[] = { + [0] = &clk_fin_mpll, + [1] = &clk_fout_mpll, +}; + +struct clksrc_sources clk_src_mpll = { + .sources = clk_src_mpll_list, + .nr_sources = ARRAY_SIZE(clk_src_mpll_list), +}; + +/* Possible clock sources for EPLL Mux */ +static struct clk *clk_src_epll_list[] = { + [0] = &clk_fin_epll, + [1] = &clk_fout_epll, +}; + +struct clksrc_sources clk_src_epll = { + .sources = clk_src_epll_list, + .nr_sources = ARRAY_SIZE(clk_src_epll_list), +}; + +int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + u32 con; + + con = __raw_readl(reg); + con = enable ? (con | ctrlbit) : (con & ~ctrlbit); + __raw_writel(con, reg); + return 0; +} + +static struct clk *s5p_clks[] __initdata = { + &clk_ext_xtal_mux, + &clk_48m, + &clk_fout_apll, + &clk_fout_mpll, + &clk_fout_epll, + &clk_arm, +}; + +void __init s5p_register_clocks(unsigned long xtal_freq) +{ + int ret; + + clk_ext_xtal_mux.rate = xtal_freq; + + ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks)); + if (ret > 0) + printk(KERN_ERR "Failed to register s5p clocks\n"); +} diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c new file mode 100644 index 00000000000..0895a77a283 --- /dev/null +++ b/arch/arm/plat-s5p/cpu.c @@ -0,0 +1,90 @@ +/* linux/arch/arm/plat-s5p/cpu.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P CPU Support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <mach/map.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <mach/regs-clock.h> +#include <plat/cpu.h> +#include <plat/s5p6440.h> + +/* table of supported CPUs */ + +static const char name_s5p6440[] = "S5P6440"; + +static struct cpu_table cpu_ids[] __initdata = { + { + .idcode = 0x56440100, + .idmask = 0xffffff00, + .map_io = s5p6440_map_io, + .init_clocks = s5p6440_init_clocks, + .init_uarts = s5p6440_init_uarts, + .init = s5p6440_init, + .name = name_s5p6440, + }, +}; + +/* minimal IO mapping */ + +#define UART_OFFS (S5P_PA_UART & 0xfffff) + +static struct map_desc s5p_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_SYSCON, + .pfn = __phys_to_pfn(S5P_PA_SYSCON), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)(S5P_VA_UART + UART_OFFS), + .pfn = __phys_to_pfn(S5P_PA_UART), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_VIC0, + .pfn = __phys_to_pfn(S5P_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_VIC1, + .pfn = __phys_to_pfn(S5P_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_TIMER, + .pfn = __phys_to_pfn(S5P_PA_TIMER), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5P_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +/* read cpu identification code */ + +void __init s5p_init_io(struct map_desc *mach_desc, + int size, void __iomem *cpuid_addr) +{ + unsigned long idcode; + + /* initialize the io descriptors we need for initialization */ + iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc)); + if (mach_desc) + iotable_init(mach_desc, size); + + idcode = __raw_readl(cpuid_addr); + s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); +} diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c new file mode 100644 index 00000000000..23c75316d49 --- /dev/null +++ b/arch/arm/plat-s5p/dev-uart.c @@ -0,0 +1,137 @@ +/* linux/arch/arm/plat-s5p/dev-uart.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Base S5P UART resource and device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/platform_device.h> + +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <mach/hardware.h> +#include <mach/map.h> + +#include <plat/devs.h> + + /* Serial port registrations */ + +static struct resource s5p_uart0_resource[] = { + [0] = { + .start = S5P_PA_UART0, + .end = S5P_PA_UART0 + S5P_SZ_UART, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S5P_UART_RX0, + .end = IRQ_S5P_UART_RX0, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_S5P_UART_TX0, + .end = IRQ_S5P_UART_TX0, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_S5P_UART_ERR0, + .end = IRQ_S5P_UART_ERR0, + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource s5p_uart1_resource[] = { + [0] = { + .start = S5P_PA_UART1, + .end = S5P_PA_UART1 + S5P_SZ_UART, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S5P_UART_RX1, + .end = IRQ_S5P_UART_RX1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_S5P_UART_TX1, + .end = IRQ_S5P_UART_TX1, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_S5P_UART_ERR1, + .end = IRQ_S5P_UART_ERR1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource s5p_uart2_resource[] = { + [0] = { + .start = S5P_PA_UART2, + .end = S5P_PA_UART2 + S5P_SZ_UART, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S5P_UART_RX2, + .end = IRQ_S5P_UART_RX2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_S5P_UART_TX2, + .end = IRQ_S5P_UART_TX2, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_S5P_UART_ERR2, + .end = IRQ_S5P_UART_ERR2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource s5p_uart3_resource[] = { + [0] = { + .start = S5P_PA_UART3, + .end = S5P_PA_UART3 + S5P_SZ_UART, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S5P_UART_RX3, + .end = IRQ_S5P_UART_RX3, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_S5P_UART_TX3, + .end = IRQ_S5P_UART_TX3, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_S5P_UART_ERR3, + .end = IRQ_S5P_UART_ERR3, + .flags = IORESOURCE_IRQ, + }, +}; + +struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { + [0] = { + .resources = s5p_uart0_resource, + .nr_resources = ARRAY_SIZE(s5p_uart0_resource), + }, + [1] = { + .resources = s5p_uart1_resource, + .nr_resources = ARRAY_SIZE(s5p_uart1_resource), + }, + [2] = { + .resources = s5p_uart2_resource, + .nr_resources = ARRAY_SIZE(s5p_uart2_resource), + }, + [3] = { + .resources = s5p_uart3_resource, + .nr_resources = ARRAY_SIZE(s5p_uart3_resource), + }, +}; diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h new file mode 100644 index 00000000000..5d7937dddad --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/irqs.h @@ -0,0 +1,83 @@ +/* linux/arch/arm/plat-s5p/include/plat/irqs.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P Common IRQ support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_S5P_IRQS_H +#define __ASM_PLAT_S5P_IRQS_H __FILE__ + +/* we keep the first set of CPU IRQs out of the range of + * the ISA space, so that the PC104 has them to itself + * and we don't end up having to do horrible things to the + * standard ISA drivers.... + * + * note, since we're using the VICs, our start must be a + * mulitple of 32 to allow the common code to work + */ + +#define S5P_IRQ_OFFSET (32) + +#define S5P_IRQ(x) ((x) + S5P_IRQ_OFFSET) + +#define S5P_VIC0_BASE S5P_IRQ(0) +#define S5P_VIC1_BASE S5P_IRQ(32) + +#define IRQ_VIC0_BASE S5P_VIC0_BASE +#define IRQ_VIC1_BASE S5P_VIC1_BASE + +/* UART interrupts, each UART has 4 intterupts per channel so + * use the space between the ISA and S3C main interrupts. Note, these + * are not in the same order as the S3C24XX series! */ + +#define IRQ_S5P_UART_BASE0 (16) +#define IRQ_S5P_UART_BASE1 (20) +#define IRQ_S5P_UART_BASE2 (24) +#define IRQ_S5P_UART_BASE3 (28) + +#define UART_IRQ_RXD (0) +#define UART_IRQ_ERR (1) +#define UART_IRQ_TXD (2) + +#define IRQ_S5P_UART_RX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_RXD) +#define IRQ_S5P_UART_TX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_TXD) +#define IRQ_S5P_UART_ERR0 (IRQ_S5P_UART_BASE0 + UART_IRQ_ERR) + +#define IRQ_S5P_UART_RX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_RXD) +#define IRQ_S5P_UART_TX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_TXD) +#define IRQ_S5P_UART_ERR1 (IRQ_S5P_UART_BASE1 + UART_IRQ_ERR) + +#define IRQ_S5P_UART_RX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_RXD) +#define IRQ_S5P_UART_TX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_TXD) +#define IRQ_S5P_UART_ERR2 (IRQ_S5P_UART_BASE2 + UART_IRQ_ERR) + +#define IRQ_S5P_UART_RX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_RXD) +#define IRQ_S5P_UART_TX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_TXD) +#define IRQ_S5P_UART_ERR3 (IRQ_S5P_UART_BASE3 + UART_IRQ_ERR) + +/* S3C compatibilty defines */ +#define IRQ_S3CUART_RX0 IRQ_S5P_UART_RX0 +#define IRQ_S3CUART_RX1 IRQ_S5P_UART_RX1 +#define IRQ_S3CUART_RX2 IRQ_S5P_UART_RX2 +#define IRQ_S3CUART_RX3 IRQ_S5P_UART_RX3 + +/* VIC based IRQs */ + +#define S5P_IRQ_VIC0(x) (S5P_VIC0_BASE + (x)) +#define S5P_IRQ_VIC1(x) (S5P_VIC1_BASE + (x)) + +#define S5P_TIMER_IRQ(x) S5P_IRQ(64 + (x)) + +#define IRQ_TIMER0 S5P_TIMER_IRQ(0) +#define IRQ_TIMER1 S5P_TIMER_IRQ(1) +#define IRQ_TIMER2 S5P_TIMER_IRQ(2) +#define IRQ_TIMER3 S5P_TIMER_IRQ(3) +#define IRQ_TIMER4 S5P_TIMER_IRQ(4) + +#endif /* __ASM_PLAT_S5P_IRQS_H */ diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h new file mode 100644 index 00000000000..d48325bb29e --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/pll.h @@ -0,0 +1,83 @@ +/* arch/arm/plat-s5p/include/plat/pll.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P PLL code + * + * Based on arch/arm/plat-s3c64xx/include/plat/pll.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. +*/ + +#define PLL45XX_MDIV_MASK (0x3FF) +#define PLL45XX_PDIV_MASK (0x3F) +#define PLL45XX_SDIV_MASK (0x7) +#define PLL45XX_MDIV_SHIFT (16) +#define PLL45XX_PDIV_SHIFT (8) +#define PLL45XX_SDIV_SHIFT (0) + +#include <asm/div64.h> + +enum pll45xx_type_t { + pll_4500, + pll_4502, + pll_4508 +}; + +static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con, + enum pll45xx_type_t pll_type) +{ + u32 mdiv, pdiv, sdiv; + u64 fvco = baseclk; + + mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK; + pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK; + sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK; + + if (pll_type == pll_4508) + sdiv = sdiv - 1; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +#define PLL90XX_MDIV_MASK (0xFF) +#define PLL90XX_PDIV_MASK (0x3F) +#define PLL90XX_SDIV_MASK (0x7) +#define PLL90XX_KDIV_MASK (0xffff) +#define PLL90XX_MDIV_SHIFT (16) +#define PLL90XX_PDIV_SHIFT (8) +#define PLL90XX_SDIV_SHIFT (0) +#define PLL90XX_KDIV_SHIFT (0) + +static inline unsigned long s5p_get_pll90xx(unsigned long baseclk, + u32 pll_con, u32 pll_conk) +{ + unsigned long result; + u32 mdiv, pdiv, sdiv, kdiv; + u64 tmp; + + mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK; + pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK; + sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK; + kdiv = pll_conk & PLL90XX_KDIV_MASK; + + /* We need to multiple baseclk by mdiv (the integer part) and kdiv + * which is in 2^16ths, so shift mdiv up (does not overflow) and + * add kdiv before multiplying. The use of tmp is to avoid any + * overflows before shifting bac down into result when multipling + * by the mdiv and kdiv pair. + */ + + tmp = baseclk; + tmp *= (mdiv << 16) + kdiv; + do_div(tmp, (pdiv << sdiv)); + result = tmp >> 16; + + return result; +} diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h new file mode 100644 index 00000000000..e1a7444b882 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h @@ -0,0 +1,38 @@ +/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h + * + * Copyright 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Header file for s5p clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_PLAT_S5P_CLOCK_H +#define __ASM_PLAT_S5P_CLOCK_H __FILE__ + +#include <linux/clk.h> + +#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) + +#define clk_fin_apll clk_ext_xtal_mux +#define clk_fin_mpll clk_ext_xtal_mux +#define clk_fin_epll clk_ext_xtal_mux + +extern struct clk clk_ext_xtal_mux; +extern struct clk clk_48m; +extern struct clk clk_fout_apll; +extern struct clk clk_fout_mpll; +extern struct clk clk_fout_epll; +extern struct clk clk_arm; + +extern struct clksrc_sources clk_src_apll; +extern struct clksrc_sources clk_src_mpll; +extern struct clksrc_sources clk_src_epll; + +extern int s5p6440_clk48m_ctrl(struct clk *clk, int enable); +extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); + +#endif /* __ASM_PLAT_S5P_CLOCK_H */ diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h new file mode 100644 index 00000000000..a4cd75afeb3 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p6440.h @@ -0,0 +1,37 @@ +/* arch/arm/plat-s5p/include/plat/s5p6440.h + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * Header file for s5p6440 cpu support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + + /* Common init code for S5P6440 related SoCs */ + +extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); +extern void s5p6440_register_clocks(void); +extern void s5p6440_setup_clocks(void); + +#ifdef CONFIG_CPU_S5P6440 + +extern int s5p6440_init(void); +extern void s5p6440_init_irq(void); +extern void s5p6440_map_io(void); +extern void s5p6440_init_clocks(int xtal); + +#define s5p6440_init_uarts s5p6440_common_init_uarts + +#else +#define s5p6440_init_clocks NULL +#define s5p6440_init_uarts NULL +#define s5p6440_map_io NULL +#define s5p6440_init NULL +#endif + +/* S5P6440 timer */ + +extern struct sys_timer s5p6440_timer; diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c new file mode 100644 index 00000000000..eada40d0847 --- /dev/null +++ b/arch/arm/plat-s5p/irq.c @@ -0,0 +1,73 @@ +/* arch/arm/plat-s5p/irq.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P - Interrupt handling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <asm/hardware/vic.h> + +#include <linux/serial_core.h> +#include <mach/map.h> +#include <plat/regs-timer.h> +#include <plat/regs-serial.h> +#include <plat/cpu.h> +#include <plat/irq-vic-timer.h> +#include <plat/irq-uart.h> + +#define VIC_VAADDR(no) (S5P_VA_VIC0 + ((no)*0x10000)) +#define VIC_BASE(no) (S5P_VIC0_BASE + ((no)*32)) + +/* + * Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] + * are consecutive when looking up the interrupt in the demux routines. + */ +static struct s3c_uart_irq uart_irqs[] = { + [0] = { + .regs = S5P_VA_UART0, + .base_irq = IRQ_S5P_UART_BASE0, + .parent_irq = IRQ_UART0, + }, + [1] = { + .regs = S5P_VA_UART1, + .base_irq = IRQ_S5P_UART_BASE1, + .parent_irq = IRQ_UART1, + }, + [2] = { + .regs = S5P_VA_UART2, + .base_irq = IRQ_S5P_UART_BASE2, + .parent_irq = IRQ_UART2, + }, + [3] = { + .regs = S5P_VA_UART3, + .base_irq = IRQ_S5P_UART_BASE3, + .parent_irq = IRQ_UART3, + }, +}; + +void __init s5p_init_irq(u32 *vic, u32 num_vic) +{ + int irq; + + /* initialize the VICs */ + for (irq = 0; irq < num_vic; irq++) + vic_init(VIC_VAADDR(irq), VIC_BASE(irq), vic[irq], 0); + + s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0); + s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1); + s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2); + s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3); + s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4); + + s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); +} diff --git a/arch/arm/plat-s5p/s5p6440-clock.c b/arch/arm/plat-s5p/s5p6440-clock.c new file mode 100644 index 00000000000..2f412f8c121 --- /dev/null +++ b/arch/arm/plat-s5p/s5p6440-clock.c @@ -0,0 +1,698 @@ +/* linux/arch/arm/plat-s5p/s5p6440-clock.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * S5P6440 - Clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/sysdev.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/map.h> + +#include <plat/cpu-freq.h> +#include <mach/regs-clock.h> +#include <plat/clock.h> +#include <plat/cpu.h> +#include <plat/clock-clksrc.h> +#include <plat/s5p-clock.h> +#include <plat/pll.h> +#include <plat/s5p6440.h> + +/* APLL Mux output clock */ +static struct clksrc_clk clk_mout_apll = { + .clk = { + .name = "mout_apll", + .id = -1, + }, + .sources = &clk_src_apll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, +}; + +static int s5p6440_epll_enable(struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; + + if (enable) + __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); + else + __raw_writel(epll_con, S5P_EPLL_CON); + + return 0; +} + +static unsigned long s5p6440_epll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +static u32 epll_div[][5] = { + { 36000000, 0, 48, 1, 4 }, + { 48000000, 0, 32, 1, 3 }, + { 60000000, 0, 40, 1, 3 }, + { 72000000, 0, 48, 1, 3 }, + { 84000000, 0, 28, 1, 2 }, + { 96000000, 0, 32, 1, 2 }, + { 32768000, 45264, 43, 1, 4 }, + { 45158000, 6903, 30, 1, 3 }, + { 49152000, 50332, 32, 1, 3 }, + { 67738000, 10398, 45, 1, 3 }, + { 73728000, 9961, 49, 1, 3 } +}; + +static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int epll_con, epll_con_k; + unsigned int i; + + if (clk->rate == rate) /* Return if nothing changed */ + return 0; + + epll_con = __raw_readl(S5P_EPLL_CON); + epll_con_k = __raw_readl(S5P_EPLL_CON_K); + + epll_con_k &= ~(PLL90XX_KDIV_MASK); + epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK); + + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { + if (epll_div[i][0] == rate) { + epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT); + epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) | + (epll_div[i][3] << PLL90XX_PDIV_SHIFT) | + (epll_div[i][4] << PLL90XX_SDIV_SHIFT); + break; + } + } + + if (i == ARRAY_SIZE(epll_div)) { + printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); + return -EINVAL; + } + + __raw_writel(epll_con, S5P_EPLL_CON); + __raw_writel(epll_con_k, S5P_EPLL_CON_K); + + clk->rate = rate; + + return 0; +} + +static struct clk_ops s5p6440_epll_ops = { + .get_rate = s5p6440_epll_get_rate, + .set_rate = s5p6440_epll_set_rate, +}; + +static struct clksrc_clk clk_mout_epll = { + .clk = { + .name = "mout_epll", + .id = -1, + }, + .sources = &clk_src_epll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 2, .size = 1 }, +}; + +static struct clksrc_clk clk_mout_mpll = { + .clk = { + .name = "mout_mpll", + .id = -1, + }, + .sources = &clk_src_mpll, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 }, +}; + +static struct clk clk_h_low = { + .name = "hclk_low", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, + .ops = &clk_ops_def_setrate, +}; + +static struct clk clk_p_low = { + .name = "pclk_low", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, + .ops = &clk_ops_def_setrate, +}; + +enum perf_level { + L0 = 532*1000, + L1 = 266*1000, + L2 = 133*1000, +}; + +static const u32 clock_table[][3] = { + /*{ARM_CLK, DIVarm, DIVhclk}*/ + {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P_CLKDIV0_HCLK_SHIFT)}, + {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P_CLKDIV0_HCLK_SHIFT)}, + {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P_CLKDIV0_HCLK_SHIFT)}, +}; + +static unsigned long s5p6440_armclk_get_rate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + u32 clkdiv; + + /* divisor mask starts at bit0, so no need to shift */ + clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK; + + return rate / (clkdiv + 1); +} + +static unsigned long s5p6440_armclk_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 iter; + + for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) { + if (rate > clock_table[iter][0]) + return clock_table[iter-1][0]; + } + + return clock_table[ARRAY_SIZE(clock_table) - 1][0]; +} + +static int s5p6440_armclk_set_rate(struct clk *clk, unsigned long rate) +{ + u32 round_tmp; + u32 iter; + u32 clk_div0_tmp; + u32 cur_rate = clk->ops->get_rate(clk); + unsigned long flags; + + round_tmp = clk->ops->round_rate(clk, rate); + if (round_tmp == cur_rate) + return 0; + + + for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) { + if (round_tmp == clock_table[iter][0]) + break; + } + + if (iter >= ARRAY_SIZE(clock_table)) + iter = ARRAY_SIZE(clock_table) - 1; + + local_irq_save(flags); + if (cur_rate > round_tmp) { + /* Frequency Down */ + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); + clk_div0_tmp |= clock_table[iter][1]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & + ~(S5P_CLKDIV0_HCLK_MASK); + clk_div0_tmp |= clock_table[iter][2]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + + } else { + /* Frequency Up */ + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & + ~(S5P_CLKDIV0_HCLK_MASK); + clk_div0_tmp |= clock_table[iter][2]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); + clk_div0_tmp |= clock_table[iter][1]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + } + local_irq_restore(flags); + + clk->rate = clock_table[iter][0]; + + return 0; +} + +static struct clk_ops s5p6440_clkarm_ops = { + .get_rate = s5p6440_armclk_get_rate, + .set_rate = s5p6440_armclk_set_rate, + .round_rate = s5p6440_armclk_round_rate, +}; + +static unsigned long s5p6440_clk_doutmpll_get_rate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + + if (__raw_readl(S5P_CLK_DIV0) & S5P_CLKDIV0_MPLL_MASK) + rate /= 2; + + return rate; +} + +static struct clk clk_dout_mpll = { + .name = "dout_mpll", + .id = -1, + .parent = &clk_mout_mpll.clk, + .ops = &(struct clk_ops) { + .get_rate = s5p6440_clk_doutmpll_get_rate, + }, +}; + +int s5p6440_clk48m_ctrl(struct clk *clk, int enable) +{ + unsigned long flags; + u32 val; + + /* can't rely on clock lock, this register has other usages */ + local_irq_save(flags); + + val = __raw_readl(S5P_OTHERS); + if (enable) + val |= S5P_OTHERS_USB_SIG_MASK; + else + val &= ~S5P_OTHERS_USB_SIG_MASK; + + __raw_writel(val, S5P_OTHERS); + + local_irq_restore(flags); + + return 0; +} + +static int s5p6440_pclk_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLK_GATE_PCLK, clk, enable); +} + +static int s5p6440_hclk0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLK_GATE_HCLK0, clk, enable); +} + +static int s5p6440_hclk1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLK_GATE_HCLK1, clk, enable); +} + +static int s5p6440_sclk_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable); +} + +static int s5p6440_mem_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable); +} + +/* + * The following clocks will be disabled during clock initialization. It is + * recommended to keep the following clocks disabled until the driver requests + * for enabling the clock. + */ +static struct clk init_clocks_disable[] = { + { + .name = "nand", + .id = -1, + .parent = &clk_h, + .enable = s5p6440_mem_ctrl, + .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON, + }, { + .name = "adc", + .id = -1, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_TSADC, + }, { + .name = "i2c", + .id = -1, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_IIC0, + }, { + .name = "i2s_v40", + .id = 0, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_IIS2, + }, { + .name = "spi", + .id = 0, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_SPI0, + }, { + .name = "spi", + .id = 1, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_SPI1, + }, { + .name = "sclk_spi_48", + .id = 0, + .parent = &clk_48m, + .enable = s5p6440_sclk_ctrl, + .ctrlbit = S5P_CLKCON_SCLK0_SPI0_48, + }, { + .name = "sclk_spi_48", + .id = 1, + .parent = &clk_48m, + .enable = s5p6440_sclk_ctrl, + .ctrlbit = S5P_CLKCON_SCLK0_SPI1_48, + }, { + .name = "mmc_48m", + .id = 0, + .parent = &clk_48m, + .enable = s5p6440_sclk_ctrl, + .ctrlbit = S5P_CLKCON_SCLK0_MMC0_48, + }, { + .name = "mmc_48m", + .id = 1, + .parent = &clk_48m, + .enable = s5p6440_sclk_ctrl, + .ctrlbit = S5P_CLKCON_SCLK0_MMC1_48, + }, { + .name = "mmc_48m", + .id = 2, + .parent = &clk_48m, + .enable = s5p6440_sclk_ctrl, + .ctrlbit = S5P_CLKCON_SCLK0_MMC2_48, + }, { + .name = "otg", + .id = -1, + .parent = &clk_h_low, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = S5P_CLKCON_HCLK0_USB + }, { + .name = "post", + .id = -1, + .parent = &clk_h_low, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = S5P_CLKCON_HCLK0_POST0 + }, { + .name = "lcd", + .id = -1, + .parent = &clk_h_low, + .enable = s5p6440_hclk1_ctrl, + .ctrlbit = S5P_CLKCON_HCLK1_DISPCON, + }, { + .name = "hsmmc", + .id = 0, + .parent = &clk_h_low, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0, + }, { + .name = "hsmmc", + .id = 1, + .parent = &clk_h_low, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1, + }, { + .name = "hsmmc", + .id = 2, + .parent = &clk_h_low, + .enable = s5p6440_hclk0_ctrl, + .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2, + }, { + .name = "rtc", + .id = -1, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_RTC, + }, { + .name = "watchdog", + .id = -1, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_WDT, + }, { + .name = "timers", + .id = -1, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_PWM, + } +}; + +/* + * The following clocks will be enabled during clock initialization. + */ +static struct clk init_clocks[] = { + { + .name = "gpio", + .id = -1, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_GPIO, + }, { + .name = "uart", + .id = 0, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_UART0, + }, { + .name = "uart", + .id = 1, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_UART1, + }, { + .name = "uart", + .id = 2, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_UART2, + }, { + .name = "uart", + .id = 3, + .parent = &clk_p_low, + .enable = s5p6440_pclk_ctrl, + .ctrlbit = S5P_CLKCON_PCLK_UART3, + } +}; + +static struct clk clk_iis_cd_v40 = { + .name = "iis_cdclk_v40", + .id = -1, +}; + +static struct clk clk_pcm_cd = { + .name = "pcm_cdclk", + .id = -1, +}; + +static struct clk *clkset_spi_mmc_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll, + &clk_fin_epll, +}; + +static struct clksrc_sources clkset_spi_mmc = { + .sources = clkset_spi_mmc_list, + .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list), +}; + +static struct clk *clkset_uart_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll +}; + +static struct clksrc_sources clkset_uart = { + .sources = clkset_uart_list, + .nr_sources = ARRAY_SIZE(clkset_uart_list), +}; + +static struct clksrc_clk clksrcs[] = { + { + .clk = { + .name = "mmc_bus", + .id = 0, + .ctrlbit = S5P_CLKCON_SCLK0_MMC0, + .enable = s5p6440_sclk_ctrl, + }, + .sources = &clkset_spi_mmc, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 1, + .ctrlbit = S5P_CLKCON_SCLK0_MMC1, + .enable = s5p6440_sclk_ctrl, + }, + .sources = &clkset_spi_mmc, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 2, + .ctrlbit = S5P_CLKCON_SCLK0_MMC2, + .enable = s5p6440_sclk_ctrl, + }, + .sources = &clkset_spi_mmc, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = -1, + .ctrlbit = S5P_CLKCON_SCLK0_UART, + .enable = s5p6440_sclk_ctrl, + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 13, .size = 1 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "spi_epll", + .id = 0, + .ctrlbit = S5P_CLKCON_SCLK0_SPI0, + .enable = s5p6440_sclk_ctrl, + }, + .sources = &clkset_spi_mmc, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "spi_epll", + .id = 1, + .ctrlbit = S5P_CLKCON_SCLK0_SPI1, + .enable = s5p6440_sclk_ctrl, + }, + .sources = &clkset_spi_mmc, + .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, + } +}; + +/* Clock initialisation code */ +static struct clksrc_clk *init_parents[] = { + &clk_mout_apll, + &clk_mout_epll, + &clk_mout_mpll, +}; + +void __init_or_cpufreq s5p6440_setup_clocks(void) +{ + struct clk *xtal_clk; + unsigned long xtal; + unsigned long fclk; + unsigned long hclk; + unsigned long hclk_low; + unsigned long pclk; + unsigned long pclk_low; + unsigned long epll; + unsigned long apll; + unsigned long mpll; + unsigned int ptr; + u32 clkdiv0; + u32 clkdiv3; + + /* Set S5P6440 functions for clk_fout_epll */ + clk_fout_epll.enable = s5p6440_epll_enable; + clk_fout_epll.ops = &s5p6440_epll_ops; + + /* Set S5P6440 functions for arm clock */ + clk_arm.parent = &clk_mout_apll.clk; + clk_arm.ops = &s5p6440_clkarm_ops; + clk_48m.enable = s5p6440_clk48m_ctrl; + + clkdiv0 = __raw_readl(S5P_CLK_DIV0); + clkdiv3 = __raw_readl(S5P_CLK_DIV3); + + xtal_clk = clk_get(NULL, "ext_xtal"); + BUG_ON(IS_ERR(xtal_clk)); + + xtal = clk_get_rate(xtal_clk); + clk_put(xtal_clk); + + epll = s5p_get_pll90xx(xtal, __raw_readl(S5P_EPLL_CON), + __raw_readl(S5P_EPLL_CON_K)); + mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); + apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502); + + printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ + " E=%ld.%ldMHz\n", + print_mhz(apll), print_mhz(mpll), print_mhz(epll)); + + fclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_ARM); + hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK); + pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK); + + if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) { + /* Asynchronous mode */ + hclk_low = mpll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW); + } else { + /* Synchronous mode */ + hclk_low = apll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW); + } + + pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW); + + printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ + " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", + print_mhz(hclk), print_mhz(hclk_low), + print_mhz(pclk), print_mhz(pclk_low)); + + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + clk_fout_apll.rate = apll; + + clk_f.rate = fclk; + clk_h.rate = hclk; + clk_p.rate = pclk; + clk_h_low.rate = hclk_low; + clk_p_low.rate = pclk_low; + + for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) + s3c_set_clksrc(init_parents[ptr], true); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_set_clksrc(&clksrcs[ptr], true); +} + +static struct clk *clks[] __initdata = { + &clk_ext, + &clk_mout_epll.clk, + &clk_mout_mpll.clk, + &clk_dout_mpll, + &clk_iis_cd_v40, + &clk_pcm_cd, + &clk_p_low, + &clk_h_low, +}; + +void __init s5p6440_register_clocks(void) +{ + struct clk *clkp; + int ret; + int ptr; + + ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); + if (ret > 0) + printk(KERN_ERR "Failed to register %u clocks\n", ret); + + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + + clkp = init_clocks_disable; + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + (clkp->enable)(clkp, 0); + } + + s3c_pwmclk_init(); +} diff --git a/arch/arm/plat-s5p/s5p6440-init.c b/arch/arm/plat-s5p/s5p6440-init.c new file mode 100644 index 00000000000..90178256cc2 --- /dev/null +++ b/arch/arm/plat-s5p/s5p6440-init.c @@ -0,0 +1,50 @@ +/* linux/arch/arm/plat-s5p/s5p6440-init.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/serial_core.h> + +#include <plat/cpu.h> +#include <plat/devs.h> +#include <plat/s5p6440.h> +#include <plat/regs-serial.h> + +static struct s3c24xx_uart_clksrc s5p6440_serial_clocks[] = { + [0] = { + .name = "pclk_low", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, + [1] = { + .name = "uclk1", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, +}; + +/* uart registration process */ +void __init s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + struct s3c2410_uartcfg *tcfg = cfg; + u32 ucnt; + + for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { + if (!tcfg->clocks) { + tcfg->clocks = s5p6440_serial_clocks; + tcfg->clocks_size = ARRAY_SIZE(s5p6440_serial_clocks); + } + } + + s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); +} diff --git a/arch/arm/plat-s5p/setup-i2c0.c b/arch/arm/plat-s5p/setup-i2c0.c new file mode 100644 index 00000000000..67a66e02a97 --- /dev/null +++ b/arch/arm/plat-s5p/setup-i2c0.c @@ -0,0 +1,25 @@ +/* linux/arch/arm/plat-s5p/setup-i2c0.c + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * I2C0 GPIO configuration. + * + * Based on plat-s3c64xx/setup-i2c0.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> + +struct platform_device; /* don't need the contents */ + +#include <plat/iic.h> + +void s3c_i2c0_cfg_gpio(struct platform_device *dev) +{ + /* Will be populated later */ +} diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig index b7b9e91c024..c7ccdf22eef 100644 --- a/arch/arm/plat-s5pc1xx/Kconfig +++ b/arch/arm/plat-s5pc1xx/Kconfig @@ -11,6 +11,9 @@ config PLAT_S5PC1XX select ARM_VIC select NO_IOPORT select ARCH_REQUIRE_GPIOLIB + select SAMSUNG_CLKSRC + select SAMSUNG_IRQ_UART + select SAMSUNG_IRQ_VIC_TIMER select S3C_GPIO_TRACK select S3C_GPIO_PULL_UPDOWN select S3C_GPIO_CFG_S3C24XX diff --git a/arch/arm/plat-s5pc1xx/clock.c b/arch/arm/plat-s5pc1xx/clock.c index 26c21d84979..387f23190c3 100644 --- a/arch/arm/plat-s5pc1xx/clock.c +++ b/arch/arm/plat-s5pc1xx/clock.c @@ -64,25 +64,13 @@ struct clk clk_54m = { .rate = 54000000, }; -static int clk_default_setrate(struct clk *clk, unsigned long rate) -{ - clk->rate = rate; - return 0; -} - -static int clk_dummy_enable(struct clk *clk, int enable) -{ - return 0; -} - struct clk clk_hd0 = { .name = "hclkd0", .id = -1, .rate = 0, .parent = NULL, .ctrlbit = 0, - .set_rate = clk_default_setrate, - .enable = clk_dummy_enable, + .ops = &clk_ops_def_setrate, }; struct clk clk_pd0 = { @@ -91,8 +79,7 @@ struct clk clk_pd0 = { .rate = 0, .parent = NULL, .ctrlbit = 0, - .set_rate = clk_default_setrate, - .enable = clk_dummy_enable, + .ops = &clk_ops_def_setrate, }; static int s5pc1xx_clk_gate(void __iomem *reg, struct clk *clk, int enable) @@ -686,6 +673,8 @@ static struct clk s5pc100_init_clocks[] = { static struct clk *clks[] __initdata = { &clk_ext, &clk_epll, + &clk_pd0, + &clk_hd0, &clk_27m, &clk_48m, &clk_54m, @@ -700,16 +689,8 @@ void __init s5pc1xx_register_clocks(void) s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - clkp = s5pc100_init_clocks; - size = ARRAY_SIZE(s5pc100_init_clocks); - - for (ptr = 0; ptr < size; ptr++, clkp++) { - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - } + s3c_register_clocks(s5pc100_init_clocks, + ARRAY_SIZE(s5pc100_init_clocks)); clkp = s5pc100_init_clocks_disable; size = ARRAY_SIZE(s5pc100_init_clocks_disable); diff --git a/arch/arm/plat-s5pc1xx/dev-uart.c b/arch/arm/plat-s5pc1xx/dev-uart.c index f749bc5407b..586c95c60bf 100644 --- a/arch/arm/plat-s5pc1xx/dev-uart.c +++ b/arch/arm/plat-s5pc1xx/dev-uart.c @@ -143,32 +143,3 @@ struct s3c24xx_uart_resources s5pc1xx_uart_resources[] __initdata = { .nr_resources = ARRAY_SIZE(s5pc1xx_uart3_resource), }, }; - -/* uart devices */ - -static struct platform_device s3c24xx_uart_device0 = { - .id = 0, -}; - -static struct platform_device s3c24xx_uart_device1 = { - .id = 1, -}; - -static struct platform_device s3c24xx_uart_device2 = { - .id = 2, -}; - -static struct platform_device s3c24xx_uart_device3 = { - .id = 3, -}; - -struct platform_device *s3c24xx_uart_src[4] = { - &s3c24xx_uart_device0, - &s3c24xx_uart_device1, - &s3c24xx_uart_device2, - &s3c24xx_uart_device3, -}; - -struct platform_device *s3c24xx_uart_devs[4] = { -}; - diff --git a/arch/arm/plat-s5pc1xx/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c index bba675df9c7..a4f67e80a15 100644 --- a/arch/arm/plat-s5pc1xx/gpio-config.c +++ b/arch/arm/plat-s5pc1xx/gpio-config.c @@ -16,7 +16,7 @@ #include <linux/gpio.h> #include <linux/io.h> -#include <mach/gpio-core.h> +#include <plat/gpio-core.h> #include <plat/gpio-cfg-s5pc1xx.h> s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off) diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c index facb410e7a7..1ffc57ac293 100644 --- a/arch/arm/plat-s5pc1xx/gpiolib.c +++ b/arch/arm/plat-s5pc1xx/gpiolib.c @@ -17,8 +17,8 @@ #include <linux/gpio.h> #include <mach/map.h> -#include <mach/gpio-core.h> +#include <plat/gpio-core.h> #include <plat/gpio-cfg.h> #include <plat/gpio-cfg-helpers.h> #include <plat/regs-gpio.h> diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h index ef8736366f0..409c804315e 100644 --- a/arch/arm/plat-s5pc1xx/include/plat/irqs.h +++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h @@ -88,11 +88,11 @@ #define IRQ_MDMA S5PC1XX_IRQ_VIC0(18) #define IRQ_PDMA0 S5PC1XX_IRQ_VIC0(19) #define IRQ_PDMA1 S5PC1XX_IRQ_VIC0(20) -#define IRQ_TIMER0 S5PC1XX_IRQ_VIC0(21) -#define IRQ_TIMER1 S5PC1XX_IRQ_VIC0(22) -#define IRQ_TIMER2 S5PC1XX_IRQ_VIC0(23) -#define IRQ_TIMER3 S5PC1XX_IRQ_VIC0(24) -#define IRQ_TIMER4 S5PC1XX_IRQ_VIC0(25) +#define IRQ_TIMER0_VIC S5PC1XX_IRQ_VIC0(21) +#define IRQ_TIMER1_VIC S5PC1XX_IRQ_VIC0(22) +#define IRQ_TIMER2_VIC S5PC1XX_IRQ_VIC0(23) +#define IRQ_TIMER3_VIC S5PC1XX_IRQ_VIC0(24) +#define IRQ_TIMER4_VIC S5PC1XX_IRQ_VIC0(25) #define IRQ_SYSTIMER S5PC1XX_IRQ_VIC0(26) #define IRQ_WDT S5PC1XX_IRQ_VIC0(27) #define IRQ_RTC_ALARM S5PC1XX_IRQ_VIC0(28) @@ -171,8 +171,15 @@ #define IRQ_SDMIRQ S5PC1XX_IRQ_VIC2(30) #define IRQ_SDMFIQ S5PC1XX_IRQ_VIC2(31) +#define IRQ_TIMER(x) (IRQ_SDMFIQ + 1 + (x)) +#define IRQ_TIMER0 IRQ_TIMER(0) +#define IRQ_TIMER1 IRQ_TIMER(1) +#define IRQ_TIMER2 IRQ_TIMER(2) +#define IRQ_TIMER3 IRQ_TIMER(3) +#define IRQ_TIMER4 IRQ_TIMER(4) + /* External interrupt */ -#define S3C_IRQ_EINT_BASE (IRQ_SDMFIQ + 1) +#define S3C_IRQ_EINT_BASE (IRQ_SDMFIQ + 6) #define S3C_EINT(x) (S3C_IRQ_EINT_BASE + (x - 16)) #define IRQ_EINT(x) (x < 16 ? IRQ_EINT0 + x : S3C_EINT(x)) diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h index c5cc86e92d6..24dec4e5253 100644 --- a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h +++ b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h @@ -61,73 +61,10 @@ #define S5PC100_EPLL_MASK 0xffffffff #define S5PC100_EPLLVAL(_m, _p, _s) ((_m) << 16 | ((_p) << 8) | ((_s))) -/* CLKSRC0 */ -#define S5PC100_CLKSRC0_APLL_MASK (0x1<<0) -#define S5PC100_CLKSRC0_APLL_SHIFT (0) -#define S5PC100_CLKSRC0_MPLL_MASK (0x1<<4) -#define S5PC100_CLKSRC0_MPLL_SHIFT (4) -#define S5PC100_CLKSRC0_EPLL_MASK (0x1<<8) -#define S5PC100_CLKSRC0_EPLL_SHIFT (8) -#define S5PC100_CLKSRC0_HPLL_MASK (0x1<<12) -#define S5PC100_CLKSRC0_HPLL_SHIFT (12) -#define S5PC100_CLKSRC0_AMMUX_MASK (0x1<<16) -#define S5PC100_CLKSRC0_AMMUX_SHIFT (16) -#define S5PC100_CLKSRC0_HREF_MASK (0x1<<20) -#define S5PC100_CLKSRC0_HREF_SHIFT (20) -#define S5PC100_CLKSRC0_ONENAND_MASK (0x1<<24) -#define S5PC100_CLKSRC0_ONENAND_SHIFT (24) - - -/* CLKSRC1 */ -#define S5PC100_CLKSRC1_UART_MASK (0x1<<0) -#define S5PC100_CLKSRC1_UART_SHIFT (0) -#define S5PC100_CLKSRC1_SPI0_MASK (0x3<<4) -#define S5PC100_CLKSRC1_SPI0_SHIFT (4) -#define S5PC100_CLKSRC1_SPI1_MASK (0x3<<8) -#define S5PC100_CLKSRC1_SPI1_SHIFT (8) -#define S5PC100_CLKSRC1_SPI2_MASK (0x3<<12) -#define S5PC100_CLKSRC1_SPI2_SHIFT (12) -#define S5PC100_CLKSRC1_IRDA_MASK (0x3<<16) -#define S5PC100_CLKSRC1_IRDA_SHIFT (16) -#define S5PC100_CLKSRC1_UHOST_MASK (0x3<<20) -#define S5PC100_CLKSRC1_UHOST_SHIFT (20) -#define S5PC100_CLKSRC1_CLK48M_MASK (0x1<<24) +/* CLKSRC0..CLKSRC3 -> mostly removed due to clksrc updates */ +#define S5PC100_CLKSRC1_CLK48M_MASK (0x1<<24) #define S5PC100_CLKSRC1_CLK48M_SHIFT (24) -/* CLKSRC2 */ -#define S5PC100_CLKSRC2_MMC0_MASK (0x3<<0) -#define S5PC100_CLKSRC2_MMC0_SHIFT (0) -#define S5PC100_CLKSRC2_MMC1_MASK (0x3<<4) -#define S5PC100_CLKSRC2_MMC1_SHIFT (4) -#define S5PC100_CLKSRC2_MMC2_MASK (0x3<<8) -#define S5PC100_CLKSRC2_MMC2_SHIFT (8) -#define S5PC100_CLKSRC2_LCD_MASK (0x3<<12) -#define S5PC100_CLKSRC2_LCD_SHIFT (12) -#define S5PC100_CLKSRC2_FIMC0_MASK (0x3<<16) -#define S5PC100_CLKSRC2_FIMC0_SHIFT (16) -#define S5PC100_CLKSRC2_FIMC1_MASK (0x3<<20) -#define S5PC100_CLKSRC2_FIMC1_SHIFT (20) -#define S5PC100_CLKSRC2_FIMC2_MASK (0x3<<24) -#define S5PC100_CLKSRC2_FIMC2_SHIFT (24) -#define S5PC100_CLKSRC2_MIXER_MASK (0x3<<28) -#define S5PC100_CLKSRC2_MIXER_SHIFT (28) - -/* CLKSRC3 */ -#define S5PC100_CLKSRC3_PWI_MASK (0x3<<0) -#define S5PC100_CLKSRC3_PWI_SHIFT (0) -#define S5PC100_CLKSRC3_HCLKD2_MASK (0x1<<4) -#define S5PC100_CLKSRC3_HCLKD2_SHIFT (4) -#define S5PC100_CLKSRC3_I2SD2_MASK (0x3<<8) -#define S5PC100_CLKSRC3_I2SD2_SHIFT (8) -#define S5PC100_CLKSRC3_AUDIO0_MASK (0x7<<12) -#define S5PC100_CLKSRC3_AUDIO0_SHIFT (12) -#define S5PC100_CLKSRC3_AUDIO1_MASK (0x7<<16) -#define S5PC100_CLKSRC3_AUDIO1_SHIFT (16) -#define S5PC100_CLKSRC3_AUDIO2_MASK (0x7<<20) -#define S5PC100_CLKSRC3_AUDIO2_SHIFT (20) -#define S5PC100_CLKSRC3_SPDIF_MASK (0x3<<24) -#define S5PC100_CLKSRC3_SPDIF_SHIFT (24) - /* CLKDIV0 */ #define S5PC100_CLKDIV0_APLL_MASK (0x1<<0) #define S5PC100_CLKDIV0_APLL_SHIFT (0) @@ -140,7 +77,7 @@ #define S5PC100_CLKDIV0_SECSS_MASK (0x7<<16) #define S5PC100_CLKDIV0_SECSS_SHIFT (16) -/* CLKDIV1 */ +/* CLKDIV1 (OneNAND clock only used in one place, removed) */ #define S5PC100_CLKDIV1_APLL2_MASK (0x7<<0) #define S5PC100_CLKDIV1_APLL2_SHIFT (0) #define S5PC100_CLKDIV1_MPLL_MASK (0x3<<4) @@ -151,56 +88,12 @@ #define S5PC100_CLKDIV1_D1_SHIFT (12) #define S5PC100_CLKDIV1_PCLKD1_MASK (0x7<<16) #define S5PC100_CLKDIV1_PCLKD1_SHIFT (16) -#define S5PC100_CLKDIV1_ONENAND_MASK (0x3<<20) -#define S5PC100_CLKDIV1_ONENAND_SHIFT (20) #define S5PC100_CLKDIV1_CAM_MASK (0x1F<<24) #define S5PC100_CLKDIV1_CAM_SHIFT (24) -/* CLKDIV2 */ -#define S5PC100_CLKDIV2_UART_MASK (0x7<<0) -#define S5PC100_CLKDIV2_UART_SHIFT (0) -#define S5PC100_CLKDIV2_SPI0_MASK (0xf<<4) -#define S5PC100_CLKDIV2_SPI0_SHIFT (4) -#define S5PC100_CLKDIV2_SPI1_MASK (0xf<<8) -#define S5PC100_CLKDIV2_SPI1_SHIFT (8) -#define S5PC100_CLKDIV2_SPI2_MASK (0xf<<12) -#define S5PC100_CLKDIV2_SPI2_SHIFT (12) -#define S5PC100_CLKDIV2_IRDA_MASK (0xf<<16) -#define S5PC100_CLKDIV2_IRDA_SHIFT (16) -#define S5PC100_CLKDIV2_UHOST_MASK (0xf<<20) -#define S5PC100_CLKDIV2_UHOST_SHIFT (20) - -/* CLKDIV3 */ -#define S5PC100_CLKDIV3_MMC0_MASK (0xf<<0) -#define S5PC100_CLKDIV3_MMC0_SHIFT (0) -#define S5PC100_CLKDIV3_MMC1_MASK (0xf<<4) -#define S5PC100_CLKDIV3_MMC1_SHIFT (4) -#define S5PC100_CLKDIV3_MMC2_MASK (0xf<<8) -#define S5PC100_CLKDIV3_MMC2_SHIFT (8) -#define S5PC100_CLKDIV3_LCD_MASK (0xf<<12) -#define S5PC100_CLKDIV3_LCD_SHIFT (12) -#define S5PC100_CLKDIV3_FIMC0_MASK (0xf<<16) -#define S5PC100_CLKDIV3_FIMC0_SHIFT (16) -#define S5PC100_CLKDIV3_FIMC1_MASK (0xf<<20) -#define S5PC100_CLKDIV3_FIMC1_SHIFT (20) -#define S5PC100_CLKDIV3_FIMC2_MASK (0xf<<24) -#define S5PC100_CLKDIV3_FIMC2_SHIFT (24) -#define S5PC100_CLKDIV3_HDMI_MASK (0xf<<28) -#define S5PC100_CLKDIV3_HDMI_SHIFT (28) - -/* CLKDIV4 */ -#define S5PC100_CLKDIV4_PWI_MASK (0x7<<0) -#define S5PC100_CLKDIV4_PWI_SHIFT (0) -#define S5PC100_CLKDIV4_HCLKD2_MASK (0x7<<4) -#define S5PC100_CLKDIV4_HCLKD2_SHIFT (4) -#define S5PC100_CLKDIV4_I2SD2_MASK (0xf<<8) -#define S5PC100_CLKDIV4_I2SD2_SHIFT (8) -#define S5PC100_CLKDIV4_AUDIO0_MASK (0xf<<12) -#define S5PC100_CLKDIV4_AUDIO0_SHIFT (12) -#define S5PC100_CLKDIV4_AUDIO1_MASK (0xf<<16) -#define S5PC100_CLKDIV4_AUDIO1_SHIFT (16) -#define S5PC100_CLKDIV4_AUDIO2_MASK (0xf<<20) -#define S5PC100_CLKDIV4_AUDIO2_SHIFT (20) +/* CLKDIV2 => removed in clksrc update */ +/* CLKDIV3 => removed in clksrc update, or not needed */ +/* CLKDIV4 => removed in clksrc update, or not needed */ /* HCLKD0/PCLKD0 Clock Gate 0 Registers */ #define S5PC100_CLKGATE_D00_INTC (1<<0) diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c index e44fd04ef33..bfc52482781 100644 --- a/arch/arm/plat-s5pc1xx/irq.c +++ b/arch/arm/plat-s5pc1xx/irq.c @@ -20,87 +20,14 @@ #include <asm/hardware/vic.h> #include <mach/map.h> -#include <plat/regs-timer.h> +#include <plat/irq-vic-timer.h> +#include <plat/irq-uart.h> #include <plat/cpu.h> -/* Timer interrupt handling */ - -static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq) -{ - generic_handle_irq(sub_irq); -} - -static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER0); -} - -static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER1); -} - -static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER2); -} - -static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER3); -} - -static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_timer(irq, IRQ_TIMER4); -} - -/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ - -static void s3c_irq_timer_mask(unsigned int irq) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - - reg &= 0x1f; /* mask out pending interrupts */ - reg &= ~(1 << (irq - IRQ_TIMER0)); - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static void s3c_irq_timer_unmask(unsigned int irq) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - - reg &= 0x1f; /* mask out pending interrupts */ - reg |= 1 << (irq - IRQ_TIMER0); - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static void s3c_irq_timer_ack(unsigned int irq) -{ - u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); - - reg &= 0x1f; /* mask out pending interrupts */ - reg |= (1 << 5) << (irq - IRQ_TIMER0); - __raw_writel(reg, S3C64XX_TINT_CSTAT); -} - -static struct irq_chip s3c_irq_timer = { - .name = "s3c-timer", - .mask = s3c_irq_timer_mask, - .unmask = s3c_irq_timer_unmask, - .ack = s3c_irq_timer_ack, -}; - -struct uart_irq { - void __iomem *regs; - unsigned int base_irq; - unsigned int parent_irq; -}; - /* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] * are consecutive when looking up the interrupt in the demux routines. */ -static struct uart_irq uart_irqs[] = { +static struct s3c_uart_irq uart_irqs[] = { [0] = { .regs = (void *)S3C_VA_UART0, .base_irq = IRQ_S3CUART_BASE0, @@ -123,113 +50,9 @@ static struct uart_irq uart_irqs[] = { }, }; -static inline void __iomem *s3c_irq_uart_base(unsigned int irq) -{ - struct uart_irq *uirq = get_irq_chip_data(irq); - return uirq->regs; -} - -static inline unsigned int s3c_irq_uart_bit(unsigned int irq) -{ - return irq & 3; -} - -/* UART interrupt registers, not worth adding to seperate include header */ -#define S3C64XX_UINTP 0x30 -#define S3C64XX_UINTSP 0x34 -#define S3C64XX_UINTM 0x38 - -static void s3c_irq_uart_mask(unsigned int irq) -{ - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg |= (1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); -} - -static void s3c_irq_uart_maskack(unsigned int irq) -{ - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg |= (1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); - __raw_writel(1 << bit, regs + S3C64XX_UINTP); -} - -static void s3c_irq_uart_unmask(unsigned int irq) -{ - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); - u32 reg; - - reg = __raw_readl(regs + S3C64XX_UINTM); - reg &= ~(1 << bit); - __raw_writel(reg, regs + S3C64XX_UINTM); -} - -static void s3c_irq_uart_ack(unsigned int irq) -{ - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); - - __raw_writel(1 << bit, regs + S3C64XX_UINTP); -} - -static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) -{ - struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0]; - u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); - int base = uirq->base_irq; - - if (pend & (1 << 0)) - generic_handle_irq(base); - if (pend & (1 << 1)) - generic_handle_irq(base + 1); - if (pend & (1 << 2)) - generic_handle_irq(base + 2); - if (pend & (1 << 3)) - generic_handle_irq(base + 3); -} - -static struct irq_chip s3c_irq_uart = { - .name = "s3c-uart", - .mask = s3c_irq_uart_mask, - .unmask = s3c_irq_uart_unmask, - .mask_ack = s3c_irq_uart_maskack, - .ack = s3c_irq_uart_ack, -}; - -static void __init s5pc1xx_uart_irq(struct uart_irq *uirq) -{ - void __iomem *reg_base = uirq->regs; - unsigned int irq; - int offs; - - /* mask all interrupts at the start. */ - __raw_writel(0xf, reg_base + S3C64XX_UINTM); - - for (offs = 0; offs < 3; offs++) { - irq = uirq->base_irq + offs; - - set_irq_chip(irq, &s3c_irq_uart); - set_irq_chip_data(irq, uirq); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } - - set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); -} - void __init s5pc1xx_init_irq(u32 *vic_valid, int num) { int i; - int uart, irq; printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); @@ -240,20 +63,13 @@ void __init s5pc1xx_init_irq(u32 *vic_valid, int num) /* add the timer sub-irqs */ - set_irq_chained_handler(IRQ_TIMER0, s3c_irq_demux_timer0); - set_irq_chained_handler(IRQ_TIMER1, s3c_irq_demux_timer1); - set_irq_chained_handler(IRQ_TIMER2, s3c_irq_demux_timer2); - set_irq_chained_handler(IRQ_TIMER3, s3c_irq_demux_timer3); - set_irq_chained_handler(IRQ_TIMER4, s3c_irq_demux_timer4); - - for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) { - set_irq_chip(irq, &s3c_irq_timer); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } + s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0); + s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1); + s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2); + s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3); + s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4); - for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++) - s5pc1xx_uart_irq(&uart_irqs[uart]); + s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs)); } diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c index b436d44510c..2bf6c57a96a 100644 --- a/arch/arm/plat-s5pc1xx/s5pc100-clock.c +++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c @@ -29,6 +29,7 @@ #include <plat/regs-clock.h> #include <plat/clock.h> +#include <plat/clock-clksrc.h> #include <plat/cpu.h> #include <plat/pll.h> #include <plat/devs.h> @@ -51,23 +52,6 @@ static struct clk clk_ext_xtal_mux = { #define clk_fout_mpll clk_mpll #define clk_vclk_54m clk_54m -struct clk_sources { - unsigned int nr_sources; - struct clk **sources; -}; - -struct clksrc_clk { - struct clk clk; - unsigned int mask; - unsigned int shift; - - struct clk_sources *sources; - - unsigned int divider_shift; - void __iomem *reg_divider; - void __iomem *reg_source; -}; - /* APLL */ static struct clk clk_fout_apll = { .name = "fout_apll", @@ -80,7 +64,7 @@ static struct clk *clk_src_apll_list[] = { [1] = &clk_fout_apll, }; -static struct clk_sources clk_src_apll = { +static struct clksrc_sources clk_src_apll = { .sources = clk_src_apll_list, .nr_sources = ARRAY_SIZE(clk_src_apll_list), }; @@ -90,10 +74,8 @@ static struct clksrc_clk clk_mout_apll = { .name = "mout_apll", .id = -1, }, - .shift = S5PC100_CLKSRC0_APLL_SHIFT, - .mask = S5PC100_CLKSRC0_APLL_MASK, .sources = &clk_src_apll, - .reg_source = S5PC100_CLKSRC0, + .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 0, .size = 1, }, }; static unsigned long s5pc100_clk_dout_apll_get_rate(struct clk *clk) @@ -111,7 +93,9 @@ static struct clk clk_dout_apll = { .name = "dout_apll", .id = -1, .parent = &clk_mout_apll.clk, - .get_rate = s5pc100_clk_dout_apll_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_apll_get_rate, + }, }; static unsigned long s5pc100_clk_arm_get_rate(struct clk *clk) @@ -165,9 +149,11 @@ static struct clk clk_arm = { .name = "armclk", .id = -1, .parent = &clk_dout_apll, - .get_rate = s5pc100_clk_arm_get_rate, - .set_rate = s5pc100_clk_arm_set_rate, - .round_rate = s5pc100_clk_arm_round_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_arm_get_rate, + .set_rate = s5pc100_clk_arm_set_rate, + .round_rate = s5pc100_clk_arm_round_rate, + }, }; static unsigned long s5pc100_clk_dout_d0_bus_get_rate(struct clk *clk) @@ -185,7 +171,9 @@ static struct clk clk_dout_d0_bus = { .name = "dout_d0_bus", .id = -1, .parent = &clk_arm, - .get_rate = s5pc100_clk_dout_d0_bus_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_d0_bus_get_rate, + }, }; static unsigned long s5pc100_clk_dout_pclkd0_get_rate(struct clk *clk) @@ -203,7 +191,9 @@ static struct clk clk_dout_pclkd0 = { .name = "dout_pclkd0", .id = -1, .parent = &clk_dout_d0_bus, - .get_rate = s5pc100_clk_dout_pclkd0_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_pclkd0_get_rate, + }, }; static unsigned long s5pc100_clk_dout_apll2_get_rate(struct clk *clk) @@ -221,7 +211,9 @@ static struct clk clk_dout_apll2 = { .name = "dout_apll2", .id = -1, .parent = &clk_mout_apll.clk, - .get_rate = s5pc100_clk_dout_apll2_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_apll2_get_rate, + }, }; /* MPLL */ @@ -230,7 +222,7 @@ static struct clk *clk_src_mpll_list[] = { [1] = &clk_fout_mpll, }; -static struct clk_sources clk_src_mpll = { +static struct clksrc_sources clk_src_mpll = { .sources = clk_src_mpll_list, .nr_sources = ARRAY_SIZE(clk_src_mpll_list), }; @@ -240,10 +232,8 @@ static struct clksrc_clk clk_mout_mpll = { .name = "mout_mpll", .id = -1, }, - .shift = S5PC100_CLKSRC0_MPLL_SHIFT, - .mask = S5PC100_CLKSRC0_MPLL_MASK, .sources = &clk_src_mpll, - .reg_source = S5PC100_CLKSRC0, + .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 4, .size = 1, }, }; static struct clk *clkset_am_list[] = { @@ -251,7 +241,7 @@ static struct clk *clkset_am_list[] = { [1] = &clk_dout_apll2, }; -static struct clk_sources clk_src_am = { +static struct clksrc_sources clk_src_am = { .sources = clkset_am_list, .nr_sources = ARRAY_SIZE(clkset_am_list), }; @@ -261,10 +251,8 @@ static struct clksrc_clk clk_mout_am = { .name = "mout_am", .id = -1, }, - .shift = S5PC100_CLKSRC0_AMMUX_SHIFT, - .mask = S5PC100_CLKSRC0_AMMUX_MASK, .sources = &clk_src_am, - .reg_source = S5PC100_CLKSRC0, + .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 16, .size = 1, }, }; static unsigned long s5pc100_clk_dout_d1_bus_get_rate(struct clk *clk) @@ -284,7 +272,9 @@ static struct clk clk_dout_d1_bus = { .name = "dout_d1_bus", .id = -1, .parent = &clk_mout_am.clk, - .get_rate = s5pc100_clk_dout_d1_bus_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_d1_bus_get_rate, + }, }; static struct clk *clkset_onenand_list[] = { @@ -292,7 +282,7 @@ static struct clk *clkset_onenand_list[] = { [1] = &clk_dout_d1_bus, }; -static struct clk_sources clk_src_onenand = { +static struct clksrc_sources clk_src_onenand = { .sources = clkset_onenand_list, .nr_sources = ARRAY_SIZE(clkset_onenand_list), }; @@ -302,10 +292,8 @@ static struct clksrc_clk clk_mout_onenand = { .name = "mout_onenand", .id = -1, }, - .shift = S5PC100_CLKSRC0_ONENAND_SHIFT, - .mask = S5PC100_CLKSRC0_ONENAND_MASK, .sources = &clk_src_onenand, - .reg_source = S5PC100_CLKSRC0, + .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 24, .size = 1, }, }; static unsigned long s5pc100_clk_dout_pclkd1_get_rate(struct clk *clk) @@ -325,7 +313,9 @@ static struct clk clk_dout_pclkd1 = { .name = "dout_pclkd1", .id = -1, .parent = &clk_dout_d1_bus, - .get_rate = s5pc100_clk_dout_pclkd1_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_pclkd1_get_rate, + }, }; static unsigned long s5pc100_clk_dout_mpll2_get_rate(struct clk *clk) @@ -345,7 +335,9 @@ static struct clk clk_dout_mpll2 = { .name = "dout_mpll2", .id = -1, .parent = &clk_mout_am.clk, - .get_rate = s5pc100_clk_dout_mpll2_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_mpll2_get_rate, + }, }; static unsigned long s5pc100_clk_dout_cam_get_rate(struct clk *clk) @@ -365,7 +357,9 @@ static struct clk clk_dout_cam = { .name = "dout_cam", .id = -1, .parent = &clk_dout_mpll2, - .get_rate = s5pc100_clk_dout_cam_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_cam_get_rate, + }, }; static unsigned long s5pc100_clk_dout_mpll_get_rate(struct clk *clk) @@ -385,7 +379,9 @@ static struct clk clk_dout_mpll = { .name = "dout_mpll", .id = -1, .parent = &clk_mout_am.clk, - .get_rate = s5pc100_clk_dout_mpll_get_rate, + .ops = &(struct clk_ops) { + .get_rate = s5pc100_clk_dout_mpll_get_rate, + }, }; /* EPLL */ @@ -399,7 +395,7 @@ static struct clk *clk_src_epll_list[] = { [1] = &clk_fout_epll, }; -static struct clk_sources clk_src_epll = { +static struct clksrc_sources clk_src_epll = { .sources = clk_src_epll_list, .nr_sources = ARRAY_SIZE(clk_src_epll_list), }; @@ -409,10 +405,8 @@ static struct clksrc_clk clk_mout_epll = { .name = "mout_epll", .id = -1, }, - .shift = S5PC100_CLKSRC0_EPLL_SHIFT, - .mask = S5PC100_CLKSRC0_EPLL_MASK, - .sources = &clk_src_epll, - .reg_source = S5PC100_CLKSRC0, + .sources = &clk_src_epll, + .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 8, .size = 1, }, }; /* HPLL */ @@ -426,7 +420,7 @@ static struct clk *clk_src_hpll_list[] = { [1] = &clk_fout_hpll, }; -static struct clk_sources clk_src_hpll = { +static struct clksrc_sources clk_src_hpll = { .sources = clk_src_hpll_list, .nr_sources = ARRAY_SIZE(clk_src_hpll_list), }; @@ -436,10 +430,8 @@ static struct clksrc_clk clk_mout_hpll = { .name = "mout_hpll", .id = -1, }, - .shift = S5PC100_CLKSRC0_HPLL_SHIFT, - .mask = S5PC100_CLKSRC0_HPLL_MASK, - .sources = &clk_src_hpll, - .reg_source = S5PC100_CLKSRC0, + .sources = &clk_src_hpll, + .reg_src = { .reg = S5PC100_CLKSRC0, .shift = 12, .size = 1, }, }; /* Peripherals */ @@ -454,190 +446,6 @@ static struct clksrc_clk clk_mout_hpll = { * have a common parent divisor so are not included here. */ -static inline struct clksrc_clk *to_clksrc(struct clk *clk) -{ - return container_of(clk, struct clksrc_clk, clk); -} - -static unsigned long s5pc100_getrate_clksrc(struct clk *clk) -{ - struct clksrc_clk *sclk = to_clksrc(clk); - unsigned long rate = clk_get_rate(clk->parent); - u32 clkdiv = __raw_readl(sclk->reg_divider); - - clkdiv >>= sclk->divider_shift; - clkdiv &= 0xf; - clkdiv++; - - rate /= clkdiv; - return rate; -} - -static int s5pc100_setrate_clksrc(struct clk *clk, unsigned long rate) -{ - struct clksrc_clk *sclk = to_clksrc(clk); - void __iomem *reg = sclk->reg_divider; - unsigned int div; - u32 val; - - rate = clk_round_rate(clk, rate); - div = clk_get_rate(clk->parent) / rate; - if (div > 16) - return -EINVAL; - - val = __raw_readl(reg); - val &= ~(0xf << sclk->divider_shift); - val |= (div - 1) << sclk->divider_shift; - __raw_writel(val, reg); - - return 0; -} - -static int s5pc100_setparent_clksrc(struct clk *clk, struct clk *parent) -{ - struct clksrc_clk *sclk = to_clksrc(clk); - struct clk_sources *srcs = sclk->sources; - u32 clksrc = __raw_readl(sclk->reg_source); - int src_nr = -1; - int ptr; - - for (ptr = 0; ptr < srcs->nr_sources; ptr++) - if (srcs->sources[ptr] == parent) { - src_nr = ptr; - break; - } - - if (src_nr >= 0) { - clksrc &= ~sclk->mask; - clksrc |= src_nr << sclk->shift; - - __raw_writel(clksrc, sclk->reg_source); - return 0; - } - - return -EINVAL; -} - -static unsigned long s5pc100_roundrate_clksrc(struct clk *clk, - unsigned long rate) -{ - unsigned long parent_rate = clk_get_rate(clk->parent); - int div; - - if (rate > parent_rate) - rate = parent_rate; - else { - div = rate / parent_rate; - - if (div == 0) - div = 1; - if (div > 16) - div = 16; - - rate = parent_rate / div; - } - - return rate; -} - -static struct clk *clkset_spi_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll2, - &clk_fin_epll, - &clk_mout_hpll.clk, -}; - -static struct clk_sources clkset_spi = { - .sources = clkset_spi_list, - .nr_sources = ARRAY_SIZE(clkset_spi_list), -}; - -static struct clksrc_clk clk_spi0 = { - .clk = { - .name = "spi_bus", - .id = 0, - .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0, - .enable = s5pc100_sclk0_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC1_SPI0_SHIFT, - .mask = S5PC100_CLKSRC1_SPI0_MASK, - .sources = &clkset_spi, - .divider_shift = S5PC100_CLKDIV2_SPI0_SHIFT, - .reg_divider = S5PC100_CLKDIV2, - .reg_source = S5PC100_CLKSRC1, -}; - -static struct clksrc_clk clk_spi1 = { - .clk = { - .name = "spi_bus", - .id = 1, - .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1, - .enable = s5pc100_sclk0_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC1_SPI1_SHIFT, - .mask = S5PC100_CLKSRC1_SPI1_MASK, - .sources = &clkset_spi, - .divider_shift = S5PC100_CLKDIV2_SPI1_SHIFT, - .reg_divider = S5PC100_CLKDIV2, - .reg_source = S5PC100_CLKSRC1, -}; - -static struct clksrc_clk clk_spi2 = { - .clk = { - .name = "spi_bus", - .id = 2, - .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2, - .enable = s5pc100_sclk0_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC1_SPI2_SHIFT, - .mask = S5PC100_CLKSRC1_SPI2_MASK, - .sources = &clkset_spi, - .divider_shift = S5PC100_CLKDIV2_SPI2_SHIFT, - .reg_divider = S5PC100_CLKDIV2, - .reg_source = S5PC100_CLKSRC1, -}; - -static struct clk *clkset_uart_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, -}; - -static struct clk_sources clkset_uart = { - .sources = clkset_uart_list, - .nr_sources = ARRAY_SIZE(clkset_uart_list), -}; - -static struct clksrc_clk clk_uart_uclk1 = { - .clk = { - .name = "uclk1", - .id = -1, - .ctrlbit = S5PC100_CLKGATE_SCLK0_UART, - .enable = s5pc100_sclk0_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC1_UART_SHIFT, - .mask = S5PC100_CLKSRC1_UART_MASK, - .sources = &clkset_uart, - .divider_shift = S5PC100_CLKDIV2_UART_SHIFT, - .reg_divider = S5PC100_CLKDIV2, - .reg_source = S5PC100_CLKSRC1, -}; - static struct clk clk_iis_cd0 = { .name = "iis_cdclk0", .id = -1, @@ -672,28 +480,31 @@ static struct clk *clkset_audio0_list[] = { &clk_mout_hpll.clk, }; -static struct clk_sources clkset_audio0 = { +static struct clksrc_sources clkset_audio0 = { .sources = clkset_audio0_list, .nr_sources = ARRAY_SIZE(clkset_audio0_list), }; -static struct clksrc_clk clk_audio0 = { - .clk = { - .name = "audio-bus", - .id = 0, - .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO0, - .enable = s5pc100_sclk1_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC3_AUDIO0_SHIFT, - .mask = S5PC100_CLKSRC3_AUDIO0_MASK, - .sources = &clkset_audio0, - .divider_shift = S5PC100_CLKDIV4_AUDIO0_SHIFT, - .reg_divider = S5PC100_CLKDIV4, - .reg_source = S5PC100_CLKSRC3, +static struct clk *clkset_spi_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll2, + &clk_fin_epll, + &clk_mout_hpll.clk, +}; + +static struct clksrc_sources clkset_spi = { + .sources = clkset_spi_list, + .nr_sources = ARRAY_SIZE(clkset_spi_list), +}; + +static struct clk *clkset_uart_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll, +}; + +static struct clksrc_sources clkset_uart = { + .sources = clkset_uart_list, + .nr_sources = ARRAY_SIZE(clkset_uart_list), }; static struct clk *clkset_audio1_list[] = { @@ -705,30 +516,11 @@ static struct clk *clkset_audio1_list[] = { &clk_mout_hpll.clk, }; -static struct clk_sources clkset_audio1 = { +static struct clksrc_sources clkset_audio1 = { .sources = clkset_audio1_list, .nr_sources = ARRAY_SIZE(clkset_audio1_list), }; -static struct clksrc_clk clk_audio1 = { - .clk = { - .name = "audio-bus", - .id = 1, - .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO1, - .enable = s5pc100_sclk1_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC3_AUDIO1_SHIFT, - .mask = S5PC100_CLKSRC3_AUDIO1_MASK, - .sources = &clkset_audio1, - .divider_shift = S5PC100_CLKDIV4_AUDIO1_SHIFT, - .reg_divider = S5PC100_CLKDIV4, - .reg_source = S5PC100_CLKSRC3, -}; - static struct clk *clkset_audio2_list[] = { &clk_mout_epll.clk, &clk_dout_mpll, @@ -737,52 +529,56 @@ static struct clk *clkset_audio2_list[] = { &clk_mout_hpll.clk, }; -static struct clk_sources clkset_audio2 = { +static struct clksrc_sources clkset_audio2 = { .sources = clkset_audio2_list, .nr_sources = ARRAY_SIZE(clkset_audio2_list), }; -static struct clksrc_clk clk_audio2 = { - .clk = { - .name = "audio-bus", - .id = 2, - .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO2, - .enable = s5pc100_sclk1_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, +static struct clksrc_clk clksrc_audio[] = { + { + .clk = { + .name = "audio-bus", + .id = 0, + .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO0, + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clkset_audio0, + .reg_div = { .reg = S5PC100_CLKDIV4, .shift = 12, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC3, .shift = 12, .size = 3, }, + }, { + .clk = { + .name = "audio-bus", + .id = 1, + .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO1, + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clkset_audio1, + .reg_div = { .reg = S5PC100_CLKDIV4, .shift = 16, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC3, .shift = 16, .size = 3, }, + }, { + .clk = { + .name = "audio-bus", + .id = 2, + .ctrlbit = S5PC100_CLKGATE_SCLK1_AUDIO2, + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clkset_audio2, + .reg_div = { .reg = S5PC100_CLKDIV4, .shift = 20, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC3, .shift = 20, .size = 3, }, }, - .shift = S5PC100_CLKSRC3_AUDIO2_SHIFT, - .mask = S5PC100_CLKSRC3_AUDIO2_MASK, - .sources = &clkset_audio2, - .divider_shift = S5PC100_CLKDIV4_AUDIO2_SHIFT, - .reg_divider = S5PC100_CLKDIV4, - .reg_source = S5PC100_CLKSRC3, }; static struct clk *clkset_spdif_list[] = { - &clk_audio0.clk, - &clk_audio1.clk, - &clk_audio2.clk, + &clksrc_audio[0].clk, + &clksrc_audio[1].clk, + &clksrc_audio[2].clk, }; -static struct clk_sources clkset_spdif = { +static struct clksrc_sources clkset_spdif = { .sources = clkset_spdif_list, .nr_sources = ARRAY_SIZE(clkset_spdif_list), }; -static struct clksrc_clk clk_spdif = { - .clk = { - .name = "spdif", - .id = -1, - }, - .shift = S5PC100_CLKSRC3_SPDIF_SHIFT, - .mask = S5PC100_CLKSRC3_SPDIF_MASK, - .sources = &clkset_spdif, - .reg_source = S5PC100_CLKSRC3, -}; - static struct clk *clkset_lcd_fimc_list[] = { &clk_mout_epll.clk, &clk_dout_mpll, @@ -790,87 +586,11 @@ static struct clk *clkset_lcd_fimc_list[] = { &clk_vclk_54m, }; -static struct clk_sources clkset_lcd_fimc = { +static struct clksrc_sources clkset_lcd_fimc = { .sources = clkset_lcd_fimc_list, .nr_sources = ARRAY_SIZE(clkset_lcd_fimc_list), }; -static struct clksrc_clk clk_lcd = { - .clk = { - .name = "lcd", - .id = -1, - .ctrlbit = S5PC100_CLKGATE_SCLK1_LCD, - .enable = s5pc100_sclk1_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC2_LCD_SHIFT, - .mask = S5PC100_CLKSRC2_LCD_MASK, - .sources = &clkset_lcd_fimc, - .divider_shift = S5PC100_CLKDIV3_LCD_SHIFT, - .reg_divider = S5PC100_CLKDIV3, - .reg_source = S5PC100_CLKSRC2, -}; - -static struct clksrc_clk clk_fimc0 = { - .clk = { - .name = "fimc", - .id = 0, - .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC0, - .enable = s5pc100_sclk1_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC2_FIMC0_SHIFT, - .mask = S5PC100_CLKSRC2_FIMC0_MASK, - .sources = &clkset_lcd_fimc, - .divider_shift = S5PC100_CLKDIV3_FIMC0_SHIFT, - .reg_divider = S5PC100_CLKDIV3, - .reg_source = S5PC100_CLKSRC2, -}; - -static struct clksrc_clk clk_fimc1 = { - .clk = { - .name = "fimc", - .id = 1, - .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC1, - .enable = s5pc100_sclk1_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC2_FIMC1_SHIFT, - .mask = S5PC100_CLKSRC2_FIMC1_MASK, - .sources = &clkset_lcd_fimc, - .divider_shift = S5PC100_CLKDIV3_FIMC1_SHIFT, - .reg_divider = S5PC100_CLKDIV3, - .reg_source = S5PC100_CLKSRC2, -}; - -static struct clksrc_clk clk_fimc2 = { - .clk = { - .name = "fimc", - .id = 2, - .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC2, - .enable = s5pc100_sclk1_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC2_FIMC2_SHIFT, - .mask = S5PC100_CLKSRC2_FIMC2_MASK, - .sources = &clkset_lcd_fimc, - .divider_shift = S5PC100_CLKDIV3_FIMC2_SHIFT, - .reg_divider = S5PC100_CLKDIV3, - .reg_source = S5PC100_CLKSRC2, -}; - static struct clk *clkset_mmc_list[] = { &clk_mout_epll.clk, &clk_dout_mpll, @@ -878,69 +598,11 @@ static struct clk *clkset_mmc_list[] = { &clk_mout_hpll.clk , }; -static struct clk_sources clkset_mmc = { +static struct clksrc_sources clkset_mmc = { .sources = clkset_mmc_list, .nr_sources = ARRAY_SIZE(clkset_mmc_list), }; -static struct clksrc_clk clk_mmc0 = { - .clk = { - .name = "mmc_bus", - .id = 0, - .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0, - .enable = s5pc100_sclk0_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC2_MMC0_SHIFT, - .mask = S5PC100_CLKSRC2_MMC0_MASK, - .sources = &clkset_mmc, - .divider_shift = S5PC100_CLKDIV3_MMC0_SHIFT, - .reg_divider = S5PC100_CLKDIV3, - .reg_source = S5PC100_CLKSRC2, -}; - -static struct clksrc_clk clk_mmc1 = { - .clk = { - .name = "mmc_bus", - .id = 1, - .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1, - .enable = s5pc100_sclk0_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC2_MMC1_SHIFT, - .mask = S5PC100_CLKSRC2_MMC1_MASK, - .sources = &clkset_mmc, - .divider_shift = S5PC100_CLKDIV3_MMC1_SHIFT, - .reg_divider = S5PC100_CLKDIV3, - .reg_source = S5PC100_CLKSRC2, -}; - -static struct clksrc_clk clk_mmc2 = { - .clk = { - .name = "mmc_bus", - .id = 2, - .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2, - .enable = s5pc100_sclk0_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC2_MMC2_SHIFT, - .mask = S5PC100_CLKSRC2_MMC2_MASK, - .sources = &clkset_mmc, - .divider_shift = S5PC100_CLKDIV3_MMC2_SHIFT, - .reg_divider = S5PC100_CLKDIV3, - .reg_source = S5PC100_CLKSRC2, -}; - - static struct clk *clkset_usbhost_list[] = { &clk_mout_epll.clk, &clk_dout_mpll, @@ -948,28 +610,141 @@ static struct clk *clkset_usbhost_list[] = { &clk_48m, }; -static struct clk_sources clkset_usbhost = { +static struct clksrc_sources clkset_usbhost = { .sources = clkset_usbhost_list, .nr_sources = ARRAY_SIZE(clkset_usbhost_list), }; -static struct clksrc_clk clk_usbhost = { - .clk = { - .name = "usbhost", - .id = -1, - .ctrlbit = S5PC100_CLKGATE_SCLK0_USBHOST, - .enable = s5pc100_sclk0_ctrl, - .set_parent = s5pc100_setparent_clksrc, - .get_rate = s5pc100_getrate_clksrc, - .set_rate = s5pc100_setrate_clksrc, - .round_rate = s5pc100_roundrate_clksrc, - }, - .shift = S5PC100_CLKSRC1_UHOST_SHIFT, - .mask = S5PC100_CLKSRC1_UHOST_MASK, - .sources = &clkset_usbhost, - .divider_shift = S5PC100_CLKDIV2_UHOST_SHIFT, - .reg_divider = S5PC100_CLKDIV2, - .reg_source = S5PC100_CLKSRC1, +static struct clksrc_clk clksrc_clks[] = { + { + .clk = { + .name = "spi_bus", + .id = 0, + .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0, + .enable = s5pc100_sclk0_ctrl, + + }, + .sources = &clkset_spi, + .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 4, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 4, .size = 2, }, + }, { + .clk = { + .name = "spi_bus", + .id = 1, + .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1, + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clkset_spi, + .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 8, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 8, .size = 2, }, + }, { + .clk = { + .name = "spi_bus", + .id = 2, + .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2, + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clkset_spi, + .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 12, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 12, .size = 2, }, + }, { + .clk = { + .name = "uclk1", + .id = -1, + .ctrlbit = S5PC100_CLKGATE_SCLK0_UART, + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clkset_uart, + .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 0, .size = 3, }, + .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 0, .size = 1, }, + }, { + .clk = { + .name = "spdif", + .id = -1, + }, + .sources = &clkset_spdif, + .reg_src = { .reg = S5PC100_CLKSRC3, .shift = 24, .size = 2, }, + }, { + .clk = { + .name = "lcd", + .id = -1, + .ctrlbit = S5PC100_CLKGATE_SCLK1_LCD, + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clkset_lcd_fimc, + .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 12, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 12, .size = 2, }, + }, { + .clk = { + .name = "fimc", + .id = 0, + .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC0, + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clkset_lcd_fimc, + .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 16, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 16, .size = 2, }, + }, { + .clk = { + .name = "fimc", + .id = 1, + .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC1, + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clkset_lcd_fimc, + .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 20, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 20, .size = 2, }, + }, { + .clk = { + .name = "fimc", + .id = 2, + .ctrlbit = S5PC100_CLKGATE_SCLK1_FIMC2, + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clkset_lcd_fimc, + .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 24, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 24, .size = 2, }, + }, { + .clk = { + .name = "mmc_bus", + .id = 0, + .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0, + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clkset_mmc, + .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 0, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 0, .size = 2, }, + }, { + .clk = { + .name = "mmc_bus", + .id = 1, + .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1, + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clkset_mmc, + .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 4, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 4, .size = 2, }, + }, { + .clk = { + .name = "mmc_bus", + .id = 2, + .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2, + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clkset_mmc, + .reg_div = { .reg = S5PC100_CLKDIV3, .shift = 8, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC2, .shift = 8, .size = 2, }, + }, { + .clk = { + .name = "usbhost", + .id = -1, + .ctrlbit = S5PC100_CLKGATE_SCLK0_USBHOST, + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clkset_usbhost, + .reg_div = { .reg = S5PC100_CLKDIV2, .shift = 20, .size = 4, }, + .reg_src = { .reg = S5PC100_CLKSRC1, .shift = 20, .size = 2, }, + } }; /* Clock initialisation code */ @@ -981,45 +756,8 @@ static struct clksrc_clk *init_parents[] = { &clk_mout_onenand, &clk_mout_epll, &clk_mout_hpll, - &clk_spi0, - &clk_spi1, - &clk_spi2, - &clk_uart_uclk1, - &clk_audio0, - &clk_audio1, - &clk_audio2, - &clk_spdif, - &clk_lcd, - &clk_fimc0, - &clk_fimc1, - &clk_fimc2, - &clk_mmc0, - &clk_mmc1, - &clk_mmc2, - &clk_usbhost, }; -static void __init_or_cpufreq s5pc100_set_clksrc(struct clksrc_clk *clk) -{ - struct clk_sources *srcs = clk->sources; - u32 clksrc = __raw_readl(clk->reg_source); - - clksrc &= clk->mask; - clksrc >>= clk->shift; - - if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) { - printk(KERN_ERR "%s: bad source %d\n", - clk->clk.name, clksrc); - return; - } - - clk->clk.parent = srcs->sources[clksrc]; - - printk(KERN_INFO "%s: source is %s (%d), rate is %ld.%03ld MHz\n", - clk->clk.name, clk->clk.parent->name, clksrc, - print_mhz(clk_get_rate(&clk->clk))); -} - #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) void __init_or_cpufreq s5pc100_setup_clocks(void) @@ -1083,17 +821,25 @@ void __init_or_cpufreq s5pc100_setup_clocks(void) clk_f.rate = armclk; for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) - s5pc100_set_clksrc(init_parents[ptr]); + s3c_set_clksrc(init_parents[ptr], true); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_audio); ptr++) + s3c_set_clksrc(clksrc_audio + ptr, true); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++) + s3c_set_clksrc(clksrc_clks + ptr, true); } static struct clk *clks[] __initdata = { &clk_ext_xtal_mux, - &clk_mout_apll.clk, &clk_dout_apll, &clk_dout_d0_bus, &clk_dout_pclkd0, &clk_dout_apll2, + &clk_mout_apll.clk, &clk_mout_mpll.clk, + &clk_mout_epll.clk, + &clk_mout_hpll.clk, &clk_mout_am.clk, &clk_dout_d1_bus, &clk_mout_onenand.clk, @@ -1101,29 +847,12 @@ static struct clk *clks[] __initdata = { &clk_dout_mpll2, &clk_dout_cam, &clk_dout_mpll, - &clk_mout_epll.clk, &clk_fout_epll, &clk_iis_cd0, &clk_iis_cd1, &clk_iis_cd2, &clk_pcm_cd0, &clk_pcm_cd1, - &clk_spi0.clk, - &clk_spi1.clk, - &clk_spi2.clk, - &clk_uart_uclk1.clk, - &clk_audio0.clk, - &clk_audio1.clk, - &clk_audio2.clk, - &clk_spdif.clk, - &clk_lcd.clk, - &clk_fimc0.clk, - &clk_fimc1.clk, - &clk_fimc2.clk, - &clk_mmc0.clk, - &clk_mmc1.clk, - &clk_mmc2.clk, - &clk_usbhost.clk, &clk_arm, }; @@ -1141,4 +870,7 @@ void __init s5pc100_register_clocks(void) clkp->name, ret); } } + + s3c_register_clksrc(clksrc_audio, ARRAY_SIZE(clksrc_audio)); + s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks)); } diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 486a0d6301e..1c2fe91c23e 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -13,5 +13,168 @@ config PLAT_SAMSUNG if PLAT_SAMSUNG +config SAMSUNG_CLKSRC + bool + help + Select the clock code for the clksrc implementation + used by newer systems such as the S3C64XX. + +# options for IRQ support + +config SAMSUNG_IRQ_VIC_TIMER + bool + help + Internal configuration to build the VIC timer interrupt code. + +config SAMSUNG_IRQ_UART + bool + help + Internal configuration to build the IRQ UART demux code. + +# options for gpio configuration support + +config SAMSUNG_GPIOLIB_4BIT + bool + help + GPIOlib file contains the 4 bit modification functions for gpio + configuration. GPIOlib shall be compiled only for S3C64XX and S5P + series of processors. + +config S3C_GPIO_CFG_S3C24XX + bool + help + Internal configuration to enable S3C24XX style GPIO configuration + functions. + +config S3C_GPIO_CFG_S3C64XX + bool + help + Internal configuration to enable S3C64XX style GPIO configuration + functions. + +config S5P_GPIO_CFG_S5PC1XX + bool + help + Internal configuration to enable S5PC1XX style GPIO configuration + functions. + +config S3C_GPIO_PULL_UPDOWN + bool + help + Internal configuration to enable the correct GPIO pull helper + +config S3C_GPIO_PULL_DOWN + bool + help + Internal configuration to enable the correct GPIO pull helper + +config S3C_GPIO_PULL_UP + bool + help + Internal configuration to enable the correct GPIO pull helper + +config SAMSUNG_GPIO_EXTRA + int "Number of additional GPIO pins" + default 0 + help + Use additional GPIO space in addition to the GPIO's the SOC + provides. This allows expanding the GPIO space for use with + GPIO expanders. + +# ADC driver + +config S3C_ADC + bool "ADC common driver support" + help + Core support for the ADC block found in the Samsung SoC systems + for drivers such as the touchscreen and hwmon to use to share + this resource. + +# device definitions to compile in + +config S3C_DEV_HSMMC + bool + help + Compile in platform device definitions for HSMMC code + +config S3C_DEV_HSMMC1 + bool + help + Compile in platform device definitions for HSMMC channel 1 + +config S3C_DEV_HSMMC2 + bool + help + Compile in platform device definitions for HSMMC channel 2 + +config S3C_DEV_I2C1 + bool + help + Compile in platform device definitions for I2C channel 1 + +config S3C_DEV_FB + bool + help + Compile in platform device definition for framebuffer + +config S3C_DEV_USB_HOST + bool + help + Compile in platform device definition for USB host. + +config S3C_DEV_USB_HSOTG + bool + help + Compile in platform device definition for USB high-speed OtG + +config S3C_DEV_NAND + bool + help + Compile in platform device definition for NAND controller + +comment "Power management" + +config SAMSUNG_PM_DEBUG + bool "S3C2410 PM Suspend debug" + depends on PM + help + Say Y here if you want verbose debugging from the PM Suspend and + Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> + for more information. + +config S3C_PM_DEBUG_LED_SMDK + bool "SMDK LED suspend/resume debugging" + depends on PM && (MACH_SMDK6410) + help + Say Y here to enable the use of the SMDK LEDs on the baseboard + for debugging of the state of the suspend and resume process. + + Note, this currently only works for S3C64XX based SMDK boards. + +config SAMSUNG_PM_CHECK + bool "S3C2410 PM Suspend Memory CRC" + depends on PM && CRC32 + help + Enable the PM code's memory area checksum over sleep. This option + will generate CRCs of all blocks of memory, and store them before + going to sleep. The blocks are then checked on resume for any + errors. + + Note, this can take several seconds depending on memory size + and CPU speed. + + See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> + +config SAMSUNG_PM_CHECK_CHUNKSIZE + int "S3C2410 PM Suspend CRC Chunksize (KiB)" + depends on PM && SAMSUNG_PM_CHECK + default 64 + help + Set the chunksize in Kilobytes of the CRC for checking memory + corruption over suspend and resume. A smaller value will mean that + the CRC data block will take more memory, but wil identify any + faults with better precision. + + See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> endif diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 4478b9f7dc3..c8c8caec8cd 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -9,3 +9,41 @@ obj-m := obj-n := dummy.o obj- := +# Objects we always build independent of SoC choice + +obj-y += clock.o +obj-y += pwm-clock.o +obj-y += gpio.o +obj-y += gpio-config.o + +obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o +obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o + +obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o +obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o + +# ADC + +obj-$(CONFIG_S3C_ADC) += adc.o + +# devices + +obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o +obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o +obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o +obj-y += dev-i2c0.o +obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o +obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o +obj-y += dev-uart.o +obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o +obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o +obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o + +# PM support + +obj-$(CONFIG_PM) += pm-gpio.o +obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o + +# PWM support + +obj-$(CONFIG_HAVE_PWM) += pwm.o diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-samsung/adc.c index ce47627f336..c7659b7378b 100644 --- a/arch/arm/plat-s3c24xx/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -1,10 +1,10 @@ -/* arch/arm/plat-s3c24xx/adc.c +/* arch/arm/plat-samsung/adc.c * * Copyright (c) 2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> * - * S3C24XX ADC device core + * Samsung ADC 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 @@ -37,6 +37,11 @@ * action is required. */ +enum s3c_cpu_type { + TYPE_S3C24XX, + TYPE_S3C64XX +}; + struct s3c_adc_client { struct platform_device *pdev; struct list_head pend; @@ -262,7 +267,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) if (!client) { dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__); - return IRQ_HANDLED; + goto exit; } data0 = readl(adc->regs + S3C2410_ADCDAT0); @@ -289,6 +294,11 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) local_irq_restore(flags); } +exit: + if (platform_get_device_id(adc->pdev)->driver_data == TYPE_S3C64XX) { + /* Clear ADC interrupt */ + writel(0, adc->regs + S3C64XX_ADCCLRINT); + } return IRQ_HANDLED; } @@ -410,9 +420,22 @@ static int s3c_adc_resume(struct platform_device *pdev) #define s3c_adc_resume NULL #endif +static struct platform_device_id s3c_adc_driver_ids[] = { + { + .name = "s3c24xx-adc", + .driver_data = TYPE_S3C24XX, + }, { + .name = "s3c64xx-adc", + .driver_data = TYPE_S3C64XX, + }, + { } +}; +MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids); + static struct platform_driver s3c_adc_driver = { + .id_table = s3c_adc_driver_ids, .driver = { - .name = "s3c24xx-adc", + .name = "s3c-adc", .owner = THIS_MODULE, }, .probe = s3c_adc_probe, diff --git a/arch/arm/plat-samsung/clock-clksrc.c b/arch/arm/plat-samsung/clock-clksrc.c new file mode 100644 index 00000000000..ae8b8507663 --- /dev/null +++ b/arch/arm/plat-samsung/clock-clksrc.c @@ -0,0 +1,212 @@ +/* linux/arch/arm/plat-samsung/clock-clksrc.c + * + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/sysdev.h> +#include <linux/io.h> + +#include <plat/clock.h> +#include <plat/clock-clksrc.h> +#include <plat/cpu-freq.h> + +static inline struct clksrc_clk *to_clksrc(struct clk *clk) +{ + return container_of(clk, struct clksrc_clk, clk); +} + +static inline u32 bit_mask(u32 shift, u32 nr_bits) +{ + u32 mask = 0xffffffff >> (32 - nr_bits); + + return mask << shift; +} + +static unsigned long s3c_getrate_clksrc(struct clk *clk) +{ + struct clksrc_clk *sclk = to_clksrc(clk); + unsigned long rate = clk_get_rate(clk->parent); + u32 clkdiv = __raw_readl(sclk->reg_div.reg); + u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size); + + clkdiv &= mask; + clkdiv >>= sclk->reg_div.shift; + clkdiv++; + + rate /= clkdiv; + return rate; +} + +static int s3c_setrate_clksrc(struct clk *clk, unsigned long rate) +{ + struct clksrc_clk *sclk = to_clksrc(clk); + void __iomem *reg = sclk->reg_div.reg; + unsigned int div; + u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size); + u32 val; + + rate = clk_round_rate(clk, rate); + div = clk_get_rate(clk->parent) / rate; + if (div > (1 << sclk->reg_div.size)) + return -EINVAL; + + val = __raw_readl(reg); + val &= ~mask; + val |= (div - 1) << sclk->reg_div.shift; + __raw_writel(val, reg); + + return 0; +} + +static int s3c_setparent_clksrc(struct clk *clk, struct clk *parent) +{ + struct clksrc_clk *sclk = to_clksrc(clk); + struct clksrc_sources *srcs = sclk->sources; + u32 clksrc = __raw_readl(sclk->reg_src.reg); + u32 mask = bit_mask(sclk->reg_src.shift, sclk->reg_src.size); + int src_nr = -1; + int ptr; + + for (ptr = 0; ptr < srcs->nr_sources; ptr++) + if (srcs->sources[ptr] == parent) { + src_nr = ptr; + break; + } + + if (src_nr >= 0) { + clk->parent = parent; + + clksrc &= ~mask; + clksrc |= src_nr << sclk->reg_src.shift; + + __raw_writel(clksrc, sclk->reg_src.reg); + return 0; + } + + return -EINVAL; +} + +static unsigned long s3c_roundrate_clksrc(struct clk *clk, + unsigned long rate) +{ + struct clksrc_clk *sclk = to_clksrc(clk); + unsigned long parent_rate = clk_get_rate(clk->parent); + int max_div = 1 << sclk->reg_div.size; + int div; + + if (rate >= parent_rate) + rate = parent_rate; + else { + div = parent_rate / rate; + if (parent_rate % rate) + div++; + + if (div == 0) + div = 1; + if (div > max_div) + div = max_div; + + rate = parent_rate / div; + } + + return rate; +} + +/* Clock initialisation code */ + +void __init_or_cpufreq s3c_set_clksrc(struct clksrc_clk *clk, bool announce) +{ + struct clksrc_sources *srcs = clk->sources; + u32 mask = bit_mask(clk->reg_src.shift, clk->reg_src.size); + u32 clksrc; + + if (!clk->reg_src.reg) { + if (!clk->clk.parent) + printk(KERN_ERR "%s: no parent clock specified\n", + clk->clk.name); + return; + } + + clksrc = __raw_readl(clk->reg_src.reg); + clksrc &= mask; + clksrc >>= clk->reg_src.shift; + + if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) { + printk(KERN_ERR "%s: bad source %d\n", + clk->clk.name, clksrc); + return; + } + + clk->clk.parent = srcs->sources[clksrc]; + + if (announce) + printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n", + clk->clk.name, clk->clk.parent->name, clksrc, + clk_get_rate(&clk->clk)); +} + +static struct clk_ops clksrc_ops = { + .set_parent = s3c_setparent_clksrc, + .get_rate = s3c_getrate_clksrc, + .set_rate = s3c_setrate_clksrc, + .round_rate = s3c_roundrate_clksrc, +}; + +static struct clk_ops clksrc_ops_nodiv = { + .set_parent = s3c_setparent_clksrc, +}; + +static struct clk_ops clksrc_ops_nosrc = { + .get_rate = s3c_getrate_clksrc, + .set_rate = s3c_setrate_clksrc, + .round_rate = s3c_roundrate_clksrc, +}; + +void __init s3c_register_clksrc(struct clksrc_clk *clksrc, int size) +{ + int ret; + + for (; size > 0; size--, clksrc++) { + if (!clksrc->reg_div.reg && !clksrc->reg_src.reg) + printk(KERN_ERR "%s: clock %s has no registers set\n", + __func__, clksrc->clk.name); + + /* fill in the default functions */ + + if (!clksrc->clk.ops) { + if (!clksrc->reg_div.reg) + clksrc->clk.ops = &clksrc_ops_nodiv; + else if (!clksrc->reg_src.reg) + clksrc->clk.ops = &clksrc_ops_nosrc; + else + clksrc->clk.ops = &clksrc_ops; + } + + /* setup the clocksource, but do not announce it + * as it may be re-set by the setup routines + * called after the rest of the clocks have been + * registered + */ + s3c_set_clksrc(clksrc, false); + + ret = s3c24xx_register_clock(&clksrc->clk); + + if (ret < 0) { + printk(KERN_ERR "%s: failed to register %s (%d)\n", + __func__, clksrc->clk.name, ret); + } + } +} diff --git a/arch/arm/plat-s3c/clock.c b/arch/arm/plat-samsung/clock.c index 619cfa82dca..e9cdbe47beb 100644 --- a/arch/arm/plat-s3c/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -150,8 +150,8 @@ unsigned long clk_get_rate(struct clk *clk) if (clk->rate != 0) return clk->rate; - if (clk->get_rate != NULL) - return (clk->get_rate)(clk); + if (clk->ops != NULL && clk->ops->get_rate != NULL) + return (clk->ops->get_rate)(clk); if (clk->parent != NULL) return clk_get_rate(clk->parent); @@ -161,8 +161,8 @@ unsigned long clk_get_rate(struct clk *clk) long clk_round_rate(struct clk *clk, unsigned long rate) { - if (!IS_ERR(clk) && clk->round_rate) - return (clk->round_rate)(clk, rate); + if (!IS_ERR(clk) && clk->ops && clk->ops->round_rate) + return (clk->ops->round_rate)(clk, rate); return rate; } @@ -178,13 +178,14 @@ int clk_set_rate(struct clk *clk, unsigned long rate) * the clock may have been made this way by choice. */ - WARN_ON(clk->set_rate == NULL); + WARN_ON(clk->ops == NULL); + WARN_ON(clk->ops && clk->ops->set_rate == NULL); - if (clk->set_rate == NULL) + if (clk->ops == NULL || clk->ops->set_rate == NULL) return -EINVAL; spin_lock(&clocks_lock); - ret = (clk->set_rate)(clk, rate); + ret = (clk->ops->set_rate)(clk, rate); spin_unlock(&clocks_lock); return ret; @@ -204,8 +205,8 @@ int clk_set_parent(struct clk *clk, struct clk *parent) spin_lock(&clocks_lock); - if (clk->set_parent) - ret = (clk->set_parent)(clk, parent); + if (clk->ops && clk->ops->set_parent) + ret = (clk->ops->set_parent)(clk, parent); spin_unlock(&clocks_lock); @@ -224,12 +225,16 @@ EXPORT_SYMBOL(clk_set_parent); /* base clocks */ -static int clk_default_setrate(struct clk *clk, unsigned long rate) +int clk_default_setrate(struct clk *clk, unsigned long rate) { clk->rate = rate; return 0; } +struct clk_ops clk_ops_def_setrate = { + .set_rate = clk_default_setrate, +}; + struct clk clk_xtal = { .name = "xtal", .id = -1, @@ -251,7 +256,7 @@ struct clk clk_epll = { struct clk clk_mpll = { .name = "mpll", .id = -1, - .set_rate = clk_default_setrate, + .ops = &clk_ops_def_setrate, }; struct clk clk_upll = { @@ -267,7 +272,6 @@ struct clk clk_f = { .rate = 0, .parent = &clk_mpll, .ctrlbit = 0, - .set_rate = clk_default_setrate, }; struct clk clk_h = { @@ -276,7 +280,7 @@ struct clk clk_h = { .rate = 0, .parent = NULL, .ctrlbit = 0, - .set_rate = clk_default_setrate, + .ops = &clk_ops_def_setrate, }; struct clk clk_p = { @@ -285,7 +289,7 @@ struct clk clk_p = { .rate = 0, .parent = NULL, .ctrlbit = 0, - .set_rate = clk_default_setrate, + .ops = &clk_ops_def_setrate, }; struct clk clk_usb_bus = { @@ -296,7 +300,6 @@ struct clk clk_usb_bus = { }; - struct clk s3c24xx_uclk = { .name = "uclk", .id = -1, @@ -333,6 +336,28 @@ int s3c24xx_register_clocks(struct clk **clks, int nr_clks) return fails; } +/** + * s3c_register_clocks() - register an array of clocks + * @clkp: Pointer to the first clock in the array. + * @nr_clks: Number of clocks to register. + * + * Call s3c24xx_register_clock() on the @clkp array given, printing an + * error if it fails to register the clock (unlikely). + */ +void __init s3c_register_clocks(struct clk *clkp, int nr_clks) +{ + int ret; + + for (; nr_clks > 0; nr_clks--, clkp++) { + ret = s3c24xx_register_clock(clkp); + + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + } +} + /* initalise all the clocks */ int __init s3c24xx_register_baseclocks(unsigned long xtal) diff --git a/arch/arm/plat-s3c/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c index a90198fc4b0..a90198fc4b0 100644 --- a/arch/arm/plat-s3c/dev-fb.c +++ b/arch/arm/plat-samsung/dev-fb.c diff --git a/arch/arm/plat-s3c/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c index 4c05b39810e..4c05b39810e 100644 --- a/arch/arm/plat-s3c/dev-hsmmc.c +++ b/arch/arm/plat-samsung/dev-hsmmc.c diff --git a/arch/arm/plat-s3c/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c index e49bc4cd0ee..e49bc4cd0ee 100644 --- a/arch/arm/plat-s3c/dev-hsmmc1.c +++ b/arch/arm/plat-samsung/dev-hsmmc1.c diff --git a/arch/arm/plat-s3c/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c index 824580bc0e0..824580bc0e0 100644 --- a/arch/arm/plat-s3c/dev-hsmmc2.c +++ b/arch/arm/plat-samsung/dev-hsmmc2.c diff --git a/arch/arm/plat-s3c/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c index 4c761529b94..4c761529b94 100644 --- a/arch/arm/plat-s3c/dev-i2c0.c +++ b/arch/arm/plat-samsung/dev-i2c0.c diff --git a/arch/arm/plat-s3c/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c index d44f7911050..d44f7911050 100644 --- a/arch/arm/plat-s3c/dev-i2c1.c +++ b/arch/arm/plat-samsung/dev-i2c1.c diff --git a/arch/arm/plat-s3c/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c index 84808ccda70..a52fb6cf618 100644 --- a/arch/arm/plat-s3c/dev-nand.c +++ b/arch/arm/plat-samsung/dev-nand.c @@ -58,8 +58,8 @@ static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) return -ENOMEM; } - size = sizeof(int) * set->nr_chips; - if (size) { + if (set->nr_map && set->nr_chips) { + size = sizeof(int) * set->nr_chips; ptr = kmemdup(set->nr_map, size, GFP_KERNEL); set->nr_map = ptr; diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c new file mode 100644 index 00000000000..3776cd95245 --- /dev/null +++ b/arch/arm/plat-samsung/dev-uart.c @@ -0,0 +1,44 @@ +/* linux/arch/arm/plat-samsung/dev-uart.c + * originally from arch/arm/plat-s3c24xx/devs.c + *x + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Base S3C24XX platform device definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ + +#include <linux/kernel.h> +#include <linux/platform_device.h> + +/* uart devices */ + +static struct platform_device s3c24xx_uart_device0 = { + .id = 0, +}; + +static struct platform_device s3c24xx_uart_device1 = { + .id = 1, +}; + +static struct platform_device s3c24xx_uart_device2 = { + .id = 2, +}; + +static struct platform_device s3c24xx_uart_device3 = { + .id = 3, +}; + +struct platform_device *s3c24xx_uart_src[4] = { + &s3c24xx_uart_device0, + &s3c24xx_uart_device1, + &s3c24xx_uart_device2, + &s3c24xx_uart_device3, +}; + +struct platform_device *s3c24xx_uart_devs[4] = { +}; diff --git a/arch/arm/plat-s3c/dev-usb-hsotg.c b/arch/arm/plat-samsung/dev-usb-hsotg.c index e2f604b51c8..e2f604b51c8 100644 --- a/arch/arm/plat-s3c/dev-usb-hsotg.c +++ b/arch/arm/plat-samsung/dev-usb-hsotg.c diff --git a/arch/arm/plat-s3c/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c index 2ee85abed6d..88165657fa5 100644 --- a/arch/arm/plat-s3c/dev-usb.c +++ b/arch/arm/plat-samsung/dev-usb.c @@ -19,7 +19,7 @@ #include <mach/map.h> #include <plat/devs.h> - +#include <plat/usb-control.h> static struct resource s3c_usb_resource[] = { [0] = { @@ -36,7 +36,7 @@ static struct resource s3c_usb_resource[] = { static u64 s3c_device_usb_dmamask = 0xffffffffUL; -struct platform_device s3c_device_usb = { +struct platform_device s3c_device_ohci = { .name = "s3c2410-ohci", .id = -1, .num_resources = ARRAY_SIZE(s3c_usb_resource), @@ -47,4 +47,23 @@ struct platform_device s3c_device_usb = { } }; -EXPORT_SYMBOL(s3c_device_usb); +EXPORT_SYMBOL(s3c_device_ohci); + +/** + * s3c_ohci_set_platdata - initialise OHCI device platform data + * @info: The platform data. + * + * This call copies the @info passed in and sets the device .platform_data + * field to that copy. The @info is copied so that the original can be marked + * __initdata. + */ +void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info) +{ + struct s3c2410_hcd_info *npd; + + npd = kmemdup(info, sizeof(struct s3c2410_hcd_info), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + + s3c_device_ohci.dev.platform_data = npd; +} diff --git a/arch/arm/plat-s3c/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index 456969b6fa0..44a84e89654 100644 --- a/arch/arm/plat-s3c/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c @@ -17,7 +17,7 @@ #include <linux/gpio.h> #include <linux/io.h> -#include <mach/gpio-core.h> +#include <plat/gpio-core.h> #include <plat/gpio-cfg.h> #include <plat/gpio-cfg-helpers.h> diff --git a/arch/arm/plat-s3c/gpio.c b/arch/arm/plat-samsung/gpio.c index 5ff24e0f9f8..28d2ab8a08d 100644 --- a/arch/arm/plat-s3c/gpio.c +++ b/arch/arm/plat-samsung/gpio.c @@ -16,7 +16,7 @@ #include <linux/io.h> #include <linux/gpio.h> -#include <mach/gpio-core.h> +#include <plat/gpio-core.h> #ifdef CONFIG_S3C_GPIO_TRACK struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; diff --git a/arch/arm/plat-samsung/gpiolib.c b/arch/arm/plat-samsung/gpiolib.c new file mode 100644 index 00000000000..8a8ba8bc1d9 --- /dev/null +++ b/arch/arm/plat-samsung/gpiolib.c @@ -0,0 +1,199 @@ +/* arch/arm/plat-samsung/gpiolib.c + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * Copyright (c) 2009 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * SAMSUNG - GPIOlib support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <mach/gpio.h> +#include <plat/gpio-core.h> +#include <plat/gpio-cfg.h> +#include <plat/gpio-cfg-helpers.h> + +#ifndef DEBUG_GPIO +#define gpio_dbg(x...) do { } while (0) +#else +#define gpio_dbg(x...) printk(KERN_DEBUG x) +#endif + +/* The samsung_gpiolib_4bit routines are to control the gpio banks where + * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the + * following example: + * + * base + 0x00: Control register, 4 bits per gpio + * gpio n: 4 bits starting at (4*n) + * 0000 = input, 0001 = output, others mean special-function + * base + 0x04: Data register, 1 bit per gpio + * bit n: data bit n + * + * Note, since the data register is one bit per gpio and is at base + 0x4 + * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of + * the output. +*/ + +static int samsung_gpiolib_4bit_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); + void __iomem *base = ourchip->base; + unsigned long con; + + con = __raw_readl(base + GPIOCON_OFF); + con &= ~(0xf << con_4bit_shift(offset)); + __raw_writel(con, base + GPIOCON_OFF); + + gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); + + return 0; +} + +static int samsung_gpiolib_4bit_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); + void __iomem *base = ourchip->base; + unsigned long con; + unsigned long dat; + + con = __raw_readl(base + GPIOCON_OFF); + con &= ~(0xf << con_4bit_shift(offset)); + con |= 0x1 << con_4bit_shift(offset); + + dat = __raw_readl(base + GPIODAT_OFF); + + if (value) + dat |= 1 << offset; + else + dat &= ~(1 << offset); + + __raw_writel(dat, base + GPIODAT_OFF); + __raw_writel(con, base + GPIOCON_OFF); + __raw_writel(dat, base + GPIODAT_OFF); + + gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); + + return 0; +} + +/* The next set of routines are for the case where the GPIO configuration + * registers are 4 bits per GPIO but there is more than one register (the + * bank has more than 8 GPIOs. + * + * This case is the similar to the 4 bit case, but the registers are as + * follows: + * + * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs) + * gpio n: 4 bits starting at (4*n) + * 0000 = input, 0001 = output, others mean special-function + * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs) + * gpio n: 4 bits starting at (4*n) + * 0000 = input, 0001 = output, others mean special-function + * base + 0x08: Data register, 1 bit per gpio + * bit n: data bit n + * + * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we + * store the 'base + 0x4' address so that these routines see the data + * register at ourchip->base + 0x04. + */ + +static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); + void __iomem *base = ourchip->base; + void __iomem *regcon = base; + unsigned long con; + + if (offset > 7) + offset -= 8; + else + regcon -= 4; + + con = __raw_readl(regcon); + con &= ~(0xf << con_4bit_shift(offset)); + __raw_writel(con, regcon); + + gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); + + return 0; +} + +static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); + void __iomem *base = ourchip->base; + void __iomem *regcon = base; + unsigned long con; + unsigned long dat; + unsigned con_offset = offset; + + if (con_offset > 7) + con_offset -= 8; + else + regcon -= 4; + + con = __raw_readl(regcon); + con &= ~(0xf << con_4bit_shift(con_offset)); + con |= 0x1 << con_4bit_shift(con_offset); + + dat = __raw_readl(base + GPIODAT_OFF); + + if (value) + dat |= 1 << offset; + else + dat &= ~(1 << offset); + + __raw_writel(dat, base + GPIODAT_OFF); + __raw_writel(con, regcon); + __raw_writel(dat, base + GPIODAT_OFF); + + gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); + + return 0; +} + +void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip) +{ + chip->chip.direction_input = samsung_gpiolib_4bit_input; + chip->chip.direction_output = samsung_gpiolib_4bit_output; + chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); +} + +void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip) +{ + chip->chip.direction_input = samsung_gpiolib_4bit2_input; + chip->chip.direction_output = samsung_gpiolib_4bit2_output; + chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); +} + +void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip, + int nr_chips) +{ + for (; nr_chips > 0; nr_chips--, chip++) { + samsung_gpiolib_add_4bit(chip); + s3c_gpiolib_add(chip); + } +} + +void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, + int nr_chips) +{ + for (; nr_chips > 0; nr_chips--, chip++) { + samsung_gpiolib_add_4bit2(chip); + s3c_gpiolib_add(chip); + } +} diff --git a/arch/arm/plat-s3c/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h index 5f3b1cd53b9..e8382c7be10 100644 --- a/arch/arm/plat-s3c/include/plat/adc.h +++ b/arch/arm/plat-samsung/include/plat/adc.h @@ -1,10 +1,10 @@ -/* arch/arm/plat-s3c/include/plat/adc.h +/* arch/arm/plat-samsung/include/plat/adc.h * * Copyright (c) 2008 Simtec Electronics * http://armlinux.simnte.co.uk/ * Ben Dooks <ben@simtec.co.uk> * - * S3C24XX ADC driver information + * S3C ADC driver information * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/arch/arm/plat-samsung/include/plat/clock-clksrc.h b/arch/arm/plat-samsung/include/plat/clock-clksrc.h new file mode 100644 index 00000000000..50a8ca7c376 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/clock-clksrc.h @@ -0,0 +1,83 @@ +/* linux/arch/arm/plat-samsung/include/plat/clock-clksrc.h + * + * Parts taken from arch/arm/plat-s3c64xx/clock.c + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * Copyright 2009 Ben Dooks <ben-linux@fluff.org> + * Copyright 2009 Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/** + * struct clksrc_sources - list of sources for a given clock + * @sources: array of pointers to clocks + * @nr_sources: The size of @sources + */ +struct clksrc_sources { + unsigned int nr_sources; + struct clk **sources; +}; + +/** + * struct clksrc_reg - register definition for clock control bits + * @reg: pointer to the register in virtual memory. + * @shift: the shift in bits to where the bitfield is. + * @size: the size in bits of the bitfield. + * + * This specifies the size and position of the bits we are interested + * in within the register specified by @reg. + */ +struct clksrc_reg { + void __iomem *reg; + unsigned short shift; + unsigned short size; +}; + +/** + * struct clksrc_clk - class of clock for newer style samsung devices. + * @clk: the standard clock representation + * @sources: the sources for this clock + * @reg_src: the register definition for selecting the clock's source + * @reg_div: the register definition for the clock's output divisor + * + * This clock implements the features required by the newer SoCs where + * the standard clock block provides an input mux and a post-mux divisor + * to provide the periperhal's clock. + * + * The array of @sources provides the mapping of mux position to the + * clock, and @reg_src shows the code where to modify to change the mux + * position. The @reg_div defines how to change the divider settings on + * the output. + */ +struct clksrc_clk { + struct clk clk; + struct clksrc_sources *sources; + + struct clksrc_reg reg_src; + struct clksrc_reg reg_div; +}; + +/** + * s3c_set_clksrc() - setup the clock from the register settings + * @clk: The clock to setup. + * @announce: true to announce the setting to printk(). + * + * Setup the clock from the current register settings, for when the + * kernel boots or if it is resuming from a possibly unknown state. + */ +extern void s3c_set_clksrc(struct clksrc_clk *clk, bool announce); + +/** + * s3c_register_clksrc() register clocks from an array of clksrc clocks + * @srcs: The array of clocks to register + * @size: The size of the @srcs array. + * + * Initialise and register the array of clocks described by @srcs. + */ +extern void s3c_register_clksrc(struct clksrc_clk *srcs, int size); diff --git a/arch/arm/plat-s3c/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h index d86af84b5b8..ba9a1cdd3a2 100644 --- a/arch/arm/plat-s3c/include/plat/clock.h +++ b/arch/arm/plat-samsung/include/plat/clock.h @@ -11,6 +11,30 @@ #include <linux/spinlock.h> +struct clk; + +/** + * struct clk_ops - standard clock operations + * @set_rate: set the clock rate, see clk_set_rate(). + * @get_rate: get the clock rate, see clk_get_rate(). + * @round_rate: round a given clock rate, see clk_round_rate(). + * @set_parent: set the clock's parent, see clk_set_parent(). + * + * Group the common clock implementations together so that we + * don't have to keep setting the same fiels again. We leave + * enable in struct clk. + * + * Adding an extra layer of indirection into the process should + * not be a problem as it is unlikely these operations are going + * to need to be called quickly. + */ +struct clk_ops { + int (*set_rate)(struct clk *c, unsigned long rate); + unsigned long (*get_rate)(struct clk *c); + unsigned long (*round_rate)(struct clk *c, unsigned long rate); + int (*set_parent)(struct clk *c, struct clk *parent); +}; + struct clk { struct list_head list; struct module *owner; @@ -21,11 +45,8 @@ struct clk { unsigned long rate; unsigned long ctrlbit; + struct clk_ops *ops; int (*enable)(struct clk *, int enable); - int (*set_rate)(struct clk *c, unsigned long rate); - unsigned long (*get_rate)(struct clk *c); - unsigned long (*round_rate)(struct clk *c, unsigned long rate); - int (*set_parent)(struct clk *c, struct clk *parent); }; /* other clocks which may be registered by board support */ @@ -54,6 +75,9 @@ extern struct clk clk_h2; extern struct clk clk_27m; extern struct clk clk_48m; +extern int clk_default_setrate(struct clk *clk, unsigned long rate); +extern struct clk_ops clk_ops_def_setrate; + /* exports for arch/arm/mach-s3c2410 * * Please DO NOT use these outside of arch/arm/mach-s3c2410 @@ -66,9 +90,12 @@ extern int s3c2410_clkcon_enable(struct clk *clk, int enable); extern int s3c24xx_register_clock(struct clk *clk); extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks); +extern void s3c_register_clocks(struct clk *clk, int nr_clks); + extern int s3c24xx_register_baseclocks(unsigned long xtal); extern void s3c64xx_register_clocks(void); +extern void s5p_register_clocks(unsigned long xtal_freq); extern void s3c24xx_setup_clocks(unsigned long fclk, unsigned long hclk, diff --git a/arch/arm/plat-s3c/include/plat/dma-core.h b/arch/arm/plat-samsung/include/plat/dma-core.h index 32ff2a92cb3..32ff2a92cb3 100644 --- a/arch/arm/plat-s3c/include/plat/dma-core.h +++ b/arch/arm/plat-samsung/include/plat/dma-core.h diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index 652e2bbdaa2..652e2bbdaa2 100644 --- a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index 29cd6a86cad..29cd6a86cad 100644 --- a/arch/arm/plat-s3c/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h diff --git a/arch/arm/plat-s3c/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index 32af612767a..49ff406a706 100644 --- a/arch/arm/plat-s3c/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -11,6 +11,11 @@ * published by the Free Software Foundation. */ +#define GPIOCON_OFF (0x00) +#define GPIODAT_OFF (0x04) + +#define con_4bit_shift(__off) ((__off) * 4) + /* Define the core gpiolib support functions that the s3c platforms may * need to extend or change depending on the hardware and the s3c chip * selected at build or found at run time. @@ -80,6 +85,29 @@ extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip); * and any other necessary functions. */ +/** + * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config. + * @chip: The gpio chip that is being configured. + * @nr_chips: The no of chips (gpio ports) for the GPIO being configured. + * + * This helper deal with the GPIO cases where the control register has 4 bits + * of control per GPIO, generally in the form of: + * 0000 = Input + * 0001 = Output + * others = Special functions (dependant on bank) + * + * Note, since the code to deal with the case where there are two control + * registers instead of one, we do not have a seperate set of function + * (samsung_gpiolib_add_4bit2_chips)for each case. + */ +extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip, + int nr_chips); +extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, + int nr_chips); + +extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); +extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); + #ifdef CONFIG_S3C_GPIO_TRACK extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; @@ -90,6 +118,8 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip) #else /* machine specific code should provide s3c_gpiolib_getchip */ +#include <mach/gpio-track.h> + static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { } #endif diff --git a/arch/arm/plat-s3c/include/plat/hwmon.h b/arch/arm/plat-samsung/include/plat/hwmon.h index 1ba88ea0aa3..1ba88ea0aa3 100644 --- a/arch/arm/plat-s3c/include/plat/hwmon.h +++ b/arch/arm/plat-samsung/include/plat/hwmon.h diff --git a/arch/arm/plat-s3c/include/plat/iic-core.h b/arch/arm/plat-samsung/include/plat/iic-core.h index 36397ca2096..36397ca2096 100644 --- a/arch/arm/plat-s3c/include/plat/iic-core.h +++ b/arch/arm/plat-samsung/include/plat/iic-core.h diff --git a/arch/arm/plat-s3c/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h index 3083df00dee..3083df00dee 100644 --- a/arch/arm/plat-s3c/include/plat/iic.h +++ b/arch/arm/plat-samsung/include/plat/iic.h diff --git a/arch/arm/plat-samsung/include/plat/irq-uart.h b/arch/arm/plat-samsung/include/plat/irq-uart.h new file mode 100644 index 00000000000..a9331e49bea --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/irq-uart.h @@ -0,0 +1,20 @@ +/* arch/arm/plat-samsung/include/plat/irq-uart.h + * + * Copyright (c) 2010 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Header file for Samsung SoC UART IRQ demux for S3C64XX and later + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +struct s3c_uart_irq { + void __iomem *regs; + unsigned int base_irq; + unsigned int parent_irq; +}; + +extern void s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs); + diff --git a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h new file mode 100644 index 00000000000..a90b53431b5 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h @@ -0,0 +1,13 @@ +/* arch/arm/plat-samsung/include/plat/irq-vic-timer.h + * + * Copyright (c) 2010 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Header file for Samsung SoC IRQ VIC timer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +extern void s3c_init_vic_timer_irq(unsigned int vic, unsigned int timer); diff --git a/arch/arm/plat-s3c/include/plat/nand.h b/arch/arm/plat-samsung/include/plat/nand.h index 226147b7e02..226147b7e02 100644 --- a/arch/arm/plat-s3c/include/plat/nand.h +++ b/arch/arm/plat-samsung/include/plat/nand.h diff --git a/arch/arm/plat-s3c/include/plat/regs-ac97.h b/arch/arm/plat-samsung/include/plat/regs-ac97.h index c3878f7acb8..c3878f7acb8 100644 --- a/arch/arm/plat-s3c/include/plat/regs-ac97.h +++ b/arch/arm/plat-samsung/include/plat/regs-ac97.h diff --git a/arch/arm/plat-s3c/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h index 4323cccc86c..f43c8dab39e 100644 --- a/arch/arm/plat-s3c/include/plat/regs-adc.h +++ b/arch/arm/plat-samsung/include/plat/regs-adc.h @@ -19,6 +19,9 @@ #define S3C2410_ADCDLY S3C2410_ADCREG(0x08) #define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C) #define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10) +#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14) +#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18) +#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20) /* ADCCON Register Bits */ diff --git a/arch/arm/plat-s3c/include/plat/regs-iic.h b/arch/arm/plat-samsung/include/plat/regs-iic.h index 2f7c17de8ac..2f7c17de8ac 100644 --- a/arch/arm/plat-s3c/include/plat/regs-iic.h +++ b/arch/arm/plat-samsung/include/plat/regs-iic.h diff --git a/arch/arm/plat-s3c/include/plat/regs-irqtype.h b/arch/arm/plat-samsung/include/plat/regs-irqtype.h index c63cd3fc5ad..c63cd3fc5ad 100644 --- a/arch/arm/plat-s3c/include/plat/regs-irqtype.h +++ b/arch/arm/plat-samsung/include/plat/regs-irqtype.h diff --git a/arch/arm/plat-s3c/include/plat/regs-nand.h b/arch/arm/plat-samsung/include/plat/regs-nand.h index 238efea7b9e..238efea7b9e 100644 --- a/arch/arm/plat-s3c/include/plat/regs-nand.h +++ b/arch/arm/plat-samsung/include/plat/regs-nand.h diff --git a/arch/arm/plat-s3c/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h index d5837cf8e40..d5837cf8e40 100644 --- a/arch/arm/plat-s3c/include/plat/regs-rtc.h +++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h diff --git a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h b/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h index abf2fbc2eb2..abf2fbc2eb2 100644 --- a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h +++ b/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h diff --git a/arch/arm/plat-s3c/include/plat/regs-sdhci.h b/arch/arm/plat-samsung/include/plat/regs-sdhci.h index e34049ad44c..e34049ad44c 100644 --- a/arch/arm/plat-s3c/include/plat/regs-sdhci.h +++ b/arch/arm/plat-samsung/include/plat/regs-sdhci.h diff --git a/arch/arm/plat-s3c/include/plat/regs-timer.h b/arch/arm/plat-samsung/include/plat/regs-timer.h index d097d92f8cc..d097d92f8cc 100644 --- a/arch/arm/plat-s3c/include/plat/regs-timer.h +++ b/arch/arm/plat-samsung/include/plat/regs-timer.h diff --git a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h index 36a85f5000c..36a85f5000c 100644 --- a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h +++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h diff --git a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h index 8d18d9d4d14..8d18d9d4d14 100644 --- a/arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h +++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h diff --git a/arch/arm/plat-s3c/include/plat/regs-watchdog.h b/arch/arm/plat-samsung/include/plat/regs-watchdog.h index 4938492470f..4938492470f 100644 --- a/arch/arm/plat-s3c/include/plat/regs-watchdog.h +++ b/arch/arm/plat-samsung/include/plat/regs-watchdog.h diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h new file mode 100644 index 00000000000..d1772414931 --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h @@ -0,0 +1,67 @@ +/* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h + * + * Copyright (C) 2009 Samsung Electronics Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __S3C64XX_PLAT_SPI_H +#define __S3C64XX_PLAT_SPI_H + +/** + * struct s3c64xx_spi_csinfo - ChipSelect description + * @fb_delay: Slave specific feedback delay. + * Refer to FB_CLK_SEL register definition in SPI chapter. + * @line: Custom 'identity' of the CS line. + * @set_level: CS line control. + * + * This is per SPI-Slave Chipselect information. + * Allocate and initialize one in machine init code and make the + * spi_board_info.controller_data point to it. + */ +struct s3c64xx_spi_csinfo { + u8 fb_delay; + unsigned line; + void (*set_level)(unsigned line_id, int lvl); +}; + +/** + * struct s3c64xx_spi_info - SPI Controller defining structure + * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field. + * @src_clk_name: Platform name of the corresponding clock. + * @num_cs: Number of CS this controller emulates. + * @cfg_gpio: Configure pins for this SPI controller. + * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6 + * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number + * @high_speed: If the controller supports HIGH_SPEED_EN bit + */ +struct s3c64xx_spi_info { + int src_clk_nr; + char *src_clk_name; + + int num_cs; + + int (*cfg_gpio)(struct platform_device *pdev); + + /* Following two fields are for future compatibility */ + int fifo_lvl_mask; + int rx_lvl_offset; + int high_speed; +}; + +/** + * s3c64xx_spi_set_info - SPI Controller configure callback by the board + * initialization code. + * @cntrlr: SPI controller number the configuration is for. + * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks. + * @num_cs: Number of elements in the 'cs' array. + * + * Call this from machine init code for each SPI Controller that + * has some chips attached to it. + */ +extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); + +#endif /* __S3C64XX_PLAT_SPI_H */ diff --git a/arch/arm/plat-s3c/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index 53198673b6b..53198673b6b 100644 --- a/arch/arm/plat-s3c/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h diff --git a/arch/arm/plat-s3c/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h index dd04db04310..a22a4f2eea9 100644 --- a/arch/arm/plat-s3c/include/plat/udc-hs.h +++ b/arch/arm/plat-samsung/include/plat/udc-hs.h @@ -12,7 +12,7 @@ * published by the Free Software Foundation. */ -enum s3c_hostg_dmamode { +enum s3c_hsotg_dmamode { S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */ S3C_HSOTG_DMA_ONLY, /* always use DMA */ S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */ @@ -24,6 +24,6 @@ enum s3c_hostg_dmamode { * @is_osc: The clock source is an oscillator, not a crystal */ struct s3c_hsotg_plat { - enum s3c_hostg_dmamode dma; + enum s3c_hsotg_dmamode dma; unsigned int is_osc : 1; }; diff --git a/arch/arm/plat-s3c/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h index 54b762acb5a..54b762acb5a 100644 --- a/arch/arm/plat-s3c/include/plat/watchdog-reset.h +++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c new file mode 100644 index 00000000000..4f8c102674a --- /dev/null +++ b/arch/arm/plat-samsung/irq-uart.c @@ -0,0 +1,143 @@ +/* arch/arm/plat-samsung/irq-uart.c + * originally part of arch/arm/plat-s3c64xx/irq.c + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * Samsung- UART Interrupt handling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/serial_core.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <mach/map.h> +#include <plat/irq-uart.h> +#include <plat/regs-serial.h> +#include <plat/cpu.h> + +/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] + * are consecutive when looking up the interrupt in the demux routines. + */ + +static inline void __iomem *s3c_irq_uart_base(unsigned int irq) +{ + struct s3c_uart_irq *uirq = get_irq_chip_data(irq); + return uirq->regs; +} + +static inline unsigned int s3c_irq_uart_bit(unsigned int irq) +{ + return irq & 3; +} + +static void s3c_irq_uart_mask(unsigned int irq) +{ + void __iomem *regs = s3c_irq_uart_base(irq); + unsigned int bit = s3c_irq_uart_bit(irq); + u32 reg; + + reg = __raw_readl(regs + S3C64XX_UINTM); + reg |= (1 << bit); + __raw_writel(reg, regs + S3C64XX_UINTM); +} + +static void s3c_irq_uart_maskack(unsigned int irq) +{ + void __iomem *regs = s3c_irq_uart_base(irq); + unsigned int bit = s3c_irq_uart_bit(irq); + u32 reg; + + reg = __raw_readl(regs + S3C64XX_UINTM); + reg |= (1 << bit); + __raw_writel(reg, regs + S3C64XX_UINTM); + __raw_writel(1 << bit, regs + S3C64XX_UINTP); +} + +static void s3c_irq_uart_unmask(unsigned int irq) +{ + void __iomem *regs = s3c_irq_uart_base(irq); + unsigned int bit = s3c_irq_uart_bit(irq); + u32 reg; + + reg = __raw_readl(regs + S3C64XX_UINTM); + reg &= ~(1 << bit); + __raw_writel(reg, regs + S3C64XX_UINTM); +} + +static void s3c_irq_uart_ack(unsigned int irq) +{ + void __iomem *regs = s3c_irq_uart_base(irq); + unsigned int bit = s3c_irq_uart_bit(irq); + + __raw_writel(1 << bit, regs + S3C64XX_UINTP); +} + +static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) +{ + struct s3c_uart_irq *uirq = desc->handler_data; + u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); + int base = uirq->base_irq; + + if (pend & (1 << 0)) + generic_handle_irq(base); + if (pend & (1 << 1)) + generic_handle_irq(base + 1); + if (pend & (1 << 2)) + generic_handle_irq(base + 2); + if (pend & (1 << 3)) + generic_handle_irq(base + 3); +} + +static struct irq_chip s3c_irq_uart = { + .name = "s3c-uart", + .mask = s3c_irq_uart_mask, + .unmask = s3c_irq_uart_unmask, + .mask_ack = s3c_irq_uart_maskack, + .ack = s3c_irq_uart_ack, +}; + +static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) +{ + struct irq_desc *desc = irq_to_desc(uirq->parent_irq); + void __iomem *reg_base = uirq->regs; + unsigned int irq; + int offs; + + /* mask all interrupts at the start. */ + __raw_writel(0xf, reg_base + S3C64XX_UINTM); + + for (offs = 0; offs < 3; offs++) { + irq = uirq->base_irq + offs; + + set_irq_chip(irq, &s3c_irq_uart); + set_irq_chip_data(irq, uirq); + set_irq_handler(irq, handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } + + desc->handler_data = uirq; + set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); +} + +/** + * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing + * @irq: The interrupt data for registering + * @nr_irqs: The number of interrupt descriptions in @irq. + * + * Register the UART interrupts specified by @irq including the demuxing + * routines. This supports the S3C6400 and newer style of devices. + */ +void __init s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs) +{ + for (; nr_irqs > 0; nr_irqs--, irq++) + s3c_init_uart_irq(irq); +} diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c new file mode 100644 index 00000000000..0270519fcab --- /dev/null +++ b/arch/arm/plat-samsung/irq-vic-timer.c @@ -0,0 +1,86 @@ +/* arch/arm/plat-samsung/irq-vic-timer.c + * originally part of arch/arm/plat-s3c64xx/irq.c + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * http://armlinux.simtec.co.uk/ + * + * S3C64XX - Interrupt handling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/io.h> + +#include <mach/map.h> +#include <plat/irq-vic-timer.h> +#include <plat/regs-timer.h> + +static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) +{ + generic_handle_irq((int)desc->handler_data); +} + +/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ + +static void s3c_irq_timer_mask(unsigned int irq) +{ + u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); + + reg &= 0x1f; /* mask out pending interrupts */ + reg &= ~(1 << (irq - IRQ_TIMER0)); + __raw_writel(reg, S3C64XX_TINT_CSTAT); +} + +static void s3c_irq_timer_unmask(unsigned int irq) +{ + u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); + + reg &= 0x1f; /* mask out pending interrupts */ + reg |= 1 << (irq - IRQ_TIMER0); + __raw_writel(reg, S3C64XX_TINT_CSTAT); +} + +static void s3c_irq_timer_ack(unsigned int irq) +{ + u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); + + reg &= 0x1f; + reg |= (1 << 5) << (irq - IRQ_TIMER0); + __raw_writel(reg, S3C64XX_TINT_CSTAT); +} + +static struct irq_chip s3c_irq_timer = { + .name = "s3c-timer", + .mask = s3c_irq_timer_mask, + .unmask = s3c_irq_timer_unmask, + .ack = s3c_irq_timer_ack, +}; + +/** + * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\ + * @parent_irq: The parent IRQ on the VIC for the timer. + * @timer_irq: The IRQ to be used for the timer. + * + * Register the necessary IRQ chaining and support for the timer IRQs + * chained of the VIC. + */ +void __init s3c_init_vic_timer_irq(unsigned int parent_irq, + unsigned int timer_irq) +{ + struct irq_desc *desc = irq_to_desc(parent_irq); + + set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer); + + set_irq_chip(timer_irq, &s3c_irq_timer); + set_irq_handler(timer_irq, handle_level_irq); + set_irq_flags(timer_irq, IRQF_VALID); + + desc->handler_data = (void *)timer_irq; +} diff --git a/arch/arm/plat-s3c/pm-check.c b/arch/arm/plat-samsung/pm-check.c index 8eb1f439861..0b5bb774192 100644 --- a/arch/arm/plat-s3c/pm-check.c +++ b/arch/arm/plat-samsung/pm-check.c @@ -20,8 +20,8 @@ #include <plat/pm.h> -#if CONFIG_S3C2410_PM_CHECK_CHUNKSIZE < 1 -#error CONFIG_S3C2410_PM_CHECK_CHUNKSIZE must be a positive non-zero value +#if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1 +#error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value #endif /* suspend checking code... @@ -29,12 +29,12 @@ * this next area does a set of crc checks over all the installed * memory, so the system can verify if the resume was ok. * - * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC, + * CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE defines the block-size for the CRC, * increasing it will mean that the area corrupted will be less easy to spot, * and reducing the size will cause the CRC save area to grow */ -#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024) +#define CHECK_CHUNKSIZE (CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE * 1024) static u32 crc_size; /* size needed for the crc block */ static u32 *crcs; /* allocated over suspend/resume */ diff --git a/arch/arm/plat-s3c/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c index cfd326a8b69..69a4c7f02e2 100644 --- a/arch/arm/plat-s3c/pm-gpio.c +++ b/arch/arm/plat-samsung/pm-gpio.c @@ -19,7 +19,7 @@ #include <linux/io.h> #include <linux/gpio.h> -#include <mach/gpio-core.h> +#include <plat/gpio-core.h> #include <plat/pm.h> /* PM GPIO helpers */ diff --git a/arch/arm/plat-s3c/pwm-clock.c b/arch/arm/plat-samsung/pwm-clock.c index a318215ab53..46c9381e083 100644 --- a/arch/arm/plat-s3c/pwm-clock.c +++ b/arch/arm/plat-samsung/pwm-clock.c @@ -130,20 +130,22 @@ static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate) return 0; } +static struct clk_ops clk_pwm_scaler_ops = { + .get_rate = clk_pwm_scaler_get_rate, + .set_rate = clk_pwm_scaler_set_rate, + .round_rate = clk_pwm_scaler_round_rate, +}; + static struct clk clk_timer_scaler[] = { [0] = { .name = "pwm-scaler0", .id = -1, - .get_rate = clk_pwm_scaler_get_rate, - .set_rate = clk_pwm_scaler_set_rate, - .round_rate = clk_pwm_scaler_round_rate, + .ops = &clk_pwm_scaler_ops, }, [1] = { .name = "pwm-scaler1", .id = -1, - .get_rate = clk_pwm_scaler_get_rate, - .set_rate = clk_pwm_scaler_set_rate, - .round_rate = clk_pwm_scaler_round_rate, + .ops = &clk_pwm_scaler_ops, }, }; @@ -256,50 +258,46 @@ static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate) return 0; } +static struct clk_ops clk_tdiv_ops = { + .get_rate = clk_pwm_tdiv_get_rate, + .set_rate = clk_pwm_tdiv_set_rate, + .round_rate = clk_pwm_tdiv_round_rate, +}; + static struct pwm_tdiv_clk clk_timer_tdiv[] = { [0] = { .clk = { - .name = "pwm-tdiv", - .parent = &clk_timer_scaler[0], - .get_rate = clk_pwm_tdiv_get_rate, - .set_rate = clk_pwm_tdiv_set_rate, - .round_rate = clk_pwm_tdiv_round_rate, + .name = "pwm-tdiv", + .ops = &clk_tdiv_ops, + .parent = &clk_timer_scaler[0], }, }, [1] = { .clk = { - .name = "pwm-tdiv", - .parent = &clk_timer_scaler[0], - .get_rate = clk_pwm_tdiv_get_rate, - .set_rate = clk_pwm_tdiv_set_rate, - .round_rate = clk_pwm_tdiv_round_rate, + .name = "pwm-tdiv", + .ops = &clk_tdiv_ops, + .parent = &clk_timer_scaler[0], } }, [2] = { .clk = { - .name = "pwm-tdiv", - .parent = &clk_timer_scaler[1], - .get_rate = clk_pwm_tdiv_get_rate, - .set_rate = clk_pwm_tdiv_set_rate, - .round_rate = clk_pwm_tdiv_round_rate, + .name = "pwm-tdiv", + .ops = &clk_tdiv_ops, + .parent = &clk_timer_scaler[1], }, }, [3] = { .clk = { - .name = "pwm-tdiv", - .parent = &clk_timer_scaler[1], - .get_rate = clk_pwm_tdiv_get_rate, - .set_rate = clk_pwm_tdiv_set_rate, - .round_rate = clk_pwm_tdiv_round_rate, + .name = "pwm-tdiv", + .ops = &clk_tdiv_ops, + .parent = &clk_timer_scaler[1], }, }, [4] = { .clk = { - .name = "pwm-tdiv", - .parent = &clk_timer_scaler[1], - .get_rate = clk_pwm_tdiv_get_rate, - .set_rate = clk_pwm_tdiv_set_rate, - .round_rate = clk_pwm_tdiv_round_rate, + .name = "pwm-tdiv", + .ops = &clk_tdiv_ops, + .parent = &clk_timer_scaler[1], }, }, }; @@ -356,31 +354,35 @@ static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent) return 0; } +static struct clk_ops clk_tin_ops = { + .set_parent = clk_pwm_tin_set_parent, +}; + static struct clk clk_tin[] = { [0] = { - .name = "pwm-tin", - .id = 0, - .set_parent = clk_pwm_tin_set_parent, + .name = "pwm-tin", + .id = 0, + .ops = &clk_tin_ops, }, [1] = { - .name = "pwm-tin", - .id = 1, - .set_parent = clk_pwm_tin_set_parent, + .name = "pwm-tin", + .id = 1, + .ops = &clk_tin_ops, }, [2] = { - .name = "pwm-tin", - .id = 2, - .set_parent = clk_pwm_tin_set_parent, + .name = "pwm-tin", + .id = 2, + .ops = &clk_tin_ops, }, [3] = { - .name = "pwm-tin", - .id = 3, - .set_parent = clk_pwm_tin_set_parent, + .name = "pwm-tin", + .id = 3, + .ops = &clk_tin_ops, }, [4] = { - .name = "pwm-tin", - .id = 4, - .set_parent = clk_pwm_tin_set_parent, + .name = "pwm-tin", + .id = 4, + .ops = &clk_tin_ops, }, }; @@ -428,25 +430,15 @@ __init void s3c_pwmclk_init(void) return; } - for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) { + for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) clk_timer_scaler[clk].parent = clk_timers; - ret = s3c24xx_register_clock(&clk_timer_scaler[clk]); - if (ret < 0) { - printk(KERN_ERR "error adding pwm scaler%d clock\n", clk); - return; - } - } - for (clk = 0; clk < ARRAY_SIZE(clk_timer_tclk); clk++) { - ret = s3c24xx_register_clock(&clk_timer_tclk[clk]); - if (ret < 0) { - printk(KERN_ERR "error adding pww tclk%d\n", clk); - return; - } - } + s3c_register_clocks(clk_timer_scaler, ARRAY_SIZE(clk_timer_scaler)); + s3c_register_clocks(clk_timer_tclk, ARRAY_SIZE(clk_timer_tclk)); for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) { ret = clk_pwm_tdiv_register(clk); + if (ret < 0) { printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk); return; diff --git a/arch/arm/plat-s3c/pwm.c b/arch/arm/plat-samsung/pwm.c index ef019f27b67..ef019f27b67 100644 --- a/arch/arm/plat-s3c/pwm.c +++ b/arch/arm/plat-samsung/pwm.c |